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. Hardware
  3. Battery voltage calculation for 18650 batteries

Battery voltage calculation for 18650 batteries

Scheduled Pinned Locked Moved Hardware
2 Posts 2 Posters 1.4k Views 2 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.
  • solaS Offline
    solaS Offline
    sola
    wrote on last edited by sola
    #1

    I have built a Dallas Temperature sensor around a Pro Mini 8Mhz.

    I am powering it with two li-ion 18650 cells connected in series (~8.4V maximum voltage when fully charged, 5.4V minimum voltage before cutoff) and powering the Pro Mini via the RAW port.

    I would like to send the current battery voltage info to the controller. I connected the wiring according to the "Battery Powering" page (1Mohm + 470kohm resistors, the resistor join point also connected to A0). The +V is the RAW port of the arduino (where the battery + is connected)

    The sketch works but seems to report wrong voltages.

    When there is no actual voltage (battery disconnected and arduino powered by the serial programmer), it reports 0.17V.
    When the battery is connected, it should report ~8V (SOC on the li-ion pack) but it reports 3.44V.

    Maybe the example sketch was specifically created for two AA batteries in series?

    My node sketch:

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    #define MY_NODE_ID 78
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    // Define sensor node childs
    #define CHILD_ID_BATT 1
    #define CHILD_ID_TEMP 0
    
    
    #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 7 // Pin where dallase sensor is connected 
    
    
    #define MAX_ATTACHED_DS18B20 16
    unsigned long SLEEP_TIME = 1000; // Sleep time between reads (in milliseconds)
    
    // Battery related init
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    float oldBatteryV = 0;
    MyMessage msgBatt(CHILD_ID_BATT, V_VOLTAGE);
    
    
    // Dallas Temperature related init
    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;
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
    
      // needed for battery soc
      // use the 1.1 V internal reference
      #if defined(__AVR_ATmega2560__)
          analogReference(INTERNAL1V1);
      #else
          analogReference(INTERNAL);
      #endif
    
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Temperature Sensor", "1.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()     
    {     
    
      // get the battery Voltage
      int battSensorValue = analogRead(BATTERY_SENSE_PIN);
      Serial.println(battSensorValue);
      float batteryV  = battSensorValue * 0.003363075;
      Serial.print("Battery Voltage: ");
      Serial.print(batteryV);
      Serial.println(" V");
    //  if (oldBatteryV != batteryV) {
        // Power up radio after sleep
        send(msgBatt.set(batteryV, 2));
        oldBatteryV = batteryV;
    //  }  
    
      // 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(msgTemp.setSensor(i).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
      sleep(SLEEP_TIME);
    }
    

    Any help is appreciated.

    mfalkviddM 1 Reply Last reply
    0
    • solaS sola

      I have built a Dallas Temperature sensor around a Pro Mini 8Mhz.

      I am powering it with two li-ion 18650 cells connected in series (~8.4V maximum voltage when fully charged, 5.4V minimum voltage before cutoff) and powering the Pro Mini via the RAW port.

      I would like to send the current battery voltage info to the controller. I connected the wiring according to the "Battery Powering" page (1Mohm + 470kohm resistors, the resistor join point also connected to A0). The +V is the RAW port of the arduino (where the battery + is connected)

      The sketch works but seems to report wrong voltages.

      When there is no actual voltage (battery disconnected and arduino powered by the serial programmer), it reports 0.17V.
      When the battery is connected, it should report ~8V (SOC on the li-ion pack) but it reports 3.44V.

      Maybe the example sketch was specifically created for two AA batteries in series?

      My node sketch:

      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      #define MY_NODE_ID 78
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      #include <SPI.h>
      #include <MySensors.h>  
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      // Define sensor node childs
      #define CHILD_ID_BATT 1
      #define CHILD_ID_TEMP 0
      
      
      #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
      
      #define ONE_WIRE_BUS 7 // Pin where dallase sensor is connected 
      
      
      #define MAX_ATTACHED_DS18B20 16
      unsigned long SLEEP_TIME = 1000; // Sleep time between reads (in milliseconds)
      
      // Battery related init
      int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
      float oldBatteryV = 0;
      MyMessage msgBatt(CHILD_ID_BATT, V_VOLTAGE);
      
      
      // Dallas Temperature related init
      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;
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      
      
      
      void before()
      {
        // Startup up the OneWire library
        sensors.begin();
      }
      
      void setup()  
      { 
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      
      
        // needed for battery soc
        // use the 1.1 V internal reference
        #if defined(__AVR_ATmega2560__)
            analogReference(INTERNAL1V1);
        #else
            analogReference(INTERNAL);
        #endif
      
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Temperature Sensor", "1.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()     
      {     
      
        // get the battery Voltage
        int battSensorValue = analogRead(BATTERY_SENSE_PIN);
        Serial.println(battSensorValue);
        float batteryV  = battSensorValue * 0.003363075;
        Serial.print("Battery Voltage: ");
        Serial.print(batteryV);
        Serial.println(" V");
      //  if (oldBatteryV != batteryV) {
          // Power up radio after sleep
          send(msgBatt.set(batteryV, 2));
          oldBatteryV = batteryV;
      //  }  
      
        // 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(msgTemp.setSensor(i).set(temperature,1));
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
          }
        }
        sleep(SLEEP_TIME);
      }
      

      Any help is appreciated.

      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #2

      @sola yes, you are correct that the calculation is form2xAA. See the comment inside loop() on the example at https://www.mysensors.org/build/battery for the required calculation, and this part for the voltage divider:

      The ADC is set to use the internal reference value of 1.1V - so Vmax at ADCmax = 1.1*(16+4703)/4703 = 3.44V

      You'll need to change the resistors in the voltage divider to handle voltages as high as 8V.

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


      23

      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