In a previous blog post I wrote about my experiences with building a wireless sensor network in my home using Arduino Uno and a RaspberryPi. After finishing the post I switched everything on and prepared to wait a few days to see the results. To my surprise, however, the batteries on the two transmitting Unos ran out after about 14-16 hours. I would like the batteries to last for several weeks, so I have some work to do. After browsing the internet for a while, I came across several potential solutions:

  • I used 9V batteries, even though the Uno runs on 5V. The Uno has a linear regulator to convert the 9V to 5V, and apparently this is terribly inefficient. Various people suggested powering the Uno with a 5V powerbank commonly used for charging mobile phones and tablets. An alternative solution is to use a regulator that is more efficient and bypass the one on the Uno.
  • The 9V battery has a capacity of about 600 mAh, and the Uno alone already draws about 45mA. So a continuously running an Uno with 9V battery will simply not last longer than 600/45=13.3 hours. For my sensor I put the Uno to sleep now and then, which makes the battery last a bit longer. But I also have the DHT22 (using 2.5mA) and the transmitter (using 15mA). So I have to save power somewhere (and use a bigger battery).
  • There are some power-saving libraries online that may be helpful: Low-Power, Narcolpetic, Enerlib.
  • Improve reception (i.e. the antenna) so that I do not have to send each packet 3 times.
  • The DHT22 is only accurate to 0.5 degrees (for temperature) and 2-5% (for humidity), so sending the second digit for temperature and either digits for humidity is pointless.
  • I should not light the LED during a transmission.

For my second experiment I decided to make the following changes to the transmitters (code below) and the experiment:

  • use the Low-Power library
  • disable power to the DHT22 after using it
  • I tried the same thing with the transmitter, but couldn’t get it to any packets to be transmitted. More later, perhaps. [Edit: later I got it to work by not using the PWN(~) pins]
  • [Edit: I am not at all sure whether turning of the power to DHT22 and transsmitter is necessary. Perhaps the Low-power lib does something similar for me.]
  • The shop where I bought the batteries for the first experiment ran out of the brand I used, so the next experiment uses other (more expensive) 9V batteries
  • I ran the transmitter code of the first experiment on the Uno in my bedroom, and the new code on the Uno in my bathroom (to account for the different batteries in this experiment)

The Uno in my bathroom (running the modified code) transmitted for 16 hours, the other Uno lasted 12 hours. So using the low-power library and switching of the DHT22 improved life time for about 30%. And, apparently, buying more expensive batteries does not necessarily mean a higher capacity.

[Edit: later, I learned that the difference was most likely not caused by my modifications, but by one of the Arduino Uno boards using less power than others (I bought them from different suppliers)]

All in all the 30% is a nice gain, but it seems hopeless to expect a life time of several weeks on a 9V battery. I am going to do some more experimenting, and let you know about progress!

Transmitter code

//Tx of temp/hum readings from DHT22
//Written By : Martijn Onderwater
// 11-04-2015
//http://www.martijn-onderwater.nl
//…………………………….

#include //for 433MHz tx
#include “LowPower.h”
#include “DHT.h”//for dht22 (and 11)

#define DHT_5V_PIN 2 // what pin powers dht
#define DHTPIN 3 // what pin to read dht data
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define ARDUINO_ID 1 // id of this sensor node
#define TRANSMITTER_DATA_PIN 12 // data pin of transmitter

//global vars
DHT dht(DHTPIN, DHTTYPE);
char* data;
unsigned long num_8s_sleep_cycles = 15;
int repeat = 3;
int timeBetweenRepeat = 500;

void setup() {

//Set the 5V pin of DHT22 to OUTPUT. Also led on pin 13
pinMode(13,OUTPUT);
pinMode(DHT_5V_PIN, OUTPUT);

//setup transmitter
vw_set_ptt_inverted(true);
vw_set_tx_pin(TRANSMITTER_DATA_PIN);
vw_setup(4000);// speed of data transfer Kbps

//for debugging
Serial.begin(9600);
Serial.println(“This is the transmitter!”);
}

void loop(){

//enable LED
digitalWrite(13,HIGH);

//read from dht22
digitalWrite(DHT_5V_PIN, HIGH);//enable power
dht.begin();
delay(500);//it seems DHT22 needs some time to start up
float h = dht.readHumidity();
float t = dht.readTemperature();
digitalWrite(DHT_5V_PIN, LOW);//disnable power

// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println(“Failed to read from DHT sensor!”);
}
else{
//some debug info
Serial.print(“Humidity: “);
Serial.print(h);
Serial.print(” %\t”);
Serial.print(“Temperature: “);
Serial.println(t);

//send packet a few times, because quite a few are lost
for(int cnt=0;cnt<repeat;cnt++){
//format data string
data = new char[VW_MAX_MESSAGE_LEN];;
sprintf(data,”%d %d %d”,ARDUINO_ID, (int)(t*100), (int)(h*100));
Serial.println(data);
vw_send((uint8_t*)data, strlen(data));
vw_wait_tx(); // Wait until the whole message is gone
delete data;
delay(timeBetweenRepeat);
}

//led off
digitalWrite(13,LOW);
}//else

for (int i = 0; i < num_8s_sleep_cycles; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}

}