Hackable CMWX1ZZABZ (LoRa) Devices

Useful STM32L082-based devices with embedded LoRa radio modem programmable with the Arduino IDE via USB connector, i.e, hackable.

Similar projects worth following
Murata's CMWX1ZZABZ module contains an STM32L082 host MCU and an SX1276 LoRa radio modem. We have designed three (and counting) useful devices using this module all programmable via the Arduino IDE using the embedded boot loader accessible through the USB controller on the STM32L082. The three devices include a 18 x 45 mm development board (Grasshopper), a 23 mm x 23 mm LoRaSensorTile, and a 23 mm x 46 mm Asset Tracker (Cricket). Each exposes plenty of GPIOs so you can modify to suit your particular application, i.e., hackable!

From the CMWX1ZZABZ data sheet:

"Type ABZ is a new, compact, low cost, low power wide area network (LPWAN) wireless module that supports the LoRaWAN long range wireless protocol. This new stand-alone module measures just 12.5 x 11.6 x 1.76 mm, is constructed in a metal shielded package and comprises a Semtech SX1276 ultra long range spread spectrum wireless transceiver and an STMicro STM32L0 series ARM Cortex-M0+ 32 bit microcontroller (MCU). An integrated TCXO that has robust low drift thermal characteristics provides an accurate clock source for the RF transceiver."

It's a small module, and we have taken advantage of this to design compact boards that use very little power to do really interesting things. The STM32L082 MCU host is a Cortex M0+ operating at 4, 16, and 32 MHz, it manages the Sematech SX1276 LoRa radio modem and offers the user up to 19 GPIOs for controlling sensors and other peripheral devices like flash memory, SD card, displays, etc. There is a well-designed LoRaWAN stack for simple configuration of the LoRa radio for use with standard gateways and, for example, the Things Network.

In addition to three different CPU clock speeds, the STM32L082 is capable of several different low power modes including SLEEP, STOP (1.6 uA) and STANDBY (500 nA); there are a variety of tools to minimize power usage. The module offers the usual set of serial protocols including SPI, I2C, and UART, as well as analog pins with ADC and DAC. So far, we have designed three devices with embedded CMWX1ZZABZ hosts: Grasshopper Development Board, LoRaSensorTile, and Cricket Asset Tracker.

Grasshopper is a Teensy-sized (18 mm x 45 mm) development board which exposes all 19 of the CMWX1ZZABZ GPIOs as well as 3V3, GND, a VIN port for power input or battery voltage output and VREF for selecting the analog reference voltage if different from the default 3V3. The Grasshopper uses the NCV8170 3V3 150 mA LDO with quiescent current of just 500 nA to allow the lowest power consumption. The on-board chip antenna provides excellent LoRa transmission; there is also a uFl connector for an external antenna if desired. Grasshopper is the perfect way to develop your LoRa application on the breadboard. And because Grasshopper is open-source, you can use the Grasshopper design as a template for your own custom design suited to your application. Grasshopper is available for sale at Tindie.

The LoRaSensorTile is designed in a different form factor than the Grasshopper and we have added a STBC08 LiPo battery charger, 16 MByte SPI NOR flash memory, BMA280 accelerometer, BME280 pressure/temperature/humidity sensors, as well as a VEML6040 RGBW ambient light sensor. The components have been chosen for ultra-low power operation; the LoRaSensorTile has a sleep current of just 12 uA. Total average power depends on sensor data rates and frequency of LoRaWAN transmission chosen but we expect with average use (store data to flash once  per minute, send LoRa data once every ten minutes) the LoRaSensorTile will last more than a year on a single AAA battery.

Lastly, the Cricket Asset Tracker adds a concurrent (GPS and GLONASS) CAM M8Q to the LoRaSensorTile component suite (no VEML6040 however) to allow asset location and asset tracking as well as motion and environmental sensing. The CAM M8Q can use its excellent chip antenna for lowest power or an external active antenna can be used for indoor use or use in difficult environments (urban canyons, construction sites, etc) at the cost of more power. Again, the components have been chosen for ultra-low power operation; Cricket has a sleep current of just 14 uA.  By judicious use of the GNSS engine the Cricket is expected to last a year on a single AA battery.

We have developed a complete system layer for the CMWX1ZZABZ and an Arduino overlayer that makes using these devices very easy.  Traditional tool chains can still be used for programming...

Read more »

Grasshopper EAGLE Design Files

x-zip-compressed - 271.13 kB - 01/19/2018 at 02:24



Grasshopper BOM

OpenDocument Spreadsheet - 16.12 kB - 01/19/2018 at 02:22


  • Another Zoo Denizen Arrives...

    Kris Winer07/16/2018 at 18:01 0 comments

    July 16, 2018

    I thought the LoRa SensorTile (23 mm x 23 mm) was about as small as I could go using the CMWX1ZZABZ LoRa module but the Gnat at 20 mm x 20 mm is 3/4 of the area of the LoRa SensorTile.

    The Gnat uses the same Murata CMWX1ZZABZ module with STM32L082 32 MHz Cortex M0+ host and SX1276 LoRa radio, of course, and includes the smaller U-Blox MAX M8Q (sibling of the CAM M8Q on Cricket) as concurrent GNSS engine. There is a BMA280 accelerometer for wake-on-motion/sleep-on-no-motion control of the GNSS engine and four GPIOs exposed at the board edge (2 digital/SWD ports and 2 analog ports) but no battery charger, SPI flash, BME280, VEML6040 or the other ~10 GPIOs of the LoRa Sensor Tile or Cricket devices.

    The MAX M8Q requires an active antenna since the internal chip antenna is absent and the ground plane of the Gnat is simply to small to support a chip antenna solution anyway. The CMWX1ZZABZ requires a whip antenna like the Cricket and LoRa SensorTiles do, although I am experimenting with a longer (80 mm x 23 mm) version of the Cricket that has 1) a chip antenna for the CMWX1ZZABZ like the Grasshopper uses and 2) an extended ground plane (71 mm from 46 mm in the Cricket) to increase the sensitivity of the CAM M8Q chip antenna.

    I am testing the power usage now to see if I can get as good performance out of the chip antenna as I do with the active patch antenna. If this longer design works well enough, I might have a small production run made. It is very convenient in some applications (animal tracking, for example) to use an asset tracker that requires no additional antennas attached to the board.

    So Gnat is a (slightly) reduced-capability mashup of the Cricket and LoRa Sensor Tile devices in a form factor that is approaching the limit of what can be done to shrink the size of any device using the CMWX1ZZABZ module. It is useful for those applications that require accurate location tracking with periodic reporting via LoRa(WAN) but in the smallest weight and form factor (volume, really) possible.

  • Third Cricket Power Test

    Kris Winer03/27/2018 at 03:07 0 comments


    Just finished the third Cricket power test. Like the last one, I am reading/logging sensor data every minute and broadcasting LoRaWAN updates every 10 minutes. I am also using a low duty cycle of one GNSS fix every two hours like the last time, and a high duty cycle of once per minute when motion is detected. This occurs ~once per day manually. Both tests started witha fully charged 105 mAH LiPo battery.

    The key variable is the GNSS fix accuracy EHPE, which was either 10 meters (minimum practical value) or 50 meters (a reasonable low-power value. EHPE sets the cutoff for ending the satellite acquisition/tracking and entering power-saving sleep mode):

    EPHE       hours       average current         number of fixes      rms location accuracy

    10              196              536 uA                         ~110                        ~ 5 meters

    50             327              321 uA                         ~180                       ~ 15 meters

    So with a single AA-sized LiSO2Cl 3.6 V, 2600 mAH low-self-discharge battery the Cricket would last:

    202 days at EHPE of 10 and 338 days at EHPE of 50.

    This time could be longer if the low duty cycle frequency were to be increased to three or four hours, which makes practical sense because the ephemeris data goes stale after about four hours. So three or four hour fix update is a sensible criterion for the long cycle.

    Overall battery life will depend on the amount of motion experienced by the device; the more motion the more fixes per day and the less the battery lifetime. For a 2600 mAH battery, total number of fixes will be limited to between 2700 (EHPE of 10) and 4400 (EHPE of 50). Of course, one could always just use two 2600 mAH batteries in parallel to get out well past one year ;>

  • New Device Added to the Zoo

    Kris Winer02/25/2018 at 18:52 2 comments


    The Sentinel is a purpose-designed utility board for safety and security applications including such things as remote monitoring of the environment, motion detection, and human presence detection, etc. It uses the CMWX1ZZABZ module as host and includes a BMD-350 slave nRF52 for BLE over UART serial bridge. The idea of the BLE slave is to act as a local interface with safety or security personnel via the beacon function as well as back up for the main LoRaWAN communication interface.

    The Sentinel is intended to be battery-powered and the 150 mA, 3.3V NCV8170 LDO uses just 500 nA to provide board voltage regulation. The Sentinel has many of the same sensors as the LoRaSensorTile including BME280 pressure/temperature/humidity sensors, BMA280 accelerometer, VEML6040 RGBW ambient light sensor but adds the CaliPile (TPiS 1S 1385) IR presence/motion sensor for human presence detection. The Sentinel also has an 8 MByte SPI flash for holding multiple programs or data logging. All of these components are ultra-low power allowing the Sentinel to sleep with ~10 uA current, wake periodically or when a sensor threshold is crossed (via interrupt), and remain "on-guard" for years on a single AAA battery.

    The Sentinel pcb is designed to fit into two off-the-shelf plastic boxes, either a 2.5-inch square box from Bud Industries or a 2.4 x 1.4 inch Hammond box.

    The pcb is designed with all components on one side and mounted close to the box face for easy access for the indicator led, ambient light and presence sensors via drilled holes in the box to the outside. The holes can be covered with transparent shields or cellophane tape to provide a barrier to excessive moisture. There is enough room in the boxes for one or more small batteries. In most cases, using a 3.6V booster and a single AAA battery would be sufficient for years of service. The boxes could be mounted using a strong magnet or velcro, etc depending on the application. It is an inexpensive and convenient packaging solution that allows for rapid deployment and change of location to fit the need.

    Periodic LoRaWAN transmissions would be used for passing state information and alerting to threshold conditions but BLE, with its greater throughput (~1 kByte/s), could be used for large-scale transfer of data stored on the SPI flash memory. The BLE beacon would be configured to sleep most of the time and wake periodically. Upon detection of a smart device for pairing, such as a smart phone or tablet carried by a security guard or safety inspector, the Sentinel could pair, exchange the proper authorization codes, and upload more extensive stored data to the smart device and download changes in configuration, etc.

    Intended deployment would be construction sites, manufacturing and utility complexes, basically anywhere humans are now required to monitor safety and security conditions. Rather than replacing humans, the intent is to augment human eyes and ears with a device that is always "on watch" for conditions out of the ordinary and able to report over long distances that human assistance is required.

  • Second Cricket Power Test

    Kris Winer02/18/2018 at 18:31 1 comment


    I am in the middle of my second Cricket Asset Tracker power test but I already have some interesting results.

    Firstly, I used the fact that the BMA280 accelerometer has two interrupts and a quite sophisticated interrupt engine to set up "wake on any motion" on one interrupt and "sleep on lack of motion" on the other. The BMA280 remains in low power mode 1 (drawing ~6 uA on average) and in this mode wakes up every second to sample the accelerometer. If it detects a change in acceleration greater than a defined slope threshold it wakes up. If it is already awake and detects less than this threshold it goes back to sleep, activating the appropriate interrupt to let the host know which state it is in. The interrupt handlers simply set a flag and wake up the host like so:

    void myinthandler1()
      BMA280_wake_flag = true; 
      Serial.println("BMA280 is awake!");
    void myinthandler2()
      BMA280_sleep_flag = true;
      Serial.println("BMA280 is asleep!");

     Then in the main loop I manage the BMA280 interrupts like so:

        // use BMA280 wake and sleep motion detection to detect motion state
        if(BMA280_wake_flag == true) 
          BMA280_wake_flag = false;      // clear the flag
          InMotion = true;               // set motion state latch
          BMA280.activateNoMotionInterrupt();                                                                // Re-enable BMA280 no motion interrupt
          attachInterrupt(BMA280_intPin2, myinthandler2, RISING);   
        if(BMA280_sleep_flag == true)
          BMA280_sleep_flag = false;    // clear the flag
          detachInterrupt(BMA280_intPin2);                                                                  // Detach the BMA280 "Go to sleep" interrupt so it doesn't spuriously wake the STM32L4
        } /* end of sleep/wake detect */

    This detaches the noMotion interrupt when the BMA280 is sleeping and re-attaches it when the BMA280 wakes to save a bit of power and avoid false positives. It also sets an InMotion flag for use by the rest of the main loop program. This is a little clunky and I can probably make this more efficient. I did it this way simply to make clear the logic for myself and get the Cricket to behave the way I wanted.

    The next bit of magic is the two TimerMillis callbacks:

    void callbackNoMotionActivity(void)
    void callbackInMotionActivity(void)
       InMotion = false;

    The first simply wakes up the CAM M8Q at a low frequency, in this test set to once an hour. The second is called every minute but only wakes the CAM M8Q if motion has been previously detected. In other words, I want the CAM M8Q, which is the big power hog on the board, to get a fix infrequently when the asset being tracked is stationary and to update the asset position more frequently when it is in motion. Since it takes a good fraction of a minute to get a hot fix in challenging conditions, a minute for the high frequency period seems reasonable. And since the ephemeris downloaded from satellite is good for four hours, three or four hours seems a reasonable period for the low frequency update. here I chose one hour just to make sure I would get a lot (relatively speaking) of data.

    The last bit to making this scheme work is the CAM M8Q sleep criterion:

             if(EPE < 100.0f) {
                Serial.println("***GNSS go to sleep!***");
                GNSS.sleep(); // once we have a good location fix put CAM M8Q to sleep
                callbackLoRaTx();  // update dashboard/backend via LoRaWAN

    I am using the quality measure EPE (estimated position error) as a sleep criterion such that once a fix is obtained with an EPE less than 100 the CAM M8Q goes to sleep, to wake up either an hour later or whenever motion is detected. The value of EPE is arbitrary but there is a tradeoff. If I use a small EPE threshold, it will take longer to achieve a fix and I will use more power. And conversely, if I make the EPE too large I will get fixes that wander all over the place. The value of 100 gives this kind of result (I am using the CayenneLPP dashboard to...

    Read more »

  • First Cricket Power Test

    Kris Winer02/09/2018 at 22:46 0 comments

    Completed first integral power test of the Cricket Asset Tracker using a fully-charged 150 mAH 1S LiPo battery, gathering BME280 and BMA280 sensor data and logging same to SPI flash once per minute using the RTC alarm as a timing interrupt, sending same data plus longitude and latitude to a LoRaWAN network (the Things Network) via TTN gateway every ten minutes, and acquiring a new fix from hot start every ten minutes. I know from testing the LoRaSensorTile under more or less the same conditions that the average power usage of everything except GNSS is about 50 uA, so the 150 mAH LiPo would last 125 days except for acquiring GNSS fixes.

    The GNSS engine (CAM M8Q) was set up to wakeup every ten minutes using a millisecond timer, acquire a 3D fix, then go to sleep again until the next wakeup. So in addition to the average current usage a key performance parameter is the average time to hot fix (TTHF). This will depend on a lot of factors. In this test, I am using the external (active) antenna with an 18 mm patch antenna I bought on Aliexpress instead of the internal chip antenna embedded in the CAM M8Q. The active antenna requires ~10 mA more power in use but also lowers the TTHF, so for GNSS-signal challenged environments like indoors on my work desk as in this test, it might be a good tradeoff.

    In the end, the test ran successfully for just over three days, or 72.5 hours. I received the first LoRaWAN data packet on TTN at 10:46 AM 2/6/18 and the last at 11:10 AM 2/9/18. This means the average current draw was ~2.1 mA and the inferred average time to hot fix was just under 38 seconds.

    I got the full data log on the 8 MByte SPI flash, here is an example of temperature and humidity over the three days:

    I made some mistakes on the first run. I logged GNSS time instead of RTC time so even though the pressure and humidity, etc data changes the times are the same for each ten minute interval instead of incrementing properly when using RTC time. That is why the data look "spiky".  I also forgot to  read the GNSS altitude variable so these were logged as all zeroes, not very useful.

    But the first test of the Cricket Asset Tracker is a success, everything worked and the power figure is very good. 2.1 mA at 10 minute intervals in a challenging (indoor) environment is a pretty good place to be. This means under these same conditions I could expect to get ~1100mAH/2.1 mA ~22 days on a single AAA battery at this duty cycle. Every ten minutes is too fast for slow moving objects like a bull dozer on a construction site and too slow for rapidly moving ones ike bicycles and cars.

    The ephemeris data downloaded from acquired satellites is accurate for about four hours and has to be re-read after this time so a practical upper limit to the acquisition duty cycle is four hours. A practical lower limit is once per minute if in challenging conditions it takes a good fraction of a minute to get a hot fix. In practical asset tracking,  the duty cycle would have to be balanced between the competing goals of power usage minimization and tracking accuracy.

    The art , then, of a practical asset tracker is to adjust the duty cycle of the GNSS fix acquisition to the tracking problem at hand by acquiring a fix infrequently when the device is more or less stationary and more frequently when the device is in motion. That is the reason why there is an accelerometer on board Cricket and making the GNSS engine motion aware is the next task.

  • Practical LoRaSensorTile Power Usage

    Kris Winer01/24/2018 at 02:57 0 comments

    With the availability of the CMWX1ZZABZ-078 Arduino core I have started to write application firmware for the various devices with embedded CMWX1ZZABZ-078 modules and test peak and average power usage as well as sleep current.

    Grasshopper sleep current is 2.1 uA, LoRaSensorTile 12 uA, and Cricket Asset Tracker 14 uA.

    First test of the LoRaSensorTile in use as an edge node casting BME280 and battery voltage data to TTN every five minutes


    shows   peak Tx of 33 mA and average power (at 3V3 input) of ~50 uA. This is with all sensors active (sensor reads once per minute) but the SPI flash is not selected (trying to figure this out now) so I am not actively writing data for logging, but this will affect the average power usage only slightly.

    So ~50 uA is about 1.2 mAH per day so with a small 3V3 booster the LoRa SensorTile should last a couple of years on a single AAA battery.

  • Initial drop of (alpha) Arduino core

    Kris Winer01/21/2018 at 02:16 0 comments


    Located hereHere is a more or less complete how-to to get going with this STM32L0 Arduino core. Just follow the instructions and choose the Grasshopper-L082CZ board in the board manager instead of the Ladybug-L432.  I have modified Simon's excellent tutorial below to make it specific to the Grasshopper board:

    If you haven't already installed the latest version of the Arduino IDE, you should do that now. If you're running Windows, you should choose to top-listed item, Windows installer (instead of the Windows app store). Linux users can follow these instructions, and Mac OS X users can follow these. Whichever OS you're running, please consider donating to the Arduino Project as part of the download!

    To get 32-bit Arduino support, go to Tools/Board/Boards Manager ... (top of the Boards menu), and select the box for Arduino SAM Boards (32-bits ARM Cortex M3), and click the Install button. Although the Grasshopper is an ARM Cortex M0 board, this step will install the gnu-arm compiler that will work with Grasshopper and other ARM Cortex boards.

    Typically, your Arduino folder is in your Documents folder on Windows and OS X, and in your home folder on Linux. Keeping your hardware support and libraries in this folder, instead of in the Arduino IDE installation folder, will ensure that they persist after you download subsequent versions of the Arduino IDE.  Next, clone  this repository into your Arduino/hardware folder. Create a directory called Arduino/hardware/STM32L0 and extract the core into the STM32L0 folder. Rename the core folder to STM32L0. You should end up with the core in the directory Arduino/hardware/STM32L0/STM32L0. Launch the Arduino IDE and under Tools/Boards you should see several new STM32L0 boards toward the bottom of the menu, including Grasshopper-L082CZ.

    Finally, you're going to add some OS-specific support allowing your computer to talk to the Grasshopper:


    1. Go to Arduino/hardware/grumpyoldpizza/stm32l0/drivers/linux/
    2. sudo cp *.rules /etc/udev/rules.d
    3. reboot


    1. Download Zadig
    2. Plugin STM32L0 board and toggle the RESET button while holding down the BOOT button
    3. Let Windows finish searching for drivers
    4. Start Zadig
    5. Select Options -> List All Devices
    6. Select STM32 BOOTLOADER from the device dropdown
    7. Select WinUSB (v6.1.7600.16385) as new driver
    8. Click Replace Driver
    9. Window 7s only:
      1. Go to Arduino/hardware/grumpypoldpizza/stm32l0/drivers/windows
      2. Right-click on dpinst_x86.exe (32 bit Windows) or dpinst_amd64.exe (64 bit Windows) and select Run as administrator
      3. Click on Install this driver software anyway at the Windows Security popup as the driver is unsigned


    Of course, no Arduino setup can be complete until you test your board with the beloved Blink sketch! Having launched the Arduino IDE, under Tools/Board choose Grasshopper-L082CZ, and under Tools/Port select the serial port on which your Grasshopper is connected. Under File/Examples/01. Basics chose Blink. Save a copy of this sketch in a temporary location (like your Desktop); Grasshopper led is on pin 13.

    Flash the modified Blink sketch, and the little red LED on the Grasshopper should start blinking on and off. If you can't flash the sketch (countdown 10 9 .. 1 FAIL), disconnect the Grasshopper, reconnect it while holding down the Boot button (labeled BOOT), and try again.

    Any question or trouble, send me an e-mail at

  • LoRaSensorTile power usage

    Kris Winer01/20/2018 at 05:08 0 comments

    The LoRaSensorTile has a lot of sensors so the current is no longer dominated by the CPU current alone. I used an ST power monitor to measure the current usage as a function of time for different conditions. The ST power monitor supplies 3.30 V which I applied to the 3V3 and GND inputs of the LoRaSensorTile. The currents reported below might be a bit higher when using a 4 V LiPo battery.

    A portion of the current history as a function of time for 32 MHz clock speed is shown here:

    You can see that every second the when the RTC alarm goes off data is read and the led blinks, etc before the STM32L082 returns to the STOP mode, with stop current of ~12 uA; this includes the ~2 uA for the STM32L082 as well as the current drawn by the I2C sensors, battery charger, and SPI flash, which are absent in the Grasshopper.

    The average current as a function of clock speed is plotted below:

    You can see the advantage of dropping the CPU speed as low as possible when deploying devices in the field. The current used by everything except the CPU is about 70 uA (0 CPU intercept). This means the CPU uses ~92 uA at 32 MHz, ~49 uA at 16 Mhz, and ~12 uA at 4.2 MHz; CPU current usage is proportional to clock speed, as expected. At just over 80 uA average current usage at 4.2 MHz the LoRaSensorTile would last for more than a year on a couple of AAA batteries.

  • Grasshopper power usage

    Kris Winer01/19/2018 at 18:59 1 comment


    Average power usage for an application will depend on what peripherals and duty cycle are chosen, etc but we can get some idea of what ultra-low power means for users of the CMWX1ZZABZ by measuring the power required to perform a simple task, in this case blinking an led, going into stop mode for 5 seconds, then repeat.

    Here is the sketch:

    /* LED Blink, for Grasshopper
       This example code is in the public domain.
    #include <STM32L0.h>
    #define myLed 13 // red led
    #define myADC A1
    float VDDA, Temperature;
    uint32_t UID[3] = {0, 0, 0};
    uint16_t adc = 0;
    void setup() 
      Serial.println("Serial enabled!");
      pinMode(myLed, OUTPUT);
      digitalWrite(myLed, LOW);  // start with leds off, since active HIGH
      pinMode(myADC, INPUT);
      Serial.print("STM32L0 MCU UID = 0x"); Serial.print(UID[0], HEX); Serial.print(UID[1], HEX); Serial.println(UID[2], HEX); 
    void loop() 
      digitalWrite(myLed, HIGH); // toggle red led on
      delay(100);                // wait 100 millisecond
      digitalWrite(myLed, LOW);  // toggle red led off
      delay(1000);               // wait 1000 milliseconds
      VDDA = STM32L0.getVDDA();
      Temperature = STM32L0.getTemperature();
      adc = analogRead(myADC);   
      Serial.print("ADC = "); Serial.println(adc);
      Serial.print("VDDA = "); Serial.println(VDDA, 2); 
      Serial.print("STM32L0 MCU Temperature = "); Serial.println(Temperature, 2);

    I am also reading an ADC and sending out some serial, but these are typical tasks. How much power is used?

    You can see that the average power usage during the active part of the sketch is almost proportional to the clock speed as expected; the proportionality is better when the constant average power (~22 uA) to blink the led is factored out. This means for most applications you want to run at 4.2 MHz clock speed if you can to minimize power usage. In this case, it takes 62 uA to blink the led for 100 ms and read the ADC every five seconds at 4.2 MHz; USB serial is disabled at 4.2 and 16 MHz.

    In stop mode, all state information (SRAM) is retained and after the time out (or upon interrupt when using STM32L0.stop();) the program picks up where it left off.  Best practice is to have all sections of the main loop depend on interrupts and leave the MCU in stop mode otherwise. When the Grasshopper is in stop mode, my multimeter reads 2.1 uA. Now that is ultra-low power!

View all 9 project logs

Enjoy this project?



eamon.moloney wrote 04/23/2021 at 09:09 point


Just wondering what is the recommended way to monitor the battery level?

I read that the Vin could be used as an output to read the there config required to setup vin as an output?

Also, are there hardware mods I would need to do? My hardware knowledge is pretty limited.

Kind regards,Eamon

  Are you sure? yes | no

lj wrote 08/14/2021 at 15:22 point

Hi, I'm also trying figuring this out. Have a look at the Grasshopper schematics/board layout in the EAGLE project ( above). Apparently, the VIN pin can be used to power the board via battery or external power supply, it is connected to the + pin of the battery connector (JP2) (BTW: There's a solder bridge SJ1 that can be used to disable the green status LED to save a bit of energy (and if USB power is never needed, D1 could be removed/bridged)) - VIN is connected to the 3V3 LDO (U5), so it isn't "visible" for the MCU directly. In order to measure the battery voltage, VIN could be connected to an ADC pin with a voltage divider (please correct me if I'm wrong). Depending on the used battery type, the voltage needs to be scaled down to 3.3 V. For example for a LiPo, which is at 4.2 V when fully charged, we'll need a voltage divider of 82k/22k (or similar), that scales 4.2 V down to 3.312 V at max, which is within specs (checked the STM32L082CZ datasheet). - Or is there another better way to monitor the battery voltage? - EDIT: I think that idea is to monitor the battery health by measuring the 3V3 supply voltage. The module can operate at low voltages (down to ~2.4 V according to datasheet), so it will continue to work after the battery voltage has dropped < 3.3 V, so the supply voltage (output of LDO) will no longer be capped and drop below 3.3 V when the battery is depleted. The STM32 has a internal voltage reference, so that drop in voltage can be seen my the MCU. It will not be accurate, and not match the actual battery voltage, but it will be good enough for an IoT node I think. Using a voltage divider like above of about 100 kOhm will already use up unnecessary amounts of energy (4 V / 100k -> 40 uA), which isn't ideal for long term installations... It could be done by simply measuring 3V3 at an ADC pin (?). But there's also that STM32L0.getVDDA() function that looks interesting... (WIP)

  Are you sure? yes | no

Kris Winer wrote 08/16/2021 at 05:58 point

We usually use a 27K/100K voltage divider (on Gnat and long Cricket, for example) but also use a GPIO-enabled dual FET to avoid the ~30 uA current draw. We have also used a 270K/1000K divider with no FET (this draw ~3 uA) but then have to increase the  ADC integration time for stable voltage measurement (Crickt, for example). Grasshopper doesn't have any kind of battery voltage monitoring, but adding a resistor divider on a breadboard is easy to do.

  Are you sure? yes | no

lj wrote 08/17/2021 at 03:48 point

@Kris Winer Thank you for the great board and the tipps! A large voltage divider seems to be indeed the most straight forward solution to monitor the battery voltage, with 270K/1000K resistors the wasted power would be no problem in most cases (a capacitor could be added to stabilize the ADC reading maybe).

I've edited the above post and added another option that might be useful if the
application only needs to detect when the battery starts to run low. In that case it could be good enough to monitor the VDDA voltage, and check if it falls below a certain threshold, e.g. <=2.8 V (according to the SP-ABZ104_B datasheet, the minimum operating voltage is 2.2 V for both ICs, the MCU and the SX1276). The handy STM32L0.getVDDA() function can be used to monitor the Grasshopper's VDDA voltage, which is the same as the 3V3 supply voltage on the board (assuming that the STM32 VDDA pin is connected internally to the module's external VDD_MCU pin). I've tested it with a lab power supply, and the measured VDDA voltage started to drop at about VIN = ~3.5 V. But I'm not entirely sure if the VREF+ solder jumper SJ2 needs to be left connected in that use case? It worked in both cases.

The downside of that approach is that for some battery types/sizes it might be already too late to react and to send out a warning message when the battery voltage already dropped too low, depending on battery capacity, age and environmental conditions. That problem could be mitigated by adding a large buffer capacitor parallel to the battery, and setting the threshold close to 3.3 V.

But yes, if an accurate full-range measurement in a very low-power long-term
installation is required, the safest option would be to use a MOSFET as a switch that is only turned on during the actual battery voltage measurement, something like that could added on a small add-on board, if really necessary.

  Are you sure? yes | no

DrPan69 wrote 03/15/2021 at 14:58 point

Dear Kris,
We are trying to figure out how to make the lorawan protocol working on the boards, could you please give us some hints on how to set a specific channel and spread factor with the LoraWan library for connecting to a single channel gateway. 

  Are you sure? yes | no

Kris Winer wrote 08/16/2021 at 06:00 point

Sorry to have missed this. If you still need help e-mail me at

  Are you sure? yes | no

Brandon Fong wrote 12/10/2020 at 19:45 point


I am trying to program the gnat using dfu-util.exe (using this program through arduino IDE).  It does not seem that the gnat is in dfu mode because the stm32-upload.bat uses up all 10 tries to find the board.  Most of the forums I have researched said I would need to hold a button to execute a reboot or reset, but the gnat board does not have a button.  I was wondering if you know what the issue is?  The last firmware I uploaded is running still, I can see the output through the COM4 Port.  So I believe it might be some hardware issue?  


Brandon Fong 

  Are you sure? yes | no

DanielArnett wrote 08/14/2021 at 00:39 point

@Brandon Fong the gnat does have buttons, the two very small buttons seen in the images above. One says boot, the other says restart. Hold the boot button and tap the restart button, then upload the basic arduino blink program. This will get it working right again. 

  Are you sure? yes | no

Kris Winer wrote 08/16/2021 at 05:59 point

I'll add that when programming from boot mode, best to restart the Arduino IDE such that no COM port shows in the tools menu.

  Are you sure? yes | no

Jorge Herrera Santos wrote 10/26/2020 at 22:54 point

Hello! Thanks for the contribution and for the knowledge shared! I designed a Murata CMWX1ZZABZ LoRa based PCB and I have issues to recognize it from the PC (via USB). I downloaded it ST Drivers and checked schematic but everything seems to be okey... Did anyone have this problem?

  Are you sure? yes | no

Evandro Padrao wrote 10/19/2020 at 19:55 point

I bought a Grasshopper module to assess the technology in a "non-Arduino" project. Initially I will use the module connected to the STM Discovery kit. I would like to know which interface can I use to communicate by AT protocol (serial interface or SPI).

  Are you sure? yes | no

DanielArnett wrote 08/01/2020 at 14:03 point

@Kris Winer I didn't see it mentioned, but it looks like the +/- pins on the Gnat/Grasshopper are 2mm pitch? So something like these connectors should fit? 

  Are you sure? yes | no

Kris Winer wrote 08/01/2020 at 15:12 point

Yes, this is what I use for LiPo battery connection. Of course, you can always just solder the battery in place, but there is no charger on the most common version of the Gnat so not advised. The expansion connectors are Molex PICO blade.

  Are you sure? yes | no

Kris Winer wrote 08/10/2020 at 17:16 point

Yes, these should work.

  Are you sure? yes | no

Kris Winer wrote 08/16/2021 at 06:01 point


  Are you sure? yes | no

DanielArnett wrote 06/17/2020 at 22:18 point

The gnat looks perfect for what I need. My only question is what do I use to receive signals from the gnat? I want a ground station for drones at my local club to log the GPS signals from gnats on each drone. What other hardware should I get ? @Kris Winer 

Also is there an option to keep it on all the time when powered? Do I just set that in the firmware?

  Are you sure? yes | no

Kris Winer wrote 06/17/2020 at 22:45 point

If you want to use the LoRaWAN protocol suitable for a network, you would use a LoRaWAN-capable gateway like the Multitech AP gateway.  This would allow ten or twenty Gnats to talk with the gateway and send their data to a server for collection/processing, etc.

If you just want to communicate point-to-point from the gnat to a ground station using LoRa radio or FSK protocol, then you could use an inexpensive Grasshopper ( or equivalent. Not sure how many Gnats could talk with a single Grasshopper.

You do not have to put the Gnat to sleep; you can run it continuously. But be aware the data throughput with LoRaWAN is low, intended to be a handful of bytes every ten seconds or so. For data rates of kilobytes per second, BLE or wifi might be better choices. A check of the CMWX1ZZABZ module data sheet shows 4.8 kilobits/s (600 bytes/s) as the data rate using  FSK.

  Are you sure? yes | no

DanielArnett wrote 06/17/2020 at 23:11 point

That sounds perfect, thank you! 1 GPS position every 10 seconds would be fantastic for finding a downed aircraft.

  Are you sure? yes | no

jag304 wrote 05/23/2019 at 20:11 point

Are schematic/layout files available for the Long Cricket? 

I've downloaded the zip of documentation and it looks like it's for a different variant.

  Are you sure? yes | no

Samuel Kramer Schwid wrote 02/16/2019 at 23:29 point

hello, where do I find the board the sentinel to buy?

  Are you sure? yes | no

Thorsten von Eicken wrote 07/21/2018 at 23:34 point

Pardon the dumb question: what software do you run on the BMD-350? It looks like a general-purpose nRF52 module. Does the SW you run support multiple slaves?

  Are you sure? yes | no

Kris Winer wrote 07/21/2018 at 23:00 point

At quantity 100 the modules cost around $10, so not much different from RFW95 + STM32L082, for example. The TXCO can be turned off; the sleep current on the Grasshopper dev board is 2.1 uA, 0.5 uA coming from the  LDO. The real benefit of our boards is the STM32L0 system layer and Arduino overlayer (and customized LoRaMAC stack) that is designed to be robust, lightweight, and power efficient. You can use this Arduino-compatible core on other hardware, of course, its just that it is designed with our boards in mind, etc.

  Are you sure? yes | no

Thorsten von Eicken wrote 07/21/2018 at 22:55 point

Nice boards! I've looked at the Murata module and was somewhat turned off by the price. Seems 2x what a LoRa module + an stm32l082 costs, at least in qty 1 at digikey. Do you buy in large qty?

Also, I'm wondering about the tcxo. I don't need a tcxo 'cause I don't really want to operate at the super-low data rates and the downside to a tcxo is that it always consumes >1uA. Is there a way to turn the tcxo off, like in the newer sx1262 LoRa chip?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates