Low-power LoRa device

A low-power LoRa temperature sensor #

We will describe in this tutorial how to build a low-power LoRa temperature sensor capable of running several years on 2 AA batteries and ready to be deployed in a real-world scenario.

Many of the parameters used in this example are similar to those explained in Arduino LoRa demo sensor. We’ll explain the additional few parameters being used here to build an operational IoT device with periodic sensing and low-power mode to be able to run on regular batteries for years. You can access the full working example on the Arduino LoRa examples github page.

Explanation of the code #

From the sketch named Arduino_LoRa_simple_temp.ino, we have the following code.

We store in EEPROM the transmitted packet sequence number so that the device keeps the continuing numbering after a reboot.

#define WITH_EEPROM

We enable the low power consumption mode which is the most important setting introduced by the simple temperature sensor example compared to the demo sensor example.

#define LOW_POWER

We can ask for an acknowledgement from the gateway. It is not recommended in operational scenarios but it is useful to test here.

#define WITH_ACK

The time taken in minutes between two readings and transmission can be defined.

unsigned int idlePeriodInMin = 10;

If low-power mode, then we include the low-power library

#ifdef LOW_POWER
 #define LOW_POWER_PERIOD 8
 // you need the LowPower library from RocketScream
 // https://github.com/rocketscream/Low-Power 
 #include "LowPower.h"
#endif

In the setup() function the initialisation procedure is similar to the one of demo sensor example.

In the loop() function, if low power mode, then power the temperature sensor

#ifdef LOW_POWER
  digitalWrite(PIN_POWER,HIGH);
  delay(200);   
#endif

Then, we get multiple values from the sensor, to calculate a mean value

  for (int i=0; i<5; i++) {
    temp += sensor_getValue();  
    delay(100);
  }

Then power down the sensor

#ifdef LOW_POWER
  digitalWrite(PIN_POWER,LOW);
#endif

Message format

  uint8_t r_size;
  char float_str[10];

  //the recommended format  \!TC/22.5
  //convert the floating value into a string
  ftoa(float_str,temp,2);
  r_size=sprintf((char*)message,"\\!#%d#%s/%s",field_index,nomenclature_str,float_str);

Send message to the gateway after performing carrier sense mechanism. Note that we can request an acknowledgment from the gateway by adding the PKT_FLAG_ACK_REQ option to PKT_TYPE_DATA.

  LT.CarrierSense();
#ifdef WITH_ACK
  p_type=PKT_TYPE_DATA | PKT_FLAG_ACK_REQ;     
#endif
  LT.transmitAddressed(message, r_size, p_type, DEFAULT_DEST_ADDR, LT.readDevAddr(), 10000, MAX_DBM, WAIT_TX)

We first switch the radio module in power saving mode and then determine how many 8s period we need to sleep.

#if defined LOW_POWER
  LT.setSleep(CONFIGURATION_RETENTION);
  
  nCycle = idlePeriodInMin*60/LOW_POWER_PERIOD; 
      
  for (int i=0; i < nCycle; i++) {  
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                                     
  }      
#endif
The raw source of the sketch example is visible here.

You can look at the Arduino_LoRa_Simple_DHT example on our GitHub which replaces the simple analog temperature sensor with the digital DHT22 sensor.

You can have a look at the following video that further shows how to reduce the power consumption by removing the power led and the voltage regulator.

For advanced users #

For the most courageous of you, you can go further and have a look at the Arduino_LoRa_Generic_DHT example on our github repository which shows a more “generic” approach to handle physical sensors: all physical sensors must be derived from a base Sensor class (defined in Sensor.cpp and Sensor.h) and should provide a get_value() and a get_nomenclature() function that will be called in the main program loop.

Then you can look at the Arduino_LoRa_Generic_Simple_MultiSensors` example on our github repository which shows how to handle multiple physical in the same “generic” manner than previously. The example drives 5 physical sensors for 7 logical sensors as 2 physical sensors provide both temperature and humidity. The example also includes sensor classes for:

  • very simple LM35DZ analog temperature sensor
  • very simple TMP36 analog temperature sensor
  • digital DHT22 (AM2302) temperature and humidity sensor (work also with the AM2305)
  • digital SHT1x and SHT2x temperature and humidity sensor from Sensirion
  • digital DS18B20 temperature sensor
  • ultra-sonic HC-SR04 distance sensor
  • Davies Leaf Wetness sensor
  • general raw analog sensor

This example runs the sensor node in Congduc Pham’s office in University of Pau, France which drives several temperature and humidity physical sensors (the test is also for comparison purpose). The associated gateway pushes data to ThingSpeak channel 66583 and WAZIUP platform as UPPA-TESTS-Sensor3. To visualize on WAZIUP platform, you may need to login as guest (password is also guest) first.

Congratulations #

We are reaching the end of this online tutorial. If you made your way to these finals steps and everything is working fine then CONGRATULATIONS from the WAZIUP/WAZIHUB team!

Enjoy!

2019 - Muhammad Ehsan, Mamour Diop & Congduc Pham