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


  • New Device Added to the Zoo

    Kris Winer02/25/2018 at 18:52 0 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 0 comments


    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 0 comments


    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 7 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

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