reporting battery to domoticZ



  • Re: Reporting Battery Level

    Hello, i'm using the sketch given here https://www.mysensors.org/build/battery without modification to report battery level to domoticZ. obviously i can't use the Vcc library because the voltage i'm monitoring is the battery voltage, while the arduino is fed through the step up regulator at a stable 3.3V.
    I 'm not sure to understand then why domoticz shows 60% battery when my battery level is actually at about 3V so i would expect 3/3.44 = 87% .

    So i'm suspecting that sendBatteryLevel(batteryPcnt); does not actually send batteryPcnt as computed in the sketch but a rescaled percentage in order to match 0% when the battery will be at about 2.7V .... can someone confirm ? where can i read the actual void sendBatteryLevel() to understand what it is doing exactly ?


  • Hardware Contributor

    @fhenryco said in reporting battery to domoticZ:

    where can i read the actual void sendBatteryLevel() to understand what it is doing exactly ?

    Domoticz: https://github.com/domoticz/domoticz/blob/3741a530c2260cea2f337a095aa9477847fc00cb/hardware/MySensorsBase.cpp#L444
    MySensors: https://github.com/mysensors/MySensors/blob/9041c8ba3d896484b6d9dca6e8ff5e81a828ffa3/core/MySensorsCore.cpp#L308

    Maybe you can show us your sketch code? I have this working with Domoticz just fine.



  • @sundberg84 thank you but as i said i did no modification to the sketch in https://www.mysensors.org/build/battery appart merging it with a DHT11 sketch. However i did notice something strange: when i switch on the arduino (sensor side) the first percentage i get in DomoticZ was 102%, then at the next update it fell to 60% and has not changed since then. I'm suspecting there is something wrong measuring the battery level from A0 pin just after sending a temperature value ??

    Insert Code Here/**
     * 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: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
     
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 600000;
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    int oldBatteryPcnt = 0;
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("TemperatureAndHumidity", "1.1");
      sendSketchInfo("Battery Meter", "1.0");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      
      metric = getConfig().isMetric;
    }
    
    
    void setup()
    {
      
       // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
        analogReference(INTERNAL1V1);
    #else
        analogReference(INTERNAL);
    #endif
    
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      sleep(dht.getMinimumSamplingPeriod());
    }
    
    
    void loop()      
    {  
      // get the battery Voltage
        int sensorValue = analogRead(BATTERY_SENSE_PIN);
    #ifdef MY_DEBUG
        Serial.println(sensorValue);
    #endif
    
        // 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 batteryPcnt = sensorValue / 10;
    #ifdef MY_DEBUG
        float batteryV  = sensorValue * 0.003363075;
        Serial.print("Battery Voltage: ");
        Serial.print(batteryV);
        Serial.println(" V");
    
        Serial.print("Battery percent: ");
        Serial.print(batteryPcnt);
        Serial.println(" %");
    #endif
    
        if (oldBatteryPcnt != batteryPcnt) {
            // Power up radio after sleep
            sendBatteryLevel(batteryPcnt);
            oldBatteryPcnt = batteryPcnt;
        }
    
    
        
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
      
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
        
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL); 
    }
    

  • Hardware Contributor

    @fhenryco - if you are experience changes it might help adding a wait(); or delay(); to get a more stable reading. If something is using power just as you read it might be strange values.

    This is one of my sketches (DHT + Bat): https://github.com/sundberg84/MySensors2.0.0/blob/master/NorrHumAs/NorrHumAs.ino and im using the voltage divider to A0 to measure the battery.



  • @sundberg84 thanks,
    the delay 500 has a big effect , now i get 116% hence a battery voltage=3.5V, while the multimeter gives it 3V ! may be the internal reference is not 1.1V in my low cost chinese pro mini 3.3v .
    BTW i did not understand why you have also a delay 500 after reading the analog pin, i would have thought that a delay before reading the analog pin is sufficient ... (?)


  • Hardware Contributor

    @fhenryco - could be the delay before is sufficient.



  • this morning , i get 102% , much closer to the actual value ... assuming that the ADC activity did not discharge my battery at an unprecedented level (i had this sketch working for two monthes with very little discharge of the battery before adding this battery monitoring functionality). I will know for sure if the battery level does not drop further in the coming days...i'm concerned that the delay 500 might produce non negligible battery consumption


  • Hardware Contributor

    @fhenryco Its hard to reach a 100% correct value on the chinese clones. I get a 5% off probably all the time. Because of that I have added an average so I collect three values every 20min into an array and send the average every hour.



  • ok, thanks again, something else i v been wondering about is why domoticz will show the temp + humidity sensor as a single sensor even though there are separate instructions
    for the presentation :
    present(CHILD_ID_HUM, S_HUM);
    present(CHILD_ID_TEMP, S_TEMP);
    and for the messages themselves
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    send(msgTemp.set(temperature, 1));
    send(msgHum.set(humidity, 1));
    what should be modified if i want domoticZ to treat the two sensors separately ? (this is for Yana, a speech recognition software that has a plugin for domoticZ, but apparantly is not able to handle several values for a given sensor).

    is it the sendSketchInfo("TemperatureAndHumidity", "1.1"); that needs to be replaced by two sendSketchInfo, one for temp and one for humidity ?



  • @fhenryco apparantly something like send(msgTemp.setSensor(CHILD_ID_TEMP).set(temperature,1));
    send(msgHum.setSensor(CHILD_ID_HUM).set(humidity,1));
    should do the job ! going to try that
    but i'm surprised this is not done by default since msgHum and msgTemp are defined separately for each sensor Id



  • @fhenryco it did nothing different ... still have a single sensor temp+hum don't understand why ...


  • Hardware Contributor

    @fhenryco - Yes, and there is a trick to seperate them... and i if I remembe right @AWI is the one to ask.

    Edit, found his post here: https://forum.mysensors.org/topic/5132/ds18b20-ans-sht31-d-show-up-as-combined-sensors-on-domoticz/13



  • using V_text and S_info is a workaround to avoid grouping



  • i would like to ask something to ,

    Now i have the battery level showing up in Domoticz what can i do to log the voltage in volts, should i add something inside the sketch or something in domoticz..



  • @Rene046
    This is the instruction in your sketch which allows to see the battery level of devices in domoticZ
    sendBatteryLevel(batteryPcnt);
    But as you noticed , this is not reported in the logs. One possibility to see it in the Log is to as well send this batteryPcnt information with a send(msgbatt.set(batteryPcnt ,1);
    provided you have defined
    MyMessage msgbatt(CHILD_ID_BATT, V_TEXT);

    In other words you send the battery info as if it was the info of an additional sensor sending text type info
    which you also need to present in the presentation void with

    present(CHILD_ID_BATT, S_INFO);
    For instance if you already have two sensors in you sketch let's say temp and hum with ID =0 and 1 respectively you would give the battery level the next unused ID
    CHILD_ID_BATT=2
    There might be a simpler and more natural way but i don't know it .


  • Hero Member

    @Rene046 The "royal" way to report battery level is to define it as S_MULTIMETER and use it to report voltage. Domoticz will take the voltage and can graph it. i.e.

    definitions: MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE);
    in presentation: present(VOLTAGE_CHILD_ID, S_MULTIMETER, "Battery level" );
    sending: send(voltageMsg.set(lastVoltage,2)); //send battery in Volt 2 decimal places



  • @ fhenryco

    Cant get it to work, if you have time could help with my sketch.

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <DHT.h>   
    
    
    
    // Enable debug prints
    #define MY_DEBUG
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define HUMIDITY_SENSOR_DIGITAL_PIN 3
    #define CHILD_ID_BATTERY 4
    unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
    
    #define SKETCH_NAME "Temp_Hum_Batt"        // Change to a fancy name you like
    #define SKETCH_VERSION "2.1"                    // Your version
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgbatt(CHILD_ID_BATTERY, V_VOLTAGE);
    //MyMessage msgbatt(CHILD_ID_BATTERY, V_TEXT);
    
    //=========================
    // BATTERY VOLTAGE DIVIDER SETUP
    // 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
    #define VBAT_PER_BITS 0.0041055718475073313782991202346  
    #define VMIN 3.6                                  //  Vmin (radio Min Volt)=1.9V (564v)
    #define VMAX 4.2                                  //  Vmax = (2xAA bat)=3.0V (892v)
    int batteryPcnt = 0;                              // Calc value for battery %
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[3];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    
    void setup()  
    { 
     analogReference(INTERNAL);             // For battery sensing
    
      delay(500); // Allow time for radio if power used as reset
      
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
      metric = getControllerConfig().isMetric;
    }
    
    void presentation()  
    { 
      // Send the Sketch Version Information to the Gateway
     // Send the Sketch Version Information to the Gateway
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register all sensors to gw (they will be created as child devices)
      
      
      present(CHILD_ID_BATTERY, S_INFO);
      //present(CHILD_ID_BATTERY, S_CUSTOM);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    }
    
    void loop()      
    {  
      delay(500); // Allow time for radio if power used as reset
      delay(dht.getMinimumSamplingPeriod());
     
      // Fetch temperatures from DHT sensor
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      // Fetch humidity from DHT sensor
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
      batM();
      sleep(SLEEP_TIME); //sleep a bit
    }
    
    void batM() //The battery calculations
    {
       delay(500);
       // Battery monitoring reading
       int sensorValue = analogRead(BATTERY_SENSE_PIN);    
       delay(500);
       
       // Calculate the battery in %
       float Vbat  = sensorValue * VBAT_PER_BITS;
       int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
       Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
       
       // Add it to array so we get an average of 3 (3x20min)
       batArray[batLoop] = batteryPcnt;
      
       if (batLoop > 2) {  
         batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
         batteryPcnt = batteryPcnt / 3;
     
       if (batteryPcnt > 100) {
         batteryPcnt=100;
     }
     
         Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
           sendBatteryLevel(batteryPcnt);
           msgbatt.set(batteryPcnt ,1);
           batLoop = 0;
          }
         else 
         {
         batLoop++;
         }
    }```
    
    My sketch is not working 100% my voltage is not precise, giving me even 221 in percentage while  lipo is at this moment 3.7 volt (simulated with a variable power supply)
    
    im running it on a nano on 1 lipo cell and a dc dc powerup to 5 volt measuring the lipo voltage with a  divider 1M/470K
    .
    Hope to add a soil moisture sensor and baro sensor in future.
    
    p.s. any one with some better idea sketch its ver welcome. im just started to experiment with Mysensor


  • O i forget to tell im running the latest gateway from Mysensor.



  • @Rene046
    not
    msgbatt.set(batteryPcnt ,1);
    but
    send(msgbatt.set(batteryPcnt ,1));

    also may be better to use S_MULTIMETER and V_VOLTAGE (rather than S_INFO and V_TEXT) as adviced by AWI and also 2 decimals hence
    send(msgbatt.set(batteryPcnt ,2));



  • thx i got a voltage log only giving me now -44.000 volt and 212 prct at battery level while measuring 3.7 volt battery and voltage on A0 1.3 volts
    .

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <DHT.h>   
    
    // Enable debug prints
    #define MY_DEBUG
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define HUMIDITY_SENSOR_DIGITAL_PIN 3
    #define CHILD_ID_BATTERY 4
    unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
    
    #define SKETCH_NAME "Temp_Hum_Batt"        // Change to a fancy name you like
    #define SKETCH_VERSION "2.1"                    // Your version
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgbatt(CHILD_ID_BATTERY, V_VOLTAGE);
    
    //=========================
    // BATTERY VOLTAGE DIVIDER SETUP
    // 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
    #define VBAT_PER_BITS 0.0041055718475073313782991202346  // 4.20/1023 volt
    #define VMIN 3.6                                  //  Vmin = 3.6 lipo empty
    #define VMAX 4.2                                  //  Vmax = 4.2 volt lipo full
    int batteryPcnt = 0;                              // Calc value for battery %
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[3];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    
    void setup()  
    { 
     analogReference(INTERNAL);             // For battery sensing
    
      delay(500); // Allow time for radio if power used as reset
      
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
      metric = getControllerConfig().isMetric;
    }
    
    void presentation()  
    { 
      // Send the Sketch Version Information to the Gateway
     // Send the Sketch Version Information to the Gateway
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register all sensors to gw (they will be created as child devices)
      
      
      present(CHILD_ID_BATTERY, S_MULTIMETER);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    }
    
    void loop()      
    {  
      delay(500); // Allow time for radio if power used as reset
      delay(dht.getMinimumSamplingPeriod());
     
      // Fetch temperatures from DHT sensor
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      // Fetch humidity from DHT sensor
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
      batM();
      sleep(SLEEP_TIME); //sleep a bit
    }
    
    void batM() //The battery calculations
    {
       delay(500);
       // Battery monitoring reading
       int sensorValue = analogRead(BATTERY_SENSE_PIN);    
       delay(500);
       
       // Calculate the battery in %
       float Vbat  = sensorValue * VBAT_PER_BITS;
       int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
       Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
       
       // Add it to array so we get an average of 3 (3x20min)
       batArray[batLoop] = batteryPcnt;
      
       if (batLoop > 2) {  
         batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
         batteryPcnt = batteryPcnt / 3;
     
       if (batteryPcnt > 100) {
         batteryPcnt=100;
     }
     
         Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
           sendBatteryLevel(batteryPcnt);
           send(msgbatt.set(batteryPcnt ,2));
           batLoop = 0;
          }
         else 
         {
         batLoop++;
         }
    }```


  • And my serial monitor is going wild .lol
    .

    41815 MCO:SLP:WUP=-1
    Battery percent: 95 %
    Battery Average (Send): -12 %
    45359 !TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=NACK:244
    45403 !TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=1,st=NACK:-12.00
    45410 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    45415 MCO:SLP:TPD
    45417 MCO:SLP:WUP=-1
    47962 !TSF:MSG:SEND,2-2-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=2,st=NACK:20.0
    T: 20.00
    48007 !TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=3,st=NACK:49.6
    H: 49.60
    Battery percent: -49 %
    49014 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    49020 MCO:SLP:TPD
    49022 MCO:SLP:WUP=-1
    51567 !TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=4,st=NACK:49.2
    H: 49.20
    Battery percent: -26 %
    52575 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    52582 MCO:SLP:TPD
    


  • And it seems like instead of real voltage i seen percentage in the log


  • Hero Member

    @Rene046 if you send V_VOLTAGE you should use the voltage level not the percentage.



  • @AWI

    hi could you explain how..



  • I still cant get it to work, No voltage reading or logging.
    I there nobody trying to build a equal sensor.

    maybe someone who could rework my sketch. or having a working sketch where i could delete some sensors from.

    kind regards and greetings from the Netherlands.


  • Hero Member

    @Rene046 I would be happy to help you but need some information on your circuit:

    • How are you powering your Arduino? Through an (onboard) regulator or directly from battery?
    • The internal reference can only be used up to 1.1V, you seem to be having a voltage divider which has a resulting voltage of > 1.1 V ?
    • I do not understand your averaging algorithm, why are you not taking an average of the latest x readings?

    My suggestion would be to use a different external reference (output of the dc-dc boost converter/ Vcc?) to measure the voltage.



  • Hi Awi

    Thanks that you want to help,
    Im powering it by a lipo battery 1 cell using an dc-dc boost converter to get 5 volts
    i would like to see what this lipo is doing during a day. this lipo will be charged by an solar panel 6 volt 300ma still waiting for that panel.

    You are absolutely right with my voltage divider it's at 1.9 volt while lipo is at 4.2 volt
    I'm not a hero in elektronics , just starting to play with it. so to start i should make an voltage divider that gives me aprox 1,1 volt max at 4,2 volt.
    I changed the voltages divider now from 270k-100k
    giving me 1.07 volt at 4.2 volt lipo

    i'm totally open for any other design you could give, i just used some code from others that was excepted by demoticz.

    If you like you could send me an sample how you would do it or change my sketch ..
    today i also received my BMP180 and BH1750 i want to include in the future..



  • my serial monitor is now making a bit more cense voltage is about 0,10 volt off
    but maybe i do something wrong with calculation.
    percentage is still something wrong with

    by the way i'm not shure with the low voltage of an 16850 lipo at 3.6 volt ...

    20412 MCO:SLP:WUP=-1
    22921 TSF:MSG:SEND,2-2-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:17.8
    T: 17.80
    22929 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=OK:35.4
    H: 35.40
    23939 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.53
    Battery voltage: 3.53 V
    Battery percent: -10 %
    23946 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    23954 MCO:SLP:TPD
    23955 MCO:SLP:WUP=-1
    26465 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=OK:36.1
    H: 36.10
    27473 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.52
    Battery voltage: 3.52 V
    Battery percent: -12 %
    27481 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    27489 MCO:SLP:TPD
    

    and here the latest sketch

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <DHT.h>   
    
    // Enable debug prints
    #define MY_DEBUG
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define HUMIDITY_SENSOR_DIGITAL_PIN 3
    #define CHILD_ID_BATTERY 4
    unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
    
    #define SKETCH_NAME "Temp_Hum_Batt"        // Change to a fancy name you like
    #define SKETCH_VERSION "2.1"                    // Your version
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgbatt(CHILD_ID_BATTERY, V_VOLTAGE);
    
    //=========================
    // BATTERY VOLTAGE DIVIDER SETUP
    // 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
    #define VBAT_PER_BITS 0.0041055718475073313782991202346  // 4.20/1023 volt
    #define VMIN 3.6                                  //  Vmin = 3.6 lipo empty
    #define VMAX 4.2                                  //  Vmax = 4.2 volt lipo full
    int batteryPcnt = 0;                              // Calc value for battery %
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[3];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    
    void setup()  
    { 
     analogReference(INTERNAL);             // For battery sensing
    
      delay(500); // Allow time for radio if power used as reset
      
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
      metric = getControllerConfig().isMetric;
    }
    
    void presentation()  
    { 
      // Send the Sketch Version Information to the Gateway
     // Send the Sketch Version Information to the Gateway
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register all sensors to gw (they will be created as child devices)
      
      
      present(CHILD_ID_BATTERY, S_MULTIMETER);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    }
    
    void loop()      
    {  
      delay(500); // Allow time for radio if power used as reset
      delay(dht.getMinimumSamplingPeriod());
     
      // Fetch temperatures from DHT sensor
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      // Fetch humidity from DHT sensor
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
      batM();
      sleep(SLEEP_TIME); //sleep a bit
    }
    
    void batM() //The battery calculations
    {
       delay(500);
       // Battery monitoring reading
       int sensorValue = analogRead(BATTERY_SENSE_PIN);    
       delay(500);
       
       // Calculate the battery in %
       float Vbat  = sensorValue * VBAT_PER_BITS;
       send(msgbatt.set(Vbat ,2));
       Serial.print("Battery voltage: "); Serial.print(Vbat); Serial.println(" V");  
       int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
       Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
       
       // Add it to array so we get an average of 3 (3x20min)
       batArray[batLoop] = batteryPcnt;
      
       if (batLoop > 2) {  
         batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
         batteryPcnt = batteryPcnt / 3;
     
       if (batteryPcnt > 100) {
         batteryPcnt=100;
     }
     
         Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
           sendBatteryLevel(batteryPcnt);
           
           batLoop = 0;
          }
         else 
         {
         batLoop++;
         }
    }
    


  • @Rene046 said in reporting battery to domoticZ:

    my serial monitor is now making a bit more cense voltage is about 0,10 volt off
    but maybe i do something wrong with calculation.
    percentage is still something wrong with

    im feeding with 3.60 volts at that moment.


  • Hero Member

    @Rene046 The 1.1V internal reference is not calibrated and can be 10% off, So you need to do some calibration yourself.
    (b.t.w. I cleaned your postings a little. Please make sure you use the code markings in the right way, i.e. put them on a new line). To get you going I rewrote the battery routine. Changes:

    • no real need to average the readings if you give it time to stabilize.
    • got rid of the "volt per bit" constant
    • added a "reference value:" for calibration, you can calculate it from the measured voltage and reported voltage.
    // battery calculations
    void batM(){
    	const float vRef = 4.2/ 1.1 ;							// actual value for max reading, adjust with help of measured voltage
    	delay(500);
    	// Battery monitoring reading
    	int sensorValue = analogRead(BATTERY_SENSE_PIN);   		// sensorValue is 0..1023 where 1023 == vRef
    	float vBat = sensorValue * vRef / 1024 ;
    	send(msgbatt.set(vBat ,2));
    	Serial.print("Battery voltage: "); Serial.print(vBat); Serial.println(" V");  
    	// Calculate the battery in %
    	int batteryPcnt = static_cast<int>(((vBat-VMIN)/(VMAX-VMIN))*100.);
    	sendBatteryLevel( batteryPcnt) ;
    	Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");
    }
    


  • Thanks that looks way better.
    I just changed
    const float vRef = 4.2/ 1.1 ;
    into
    const float vRef = 4.2/ 1.07 ;
    because this is what i measure with my multimeter with 4.2 volt battery and measuring my voltage divider i have 1.07 volt
    .
    Giving me strange results something must be bad ..... my multimeter ?? it should be closer to 4.2 ? i guess

    Battery voltage: 3.92 V
    14842 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:53
    Battery percent: 53 %
    14850 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    14856 MCO:SLP:TPD
    14858 MCO:SLP:WUP=-1
    17367 TSF:MSG:SEND,2-2-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:19.4
    T: 19.40
    17376 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=OK:48.5
    H: 48.50
    17885 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.92
    Battery voltage: 3.92 V
    17893 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:53
    Battery percent: 53 %
    17900 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    17906 MCO:SLP:TPD```

  • Hero Member

    @Rene046 You should still compensate for the 1.1 offset. What you should do is calculate the vRef from the measured battery voltage and the real voltage.



  • @Rene046 what resistors do you use to measure battery. VBAT_PER_BITS is not just 4.2/1023. Personally I am using 1m and 300k it gives me up to 4.77V



  • @Arnold-Šlepetis

    Hi im using at this moment what i had.
    270k-100k giving me 1.07 volt at 4.2 battery

    So i stay save , but ok reading is not giving my wanted 4.2 volt but around 3.92 volt

    My nano is feeded by an dc -dc boost converter giving me 5 volt from this 4.2 battery.

    @AWI
    Sorry im still a noob in this, just understood how to make a voltage diver using 3:1 divider
    .
    Could you please give me a simple example how do this calculation.



  • @Rene046
    As I understand correct VBAT_PER_BITS is not just 4.2/1032. This depends what resistors do you use. If you use 1m and 470k VBAT_PER_BITS=0.003363075 made from formula and it will never reads more 3.44v.
    #define VMIN and #define VMAX 4.2 used only for formula int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
    If you use 270k and 100k maximum is 4.07V so will be VBAT_PER_BITS=0.0039784946236559 and not like in your sketch 0.0041055718475073313782991202346


  • Hero Member

    @Rene046 You making it complex. The steps)

    • Make sure that the input voltage is within the range of the reference. You did that with the voltage divider (max 1.07 V) 👍
    • set vRefin the sketch to an expected value (4.2 / 1 , where 1 is the calibration value). You did (4.2/1.07) 👍
    • Now you need to calibrate in the software:
    1. Measure the battery voltage (batteryVoltage) (not the voltage divider) with the multimeter. You did (4.2 Volt) 👍
    2. Look at the voltage level reported by the sketch (reportedVoltage). You did (3.92 Volt) 👍
    3. Calculate the calibration value and adjust vRef. It needs to report 4.2V now it reports 3.92V so you are off by 1.07. => (4.2/1.07) * 1.07 = 4.2 => set vRef to (4.2/ 1.0) and you will be fine.

    There are a few reasons why you need to calibrate:

    • The internal reference of the Arduino (1.1V) is not calibrated (can roughly vary from 1V to 1.2V)
    • Your voltage divider is not always precise.
    • Most multimeters are far more accurate...

  • Hero Member

    @Arnold-Šlepetis Purist physics 😉 : Although you calculation is probably correct for your use case. I associate a VBAT_PER_BITS=0.0039784946236559 with almost atomic precision. As where the internal (band-gap) reference has +- 10% offset and drift with temperature and Vcc (although it is pretty stable for MySensors purposes).
    0_1488182473299_upload-573a5ed3-04bf-44df-a0d5-a4b78bb505c5



  • What can i do to get a more stable reading now the voltage goes from 3.80 to 4.20 while feeding with an 4.20 volt



  • @Rene046 said in reporting battery to domoticZ:

    What can i do to get a more stable reading now the voltage goes from 3.80 to 4.20 while feeding with an 4.20 volt

    It seems like when the nano starts reading the voltage drops a bid.


  • Hero Member

    @Rene046 Can you be a little more specific? i.e. post a log of voltage readings over time.



  • vref: 4.20 V
    sensorValue: 949 bit
    219143 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.89
    Battery voltage: 3.89 V
    219151 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:48
    Battery percent: 48 %
    219158 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    219164 MCO:SLP:TPD
    219166 MCO:SLP:WUP=-1
    221699 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=OK:35.2
    H: 35.20
    vref: 4.20 V
    sensorValue: 951 bit
    222708 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.90
    Battery voltage: 3.90 V
    222717 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:50
    Battery percent: 50 %
    222724 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    222731 MCO:SLP:TPD
    222733 MCO:SLP:WUP=-1
    225242 TSF:MSG:SEND,2-2-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:20.6
    T: 20.60
    225251 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=OK:34.5
    H: 34.50
    vref: 4.20 V
    sensorValue: 955 bit
    226260 TSF:MSG:SEND,2-2-0-0,s=4,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:3.92
    Battery voltage: 3.92 V
    226269 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:52
    Battery percent: 52 %
    226276 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255
    226282 MCO:SLP:TPD
    

  • Hero Member

    @Rene046 From your earlier postings I can see that you are using a boost converter. Speaking in general these things make a lot of noise on the power line and are certainly not a stable supply.
    Just a few considerations:

    • A nano is not well suited for battery operation. These tend to dissipate at minimum 5mA and will drown a one cell battery fast. Go for a 3.3V pro-mini and remove the led.
    • Get rid of the Boost converter and power directly from the battery. The radio and pro-mini will work fine on 3.6V using a regulator (LDO). In this case you can measure battery directly from the Vcc pin without divider.


  • Last reading from multimeter battery voltage 4.204 volt now i measure A0 1,104 > gnd


  • Hero Member

    @Rene046 What is the output of the DC=DC converter measuring? Are you powering the nano on the Vcc or Vin pin?



  • Hi Awi i will build someday if i got it working this project on a pro-mini,.
    im not measuring the voltage on the dc-dc booster but on the battery side feeding the converter.
    I need this booster because i also feeding my DHT with 5 volt and in future other sensors.BH1750, BMP180, Soil moisture sensor
    and im charging my battery in the future with an 6 volt solar panel.
    So to see this is working during day time i should be able to read the charging voltage of 4.2 volt and during the night the voltage of battery dropping



  • @AWI

    Im feeding the 5v pin with 5.14 volt coming from the dc-dc output not the vin


  • Hero Member

    @Rene046 A 3.6-4.2 V battery with 3.3V ldo is perfectly suited to power the sensors you mentioned . I would replace the DHT22 with a (much better) I2C sensor (si7021/ BME280 /... ).

    If the measured voltage is not stable then in most cases the power supply or the measured voltage is unstable.


Log in to reply
 

Suggested Topics

  • 3
  • 6
  • 2
  • 6
  • 8

7
Online

11.4k
Users

11.1k
Topics

112.7k
Posts