Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Battery percentage gone wild [SOLVED]

Battery percentage gone wild [SOLVED]

Scheduled Pinned Locked Moved Troubleshooting
27 Posts 6 Posters 2.8k Views 6 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Strixx
    wrote on last edited by Strixx
    #1

    Hello,

    I'm building my first battery powered sensor. A simple temperature sensor using a Pro Mini with a DS18b20.
    The temperature reading works just fine, but the battery reading is all crazy.
    I have wired it just like the example.

    When connected to the serial programmer the reading seems fine. The reading jumps up and down but never goes above 100%. I guess fluctuation is due to the powering from the FTDI, and the battery only connected to radio and tap point to A0.

    But when on battery power I got readings every sleep cycle of 120-300%. This is my code:

    // ------------------ MYSENSORS ------------------
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    // Set the frequency to channel 110 (2,510MHz), to prevent interference of WiFi channel 14 (-2,495MHz)
    #define MY_RF24_CHANNEL 110
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    unsigned long SLEEP_TIME =  5 * 60000; // Sleep time between reads (in milliseconds), 60000 ms = 1 minute
    
    // ------------------ TEMPERATURE ------------------
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 1
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    // ------------------ BATTERY ------------------
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;  // remember last measured percentage
    #define V_MIN 2.7  // 0% Battery voltage
    #define V_MAX 3.3  // 100% Battery voltage
    
    void before()
    {
      sensors.begin();
    }
    
    void setup()
    {
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
      // Setup 1.1 V internal reference for analoge GPIO
      analogReference(INTERNAL);
    }
    
    void presentation()
    {
       // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Hottub", "2.1");
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    }
    
    void loop()
    {
      // read analog pin
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
      // calculate battery voltage
      float vBat  = static_cast<float>(sensorValue * (V_MAX/1023));
      // calculate % left of defined interval
      int batteryPcnt = static_cast<int>(((vBat-V_MIN)/(V_MAX-V_MIN))*100.);  
      // debugging
      #ifdef MY_DEBUG
        Serial.print("Sensor value: ");
        Serial.println(sensorValue);
        Serial.print("Battery Voltage: ");
        Serial.print(vBat);
        Serial.println(" V");
        Serial.print("Battery percent: ");
        Serial.print(batteryPcnt);
        Serial.println(" %");
      #endif
      // If battery % has change send to controller
      if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
      }
    
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      sleep(conversionTime);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
          if (temperature != -127.00 && temperature != 85.00) {
        #endif
    
          // Send in the new temperature
          send(msg.setSensor(i).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
      sleep(SLEEP_TIME);
    }
    

    How can the value ever be greater than 100% and only when powered with battery and not with the serial programmer?

    What am I missing? I have been struggling with this for 2 days now, and can't come up with any more ideas to try!

    sundberg84S 1 Reply Last reply
    0
    • S Strixx

      Hello,

      I'm building my first battery powered sensor. A simple temperature sensor using a Pro Mini with a DS18b20.
      The temperature reading works just fine, but the battery reading is all crazy.
      I have wired it just like the example.

      When connected to the serial programmer the reading seems fine. The reading jumps up and down but never goes above 100%. I guess fluctuation is due to the powering from the FTDI, and the battery only connected to radio and tap point to A0.

      But when on battery power I got readings every sleep cycle of 120-300%. This is my code:

      // ------------------ MYSENSORS ------------------
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      // Set the frequency to channel 110 (2,510MHz), to prevent interference of WiFi channel 14 (-2,495MHz)
      #define MY_RF24_CHANNEL 110
      
      #include <SPI.h>
      #include <MySensors.h>  
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      unsigned long SLEEP_TIME =  5 * 60000; // Sleep time between reads (in milliseconds), 60000 ms = 1 minute
      
      // ------------------ TEMPERATURE ------------------
      #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
      #define MAX_ATTACHED_DS18B20 1
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors=0;
      bool receivedConfig = false;
      bool metric = true;
      // Initialize temperature message
      MyMessage msg(0,V_TEMP);
      
      // ------------------ BATTERY ------------------
      int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
      int oldBatteryPcnt = 0;  // remember last measured percentage
      #define V_MIN 2.7  // 0% Battery voltage
      #define V_MAX 3.3  // 100% Battery voltage
      
      void before()
      {
        sensors.begin();
      }
      
      void setup()
      {
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      
        // Setup 1.1 V internal reference for analoge GPIO
        analogReference(INTERNAL);
      }
      
      void presentation()
      {
         // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Hottub", "2.1");
        // Fetch the number of attached temperature sensors  
        numSensors = sensors.getDeviceCount();
      
        // Present all sensors to controller
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
           present(i, S_TEMP);
        }
      }
      
      void loop()
      {
        // read analog pin
        int sensorValue = analogRead(BATTERY_SENSE_PIN);
        // calculate battery voltage
        float vBat  = static_cast<float>(sensorValue * (V_MAX/1023));
        // calculate % left of defined interval
        int batteryPcnt = static_cast<int>(((vBat-V_MIN)/(V_MAX-V_MIN))*100.);  
        // debugging
        #ifdef MY_DEBUG
          Serial.print("Sensor value: ");
          Serial.println(sensorValue);
          Serial.print("Battery Voltage: ");
          Serial.print(vBat);
          Serial.println(" V");
          Serial.print("Battery percent: ");
          Serial.print(batteryPcnt);
          Serial.println(" %");
        #endif
        // If battery % has change send to controller
        if (oldBatteryPcnt != batteryPcnt) {
          // Power up radio after sleep
          sendBatteryLevel(batteryPcnt);
          oldBatteryPcnt = batteryPcnt;
        }
      
        // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
      
        // query conversion time and sleep until conversion completed
        int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
        sleep(conversionTime);
      
        // Read temperatures and send them to controller 
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
      
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
      
          // Only send data if temperature has changed and no error
          #if COMPARE_TEMP == 1
            if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
          #else
            if (temperature != -127.00 && temperature != 85.00) {
          #endif
      
            // Send in the new temperature
            send(msg.setSensor(i).set(temperature,1));
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
          }
        }
        sleep(SLEEP_TIME);
      }
      

      How can the value ever be greater than 100% and only when powered with battery and not with the serial programmer?

      What am I missing? I have been struggling with this for 2 days now, and can't come up with any more ideas to try!

      sundberg84S Offline
      sundberg84S Offline
      sundberg84
      Hardware Contributor
      wrote on last edited by
      #2

      @strixx - try to measure the voltage on A0 and see what you get.

      Controller: Proxmox VM - Home Assistant
      MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
      MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
      RFLink GW - Arduino Mega + RFLink Shield, 433mhz

      S 1 Reply Last reply
      0
      • sundberg84S sundberg84

        @strixx - try to measure the voltage on A0 and see what you get.

        S Offline
        S Offline
        Strixx
        wrote on last edited by
        #3

        @sundberg84 Short reply:
        Doesn't matter what the actual reading is.

        #define V_MIN 2.7  // 0% Battery voltage
        #define V_MAX 3.3  // 100% Battery voltage
        
          // read analog pin
          int sensorValue = analogRead(BATTERY_SENSE_PIN);
          // calculate battery voltage
          float vBat  = static_cast<float>(sensorValue * (V_MAX/1023));
          // calculate % left of defined interval
          int batteryPcnt = static_cast<int>(((vBat-V_MIN)/(V_MAX-V_MIN))*100.);
        

        In my head this code should never be able to set batteryPcnt higher than 100. Unless sensorValue can be greater than 1023.

        Long reply:
        Yesterday I was measuring the voltage with a multimeter and ended up recalculating the divider over and over again. With the same result over and over again. The voltage at the tap point was not the same as the math told me it should be.
        But then last night it hit me. The internal resistance in my multimeter is not high enough to give me an accurate reading with such high resistors in the divider. (I studied electronics 25 years ago. The knowledge is there but buried deep in my mind)

        In one of all these recalculations I came up with the code snippet in this reply. Simply to make shore that what ever reading you get you will never present a value over 100%.

        And as I wrote in the original post. The strange thing is that when the sensor is connected to the serial programmer the sensorValue never exceeds 1023, and therefore the batteryPcnt never exceeds 100. But as soon as i disconnect the serial programmer and put the sensor on battery power, it starts reporting reading of above 100% and all the way up to 300%.
        And it makes it every time. I have tried switching at least ten times with the same result every time.

        zboblamontZ 1 Reply Last reply
        0
        • S Strixx

          @sundberg84 Short reply:
          Doesn't matter what the actual reading is.

          #define V_MIN 2.7  // 0% Battery voltage
          #define V_MAX 3.3  // 100% Battery voltage
          
            // read analog pin
            int sensorValue = analogRead(BATTERY_SENSE_PIN);
            // calculate battery voltage
            float vBat  = static_cast<float>(sensorValue * (V_MAX/1023));
            // calculate % left of defined interval
            int batteryPcnt = static_cast<int>(((vBat-V_MIN)/(V_MAX-V_MIN))*100.);
          

          In my head this code should never be able to set batteryPcnt higher than 100. Unless sensorValue can be greater than 1023.

          Long reply:
          Yesterday I was measuring the voltage with a multimeter and ended up recalculating the divider over and over again. With the same result over and over again. The voltage at the tap point was not the same as the math told me it should be.
          But then last night it hit me. The internal resistance in my multimeter is not high enough to give me an accurate reading with such high resistors in the divider. (I studied electronics 25 years ago. The knowledge is there but buried deep in my mind)

          In one of all these recalculations I came up with the code snippet in this reply. Simply to make shore that what ever reading you get you will never present a value over 100%.

          And as I wrote in the original post. The strange thing is that when the sensor is connected to the serial programmer the sensorValue never exceeds 1023, and therefore the batteryPcnt never exceeds 100. But as soon as i disconnect the serial programmer and put the sensor on battery power, it starts reporting reading of above 100% and all the way up to 300%.
          And it makes it every time. I have tried switching at least ten times with the same result every time.

          zboblamontZ Offline
          zboblamontZ Offline
          zboblamont
          wrote on last edited by
          #4
          This post is deleted!
          1 Reply Last reply
          0
          • gohanG Offline
            gohanG Offline
            gohan
            Mod
            wrote on last edited by
            #5

            Do you have a capacitor on the A0 pin?

            1 Reply Last reply
            0
            • rozpruwaczR Offline
              rozpruwaczR Offline
              rozpruwacz
              wrote on last edited by
              #6

              what is the reference voltage of the ADC ? You will get negative batteryPcnt values for sensorValue lower than 837, what happens with the batteryPcnt values ? maybe thaey are treated somewhere as unsigned ? You say You use voltage divider but I don't see that your code is handling the voltage divider.

              1 Reply Last reply
              0
              • gohanG Offline
                gohanG Offline
                gohan
                Mod
                wrote on last edited by
                #7

                He is using internal reference

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Strixx
                  wrote on last edited by
                  #8

                  @zboblamont Yes. 3V Mini Pro
                  @gohan Yes. 0.1uF capacitor.
                  @rozpruwacz Internal reference 1.1V. Have a external divider exactly as the example schematics on the home page, to get maximal 1.1 V with two AA batteries.

                  As a first step I am trying to understand how the batteryPcnt can ever be higher than 100. With my code that should be impossible. Even if i put 5V on A0.

                  vBat should never be able to be higher than v_MAX
                  and therefore batteryPcnt should never be able to be higher than 100.

                  zboblamontZ 1 Reply Last reply
                  0
                  • S Strixx

                    @zboblamont Yes. 3V Mini Pro
                    @gohan Yes. 0.1uF capacitor.
                    @rozpruwacz Internal reference 1.1V. Have a external divider exactly as the example schematics on the home page, to get maximal 1.1 V with two AA batteries.

                    As a first step I am trying to understand how the batteryPcnt can ever be higher than 100. With my code that should be impossible. Even if i put 5V on A0.

                    vBat should never be able to be higher than v_MAX
                    and therefore batteryPcnt should never be able to be higher than 100.

                    zboblamontZ Offline
                    zboblamontZ Offline
                    zboblamont
                    wrote on last edited by
                    #9

                    @strixx What does your #ifdef MY_DEBUG sequence spit out?

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      Strixx
                      wrote on last edited by
                      #10

                      @zboblamont Nothing strange. sensorValues between 800 and 1023, and correct corresponding vBat and batteryPcnt according to my formulas. But that's when I have the serial programmer connected.
                      I don't know how to get the serial output from debug without having it connected.
                      The strange values only appear when on battery.

                      zboblamontZ 1 Reply Last reply
                      0
                      • S Strixx

                        @zboblamont Nothing strange. sensorValues between 800 and 1023, and correct corresponding vBat and batteryPcnt according to my formulas. But that's when I have the serial programmer connected.
                        I don't know how to get the serial output from debug without having it connected.
                        The strange values only appear when on battery.

                        zboblamontZ Offline
                        zboblamontZ Offline
                        zboblamont
                        wrote on last edited by
                        #11

                        @strixx I think you can disconnect power from the FTDI to the board and leave the battery connected, so long as gnd etc remain connected from FTDI...
                        Perhaps somebody can correct me if I'm wrong...

                        1 Reply Last reply
                        0
                        • gohanG Offline
                          gohanG Offline
                          gohan
                          Mod
                          wrote on last edited by
                          #12

                          yes, just unplug the vcc cable

                          1 Reply Last reply
                          1
                          • K Offline
                            K Offline
                            kimot
                            wrote on last edited by
                            #13

                            I always think about this battery percentage. Where it gives its limits.
                            Then I see some project - "NodeManager"
                            GitHub
                            And there was some functions :

                             // [11] the expected vcc when the batter is fully discharged, used to calculate the percentage (default: 2.7)
                                  void setBatteryMin(float value);
                                  // [12] the expected vcc when the batter is fully charged, used to calculate the percentage (default: 3.3)```
                            zboblamontZ 1 Reply Last reply
                            0
                            • gohanG Offline
                              gohanG Offline
                              gohan
                              Mod
                              wrote on last edited by
                              #14

                              as @sundberg84 made in his examples I do an average of the last 4 battery readings

                              1 Reply Last reply
                              0
                              • K kimot

                                I always think about this battery percentage. Where it gives its limits.
                                Then I see some project - "NodeManager"
                                GitHub
                                And there was some functions :

                                 // [11] the expected vcc when the batter is fully discharged, used to calculate the percentage (default: 2.7)
                                      void setBatteryMin(float value);
                                      // [12] the expected vcc when the batter is fully charged, used to calculate the percentage (default: 3.3)```
                                zboblamontZ Offline
                                zboblamontZ Offline
                                zboblamont
                                wrote on last edited by
                                #15

                                @kimot If there were a problem with the sketch it would equally apply when the ftdi is connected with the sensors connected.
                                I believe that is why @sundberg84 suggested measuring the voltage at A0... ;)

                                1 Reply Last reply
                                0
                                • S Offline
                                  S Offline
                                  Strixx
                                  wrote on last edited by
                                  #16

                                  @zboblamont
                                  The voltage at A0 is at steady 0,8V with batteries.
                                  Which should give sensor value 744.
                                  The voltage of the two batteries is 2,88V.

                                  But as I wrote earlier it must be so that my multimeters internal resistance is not high enough. And is messing up the divider when measuring.
                                  The calculated voltage at A0 should be 0,89V
                                  Which should give sensorValue 828

                                  My sensors right now is reporting 100% then 253% and now 236%.

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    Strixx
                                    wrote on last edited by
                                    #17

                                    @gohan Cant unplug the Vcc from FTDI. Not without cutting the pin on my Mini.
                                    And it will not help do average from 4 or even 10 readings. It will still show a messed up percentage. Non of the readings is below 100%

                                    1 Reply Last reply
                                    0
                                    • gohanG Offline
                                      gohanG Offline
                                      gohan
                                      Mod
                                      wrote on last edited by
                                      #18

                                      use jumper wires

                                      1 Reply Last reply
                                      2
                                      • S Offline
                                        S Offline
                                        Strixx
                                        wrote on last edited by
                                        #19

                                        @gohan Thinking outside the box... :joy: will do..

                                        1 Reply Last reply
                                        0
                                        • S Offline
                                          S Offline
                                          Strixx
                                          wrote on last edited by
                                          #20

                                          Ok. So connecting the node to serial interface, but without power from it. And power from same batteries.
                                          The calculations is correct and multimeter is not measuring correct.

                                          This is debug out put:
                                          First loop:

                                          Sensor value: 1023
                                          Battery Voltage: 3.30 V
                                          Battery percent: 100 %
                                          

                                          Second and the following loops:

                                          Sensor value: 877
                                          Battery Voltage: 2.83 V
                                          Battery percent: 21 %
                                          

                                          So back to square one. When serial output is connected it works perfect.
                                          When disconnected it starts reporting all messed up readings!

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          34

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular