Low power sketch burns batteries

  • Hi Everybody,

    I built a temp/hum sensor based on the My Slim node (https://forum.mysensors.org/topic/2745/my-slim-2aa-battery-node?_=1664381788684).
    The first prototype I built is running perfectly for about 1 year now without any battery change.

    But then I started playing with the sketch as I want the battery to report the level. But my sketch seems to have an error somewhere as it seems to drain the batteries really fast. I cannot find the error.

    Can anybody spot the issue? It seems that either the battery level is published too often or the process of measureing the battery level is burning elctricity.

    The commented out part is something I tried but it didn't work.

    Any help is highly appreciated!!

     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     * v1.0: Yveaux
     * v1.01: Maddhin
     * v1.02: changed to Adafruit HTU21D library, minor bugs and updates
     * v1.03: first production version
     * v1.04: change debug serial.print handling, minor modifications
     * v1.05 29.12.2021: modifikations to battery reporting adding heartbeat battery reporting
     * v1.06 20.01.2022: revision to simple v4 battery reporting
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a HTU21D sensor.
     *   */
    #define SKETCH_NAME "TempSen_HTU21D_v6"     //<--------- UPDATE sketch name!!!
    #define SKETCH_VERSION "1.06"               //<--------- UPDATE version nummer!!!
    // Enable debug prints
    //#define MY_DEBUG                   //<--------- switch DEBUG mode on/off
    // Enable REPORT_BATTERY_LEVEL to measure battery level and send changes to gateway
    // Enable and select radio type attached 
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    #define MY_NODE_ID 105
    //#define MY_PARENT_NODE_ID 0
    //#define MY_RF24_PA_LEVEL RF24_PA_MAX
    #include <MySensors.h>  
    #define CHILD_ID_HUM  0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_VOLT 2
    static MyMessage msgHum( CHILD_ID_HUM,  V_HUM );      // Node humidity
    static MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);      // Node temperature
    static MyMessage msgVolt(CHILD_ID_VOLT, V_VOLTAGE);   // Node voltage
    // Sleep time between sensor updates (in milliseconds)
    static const char SLEEP = 5;
    static const uint64_t UPDATE_INTERVAL = SLEEP*60000;      // x * 1 min
    //static const uint64_t UPDATE_INTERVAL = 5000;       //for debugging: 5s intervall
    #include "Adafruit_HTU21DF.h"
    Adafruit_HTU21DF sensor = Adafruit_HTU21DF();
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
      #include <Vcc.h>
      static uint8_t oldBatteryPcnt = 200;  // Initialize to 200 to assure first time value will be sent.
      const float VccMin        = 1.8;      // Minimum expected Vcc level, in Volts: Brownout at 1.8V    -> 0%
      const float VccMax        = 2.0*1.6;  // Maximum expected Vcc level, in Volts: 2xAA fresh Alkaline -> 100%
      const float VccCorrection = 1.03;      // Measured Vcc by multimeter divided by reported Vcc
      static Vcc vcc(VccCorrection); 
      int irtCounter = 0;
      #define BATTERY_REPORT_BY_IRT_CYCLE 24*60/SLEEP  // Make a battery report after this many trips. Here once per day = 24h * 60min / update interval (ms) / 60000ms (calc in minutes)
    #ifdef MY_DEBUG
     #define DEBUG_PRINT(x)    Serial.print (x)
     #define DEBUG_PRINTDEC(x) Serial.print (x, DEC)
     #define DEBUG_PRINTLN(x)  Serial.println (x)
     #define DEBUG_PRINT(x)
     #define DEBUG_PRINTDEC(x)
     #define DEBUG_PRINTLN(x)
    void presentation()  
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
      //show reporting cycles until battery report is triggered
      DEBUG_PRINT("Battery reporting cycles: "); 
      // Present sensors as children to gateway
      present(CHILD_ID_HUM, S_HUM,   "Humidity");
      present(CHILD_ID_TEMP, S_TEMP, "Temperature");
      present(CHILD_ID_VOLT, S_MULTIMETER, "Voltage");
    void setup()
      while (!sensor.begin())
        DEBUG_PRINTLN(F("Sensor not detected!"));
    void loop()      
      // Read temperature & humidity from sensor.
        const float temperature = float( sensor.readTemperature() );
        const float humidity    = float( sensor.readHumidity() );
        DEBUG_PRINT(F("Temp "));
        DEBUG_PRINT(F("\tHum "));
        send(msgTemp.set(temperature, 1));
        send(msgHum.set(humidity, 1));
      // Battery Reporting
        const uint8_t batteryPcnt = static_cast<uint8_t>(0.5 + vcc.Read_Perc(VccMin, VccMax));
        DEBUG_PRINT(F("Vbat "));
        DEBUG_PRINT(F("\tPerc "));
    //    irtCounter++;
    //    // Battery readout should only go down. So report only when new value is smaller than previous one.
    //    if ( batteryPcnt < oldBatteryPcnt )
    //    {
    //      send(msgVolt.set(vcc.Read_Volts(),2));
    //      sendBatteryLevel(batteryPcnt);
    //      oldBatteryPcnt = batteryPcnt;
    //      irtCounter=0;
    //    }
    //    // Report battery in intervals (typically every 24h)
    //    else {
    //      if (irtCounter>=BATTERY_REPORT_BY_IRT_CYCLE) {
    //      irtCounter=0;
    //      send(msgVolt.set(vcc.Read_Volts(),2));
    //      sendBatteryLevel(batteryPcnt);
    //    }
    //    }
        // Battery readout should only go down. So report only when new value is smaller than previous one.
        if ( batteryPcnt < oldBatteryPcnt )
          oldBatteryPcnt = batteryPcnt;
      // Sleep until next update to save energy

Log in to reply

Suggested Topics