Sudden battery drain - Pro-mini + RFM69



  • Hi all,

    I have a node based on Pro-Mini 3v + RFM69 + SI7021 that runs on 2 AA batteries. I use a Raspberry Pi gateway and Openhab as controller.

    I had for the second time the problem of sudden battery drain. In the first time, I assumed the problem was the wearing out of the board (it stays outdoor in a case, but you can see the dirt and humidity kind of making the board + wires look bad).

    I changed the whole kit for a new board, sensor and radio and also changed the bootload for Minicore bootloader (following this instruction).

    However, after after a little more the 1 month, I got the same problem, as you can see below:

    ce20708f-d76e-4da5-83fe-2bbdd4969ed2-image.png

    These were a brand new pair of AA batteries. After a couple of days offline (I was traveling when the sensor shut down), they measured on 2.4V.

    I've checked the log file in Raspberrry, but nothing seemed unusual.

    One thing that called my attention is that the node should check the battery level once a day, but since March 23, it had checked it more frequently.

    Can anyone help me with it?

    This is the node code:

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Yveaux
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a Si7021 sensor.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humiditySi7021
     * 
     */
    
    // Enable debug prints
    //#define MY_DEBUG
    
    // Atualizar para nΓ³ esperado
    #define MY_NODE_ID 3
    
    // Enable REPORT_BATTERY_LEVEL to measure battery level and send changes to gateway
    #define REPORT_BATTERY_LEVEL
    //#define REPORT_BATTERY_LEVEL_EXT
    
    // Novo driver para gateway RPI
    #define MY_RFM69_NEW_DRIVER
    
    // Enable and select radio type attached 
    //#define MY_RADIO_RF24
    #define MY_RADIO_RFM69
    //#define MY_RS485
    
    #define MY_RFM69_FREQUENCY RFM69_433MHZ  // Define for frequency setting. Needed if you're radio module isn't 868Mhz (868Mhz is default in lib)
    //#define MY_IS_RFM69HW  // Mandatory if you radio module is the high power version (RFM69HW and RFM69HCW), Comment it if it's not the case
    
    
    #include <MySensors.h>  
    
    static bool metric = true;
    
    // Sleep time between sensor updates (in milliseconds)
    static const uint64_t UPDATE_INTERVAL = 600000; // 600000 = 10 minutos
    
    #include <SI7021.h>
    static SI7021 sensor;
    
    #ifdef REPORT_BATTERY_LEVEL_EXT
    
    //  BatteryPoweredSensor - Code
      int BATTERY_SENSE_PIN = A1;  // select the input pin for the battery sense point
    //  int oldBatteryPcnt = 0;
    
    #endif
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_RSSI 2               //RSSI
    #define CHILD_ID_VOLT 3               //Battary Voltage
    
    int16_t rssiVal;               //RSSI
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgRSSI(CHILD_ID_RSSI,V_VAR5);
    MyMessage msgVOLT(CHILD_ID_VOLT,V_VOLTAGE);
    
    // Variables for update intervals and other
    
    static const float min_temp_chg = 0.4;    // min change to send temperatura - 0.4 C (sensor error)
    static const uint8_t min_hum_chg = 3;   // min change to send humidity - 3% (sensor error)
    static const uint8_t interv_temp = 72;      // 12 hrs * 6 measurement / hour = 72
    static const uint8_t interv_hum = 72;     // 12 hrs * 6 measurement / hour = 72
    static const uint8_t interv_bat_rssi = 144; // 24 hrs * 6 measurement / hour = 144
    
    float last_temp;
    float last_hum;
    uint8_t cont_temp = interv_temp + 1;
    uint8_t cont_hum = interv_hum + 1;
    uint8_t cont_bat_rssi = interv_bat_rssi + 1;
    
    
    void presentation()  
    { 
      Serial.println("Presentation Begin");
      
      // Send the sketch info to the gateway
      sendSketchInfo("Si7021_Tem_Hum_v07", "2.0");
    
      // Present sensors as children to gateway
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_RSSI, S_CUSTOM);
      present(CHILD_ID_VOLT, S_MULTIMETER);
    
      metric = getControllerConfig().isMetric;
      Serial.println("Presentation OK");
      
      #ifdef MY_DEBUG
          
      #endif
    }
    
    void setup()
    {
    
      Serial.println("Setup Begin");
      
       while (not sensor.begin())
       {
         Serial.println(F("Sensor not detected!"));
         delay(5000);
       }
    
      // use the 1.1 V internal reference
      #if defined(__AVR_ATmega2560__)
        analogReference(INTERNAL1V1);
      #else
        analogReference(INTERNAL);
      #endif
    
      Serial.println("Setup OK");
      
    }
    
    
    void loop()      
    {  
    
      #ifdef MY_DEBUG
        Serial.println("Loop begin");
        
        Serial.print(F("min_temp_chg "));
        Serial.println(min_temp_chg);
        Serial.print(F("min_hum_chg "));
        Serial.println(min_hum_chg);
        Serial.print(F("interv_temp "));
        Serial.println(interv_temp);
        Serial.print(F("interv_hum "));
        Serial.println(interv_hum);
        Serial.print(F("interv_bat_rssi "));
        Serial.println(interv_bat_rssi);
        
        Serial.print(F("last_temp "));
        Serial.println(last_temp);
        Serial.print(F("last_hum "));
        Serial.println(last_hum);
        Serial.print(F("cont_temp "));
        Serial.println(cont_temp);
        Serial.print(F("cont_hum "));
        Serial.println(cont_hum);
        Serial.print(F("cont_bat_rssi "));
        Serial.println(cont_bat_rssi);   
      #endif
      
      // Read temperature & humidity from sensor.
      const float temperature = float( metric ? sensor.getCelsiusHundredths() : sensor.getFahrenheitHundredths() ) / 100.0;
      const float humidity    = float( sensor.getHumidityBasisPoints() ) / 100.0;
    
      #ifdef MY_DEBUG
        Serial.print(F("Temp "));
        Serial.print(temperature);
        Serial.print(metric ? 'C' : 'F');
        Serial.print(F("\tHum "));
        Serial.println(humidity);
      #endif
    
      if ( abs(last_temp - temperature) > min_temp_chg || cont_temp > interv_temp) {
          send(msgTemp.set(temperature, 2));
          cont_temp = 0;
          last_temp = temperature;
      } else {
        cont_temp = cont_temp + 1;
      }
      
      if ( abs(last_hum - humidity) > min_hum_chg || cont_hum > interv_hum) {
          send(msgHum.set(humidity, 2));
          cont_hum = 0;
          last_hum = humidity;
      } else {
        cont_hum = cont_hum + 1;
      }
      
      if ( cont_bat_rssi > interv_bat_rssi ) {
        #ifdef REPORT_BATTERY_LEVEL
          // get the battery Voltage
    
          #ifdef REPORT_BATTERY_LEVEL_EXT
                // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                // 3.44/1023 = Volts per bit = 0.003363075
    
            int sensorValue = analogRead(BATTERY_SENSE_PIN);    
            float batteryV  = sensorValue * 0.003216031; // medido
            send(msgVOLT.set(batteryV, 2));
            
            #ifdef MY_DEBUG     
              Serial.print("Sensor Read: ");
              Serial.println(sensorValue);
              Serial.print("External volt: ");
              Serial.print(batteryV);
              Serial.println(" V");
            #endif
            
          #else
            long batteryMillivolts = hwCPUVoltage();
            send(msgVOLT.set(batteryMillivolts / 1000.0, 2));
            #ifdef MY_DEBUG
              Serial.println("Else");
              Serial.print(batteryMillivolts / 1000.0);
              Serial.println(" V");
            #endif
          #endif
        #endif
    
        rssiVal = RFM69_getReceivingRSSI();  // New Driver
        send(msgRSSI.set(rssiVal, 2));
        
        #ifdef MY_DEBUG
          Serial.print("RSSI: ");
          Serial.println(rssiVal);
        #endif
        cont_bat_rssi = 0;
    
      } else {
        cont_bat_rssi = cont_bat_rssi + 1;
      }
    
      // Sleep until next update to save energy
      #ifdef MY_DEBUG
        Serial.println("Sleep Start");
      #endif
      
      sleep(UPDATE_INTERVAL);
      
      #ifdef MY_DEBUG
      Serial.println("Wake up!");
      #endif
    }
    


  • I suggest you take apart the node and give it a good clean - check for any tiny cracks or dry joints on soldered items and if using dupont connectors then clean thoroughly with isopropyl alcohol. Replace any connectors that don't clean up too well. =

    Dirt and moisture can cause a lot of problems for electronics and batteries.

    Sudden drops in voltage can also be caused by sudden drops of temperature or wind chill. I just posted a few days back a 1 year record of a PIR sensor with daily battery readings, it is not a smooth fall-off as most people might expect. I correlate the biggest sudden drop with a period of very cold and windy weather in February. It is in the battery powered section if you want to see it.

    Finally as you have a 3.3V pro mini and power from 2xAA batteries I suggest you remove the battery monitoring from A1 and the associated components and instead use the internal voltmeter method.

    Good Luck!



  • Thanks @skywatch for the reply.

    The board is pretty clean. After your comments, I also checked the led and regulator contacts (I removed both, mediocre but good enough job).

    However, I think the battery contacts have oxidized. I cleaned that and am testing again.

    Does anyone have any tips on how to avoid battery terminals to get oxidized? Adding solder tin on that battery case avoids that?

    Thanks!



  • In case someone has the same issue, quick update:

    I cleaned the battery contacts, added some solder (maybe they would not get oxidized) and put new batteries.

    However, after 6 days, there was the sudden drop in battery again. From 3.0 to 2.5 in less than 24 hours.

    Still don't know what is the problem...



  • @Oumuamua I strongly suggest your problem is moisture related, been there done that.

    My external nodes are all in weatherproof boxes (Gewiss surface mounted modular light switch box with the transparent hinged front cover - I dremel off the switch tangs) with a roasted clay desiccant pack thrown in to cope with any moisture which may creep in on the cables over winter, then the front is latched shut.

    No oxidisation is possible so long as the box is weatherproof (sealed), as any internal moisture is absorbed by the desiccant (a reactivated silica gel pack will work) when you close it up.

    My gas meter node was like that, running for 4 winters down to -20 and never skipped a beat - It was like new when I changed the batteries, and ultimately took it apart, zero corrosion.



  • Thanks @zboblamont !

    I will try changing to a weatherproof case.

    Today I realized I started having the sudden battery drain after I moved to a Raspberry PI gateway and therefore had to add #define MY_RFM69_NEW_DRIVER to my code.

    Could it also be the case that the new driver has some bug that consumes the battery (e.g. holds the radio on)?

    Thanks,



  • @Oumuamua Sorry but I've no idea - I didn't update the MySensors side of the system once everything on the Gateway and Controller were working perfectly 5 years ago - Only Domoticz updates on the Pi Controller have interrupted it, the arduino gateway and disc drive have run 24/7 through multiple power cuts on the UPS.

    It does seems unlikely the driver is at fault given so many others updated and none have reported such a bug.

    IIRC the new driver has to be installed on ALL devices using the rfm, so I'll update the Gateway in summer when swapping out the UPS battery and drive.



  • I haven’t moved the sensor to a weatherproof case (still figuring out the new design), but I connected it to an external power source.

    The circuit is operating perfectly.

    If humidity or something alike had damaged it, it should be not working, right?

    Although I think it is important to use the weatherproof case, I feel something else is happening here.

    @skywatch: where I live in BR temperature ranges between 5-36C. I can see some fluctuations in battery V when temp changes, but usually around 0.05V

    Thanks!



  • That's good news.

    Moisture would not necessarily have damaged it permanently, it's more a case of humidity can play havoc with tiny electronics and wiring when it condenses.

    The advantage of a weatherproof box in my environment is obvious, but it has advantage elsewhere as it's a controlled and sealed environment inside - If closed up dry it stays dry.



  • Hi all,

    Should anyone face the same problem, I found the root cause: brownout threshold. I burned a new bootloader (Optiboot 8.0) without such trigger and the node has been working with used batteries (~2.7V) since May.

    Hope this helps.



Suggested Topics

21
Online

11.2k
Users

11.1k
Topics

112.5k
Posts