High power consumption.

Started by mattt, August 09, 2014, 03:57:26 PM

mattt

I was hoping someone could give me some pointers as to where i'm going wrong with a low power temp/hum node. I have been studying the low power sticky thread and I am using some of the available libraries for low power. I am using a moteino rfm69hw with an adafruit HTU21D powered by a 9v battery. According to the HTU21D datasheet http://www.adafruit.com/datasheets/1899_HTU21D.pdf, the sensor should be using 0.02 microamps when idle and 500 microamps when measuring every 30 seconds. The first sketch I was using with no battery saving techniques and the 9v battery would last for about 8 hours. After introducing power saving code and sleep for the transmitter the node ran for the same amount of time. I was hoping for a noticeable improvement. Here is the sketch i'm using.

#include <RFM69.h>
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_HTU21DF.h"
#include <JeeLib.h>

ISR(WDT_vect) { Sleepy::watchdogEvent(); }

#define NODEID      2
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_433MHZ         //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey"  //has to be same 16 characters/bytes on all nodes, not more not less!

#define SERIAL_BAUD 115200

boolean requestACK = true;              
#define ACK_TIME    15                  // Numbers of ms to wait for an ack
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
float celsius;
float humidity;
RFM69 radio;

// ########################################################################################################################
// Data Structure to be sent
// ########################################################################################################################
typedef struct {
  int nodeId;        
  float temp;
  float hum;
} 
Payload;
Payload theData;

// ########################################################################################################################
// SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP
// ########################################################################################################################
void setup(){
  Serial.begin(SERIAL_BAUD);  
  Serial.println("*** RF-Sender (433 MHz) ***");
  Serial.print("*** NodeID: "); 
  Serial.print(NODEID);
  Serial.print(", Group: "); 
  Serial.println(NETWORKID);
  Serial.println("***************************");

  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.encrypt(KEY);
  radio.setHighPower();
  radio.setPowerLevel(8);
  radio.sleep();
  if (!htu.begin()) { //Adafruit temp/hum sensor
    Serial.println("Couldn't find sensor!");
    while (1);}
}

// ########################################################################################################################
// LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP
// ########################################################################################################################
void loop() {
  celsius = htu.readTemperature();
  humidity = htu.readHumidity();

  theData.nodeId = 2;
  theData.temp = celsius;
  theData.hum = humidity;
  

  //theData.Vcc = readVcc();       // Get supply voltage

  //Serielle Ausgabe
  Serial.print("Node ID: ");
  Serial.println(theData.nodeId);
  Serial.print("Temp: ");
  Serial.println(theData.temp);
  Serial.print("Hum: ");
  Serial.println(theData.hum);

  radio.send(GATEWAYID, (const void*)(&theData), sizeof(theData), requestACK); 
  if (requestACK)
  {
    if (waitForAck(GATEWAYID))
      Serial.println("> ACK ok");
    else 
      Serial.println("> no ACK!");
  }
  Serial.println("*****************");
  radio.sleep(); 
  Sleepy::loseSomeTime(30000);
  //delay(5000);
}


// ########################################################################################################################
// waitForAck
// ########################################################################################################################
//wait a few milliseconds for proper ACK to me, return true if indeed received
static bool waitForAck(byte theNodeID)
{
  long now = millis();
  while (millis() - now <= ACK_TIME) {
    if (radio.ACKReceived(theNodeID))
      return true;
  }
  return false;
}
// ########################################################################################################################


I did some math and assuming the 9v battery is around 400mAh and the sensor is reading 500 microamps every 30 seconds I guess it will drain the battery after 6.6 hours. On the datasheet for the sensor it talks about how its ideal for battery powered applications. I'm thinking its probably too power hungry for my needs. I was hoping to realistically power a small node for 6 months - year. Even with a larger lipo battery this would only give me a few weeks.

Felix

I think the sketch looks ok. I have never used the jeelib loosesometime. I recommend the narcoleptic library which is something I used and I know works well:

#include <LowPower.h> //get library from: https://github.com/rocketscream/Low-Power

See this sketch for sample usage:
https://github.com/LowPowerLab/RFM69/blob/master/Examples/MotionMote/MotionMote.ino

You need to verify that your sensor is not keeping the node awake. Also you should check your power consumption with a meter to see for real when the node is sleeping (it should be close to 99.9% of time otherwise it's not sleeping).

mattt


Lensdigital

Quote from: mattt on August 10, 2014, 02:50:32 PM
Great! thanks for the advice.
Matt, I was able to run Moteino R2 with Temperature/Humidy sensor off single AAA battery for a little over 6 months. I configured it to get data from sensor and send it every 5 minutes, and sleep rest of the time.

ltj

@matt, you should be fine using the jeelib sleepy method. There's no significant difference between sleepy, lowpower and narcoleptic. They basically do the same thing.

As suggested you really ought to get much more milage out of you current setup. But sleeping for 30 secs only gets you so far btw. If you peek into the adafruit HTU21 lib you can see that they use 10ms of delay in every measurement function. That means you spend 20 ms at full uC power every time you read the temp. and humidity. Replace those delay()'s with loseSomeTime or whatever you choose to use. Furthermore, you can get rid of all Serial outputs when not debugging and maybe also the ack waiting (typically you don't care about these unless you want your node to somehow behave intelligently to not getting a response). And like lensDigital writes, setting your send interval to, say, just a minute will half your average power consumption.

Good luck  ;)