About battery level



  • Hello,
    I have a question regarding the battery level
    If I have any sensor how could I show the battery level? Do I need extra code inside my .ino sketch or should I adjust something in the settings of the mycontroller panel
    I am using the mysensors nodes and gateway

    Thanks


  • ADMIN

    @bmanos you should send it from your node. refer this code



  • Thanks
    I already see this in my yesterday searches but when I try to Include to existing node code I cannot have both of values for example in my moisture sensor the value never change, Obviously I have somewhere an error in my code but I don't know where
    I will try again today and If I cannot do anything I will ask for your help again
    Thanks



  • In case you can post your sensor code here I can have a look at it. Normally you just use sendBatteryLevel(batteryPcnt); in your sketch and it will be send (I think) with sensor ID 255 to the controller



  • @Anduril Thanks for helping me on this

    get a look at the following pleas

    This is the code without the battery

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #define CHILD_ID 0
    #include <MySensors.h>
    
    // Here we are setting up some water thresholds that we will
    // use later. Note that you will need to change these to match
    // your soil type and environment. It doesn't do much for me because I'm using domoticz
    int thresholdUp = 400;
    int thresholdDown = 075;
    
    MyMessage msg(CHILD_ID, V_LEVEL);
    unsigned long SLEEP_TIME = 30000;
    
    // We are setting up the pin A0 on the redboard to be our sensor
    // pin input:
    int sensorPin = A0;
    
    const int buzzer = 8; //buzzer to arduino pin 8
    
    void setup(){
      pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output
    }
    
    void presentation()
    {
    sendSketchInfo("Soil Moisture Sensor", "1.0");
    present(CHILD_ID, S_MOISTURE);
    }
    
    void loop()
    {
    int sensorValue;
    sensorValue = analogRead(sensorPin);
    //send back the values
    send(msg.set(sensorValue));
    if (sensorValue <= 800){
      tone(buzzer, 2000); 
      delay(1000);        
      noTone(buzzer);     
      delay(500);        
      Serial.println(sensorValue);
    }
    else{
      Serial.println(sensorValue);
      }
    // delay until next measurement (msec)
    
    sleep(SLEEP_TIME);
    
    }
    

    This is the code with battery code that seems to work ( I am waiting for the battery to run out to see if the values shown are correct)

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #define CHILD_ID 0
    #include <MySensors.h>
    
    // Here we are setting up some water thresholds that we will
    // use later. Note that you will need to change these to match
    // your soil type and environment. It doesn't do much for me because I'm using domoticz
    int thresholdUp = 400;
    int thresholdDown = 075;
    
    MyMessage msg(CHILD_ID, V_LEVEL);
    unsigned long SLEEP_TIME = 30000;
    //unsigned long SLEEP_TIME = 900000;  //15 minutes
    
    // We are setting up the pin A0 on the redboard to be our sensor
    // pin input:
    int sensorPin = A0;
    
    const int buzzer = 8; //buzzer to arduino pin 8
    
    void setup(){
      pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output
    }
    
    void presentation()
    {
    sendSketchInfo("Soil Moisture Sensor", "1.0");
    present(CHILD_ID, S_MOISTURE);
    }
    
    void loop()
    {
    int sensorValue;
    sensorValue = analogRead(sensorPin);
    //send back the values
    send(msg.set(sensorValue));
    if (sensorValue <= 800){
      tone(buzzer, 2000);
      delay(1000);       
      noTone(buzzer);    
      delay(1000);       
      Serial.println(sensorValue);
    }
    else{
      Serial.println(sensorValue);
      }
    // delay until next measurement (msec)
    
      #define MIN_V 2700
      #define MAX_V 4100
      int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage
      sendBatteryLevel(batteryPcnt); // Send battery percentage to gateway
    
    sleep(SLEEP_TIME);
    
    }
    
      long readVcc() {
        // Read 1.1V reference against AVcc
        // set the reference to Vcc and the measurement to the internal 1.1V reference
        #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
          ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
          ADMUX = _BV(MUX5) | _BV(MUX0);
        #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
          ADMUX = _BV(MUX3) | _BV(MUX2);
        #else
          ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        #endif  
       
        delay(2); // Wait for Vref to settle
        ADCSRA |= _BV(ADSC); // Start conversion
        while (bit_is_set(ADCSRA,ADSC)); // measuring
       
        uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
        uint8_t high = ADCH; // unlocks both
       
        long result = (high<<8) | low;
       
        result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
        return result; // Vcc in millivolts
      }
    

    And this is the code with the battery from mysensors that is not working as I don't t get values from the soil moisture sensor and I am not sure that the battery level is working

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #define CHILD_ID 0
    #include <MySensors.h>
    
    // Here we are setting up some water thresholds that we will
    // use later. Note that you will need to change these to match
    // your soil type and environment. It doesn't do much for me because I'm using domoticz
    int thresholdUp = 400;
    int thresholdDown = 075;
    
    MyMessage msg(CHILD_ID, V_LEVEL);
    unsigned long SLEEP_TIME = 30000;
    
    // We are setting up the pin A0 on the redboard to be our sensor
    // pin input:
    int sensorPin = A1;
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    const int buzzer = 8; //buzzer to arduino pin 8
    
    int oldBatteryPcnt = 0;
    
    void setup(){
      pinMode(buzzer, OUTPUT); // Set buzzer - pin 8 as an output
    // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
      analogReference(INTERNAL1V1);
    #else
      analogReference(INTERNAL);
    #endif
    }
    
    void presentation()
    {
    sendSketchInfo("Soil Moisture Sensor", "1.0");
    present(CHILD_ID, S_MOISTURE);
    }
    
    void loop()
    {
    int sensorValue;
    sensorValue = analogRead(sensorPin);
    //send back the values
    send(msg.set(sensorValue));
    if (sensorValue <= 800){
      tone(buzzer, 2000);
      delay(1000);       
      noTone(buzzer);     
      delay(500);        
      Serial.println(sensorValue);
    }
    else{
      Serial.println(sensorValue);
      }
    // delay until next measurement (msec)
    
    // get the battery Voltage
      int sensorValueBat = analogRead(BATTERY_SENSE_PIN);
    #ifdef MY_DEBUG
      Serial.println(sensorValueBat);
    #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 = sensorValueBat / 10;
    
    #ifdef MY_DEBUG
      float batteryV  = sensorValueBat * 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;
      }
    
    sleep(SLEEP_TIME);
    
    }
    

    Also I have another issue I would like that the sleep function works differently for the sensor and for the battery level and I cannot figure how to do this yet

    Thanks



  • Hey,

    I have a sensor working also using the readVCC lib as in your working example. But I don't see any obvious problem in your example using the voltage divider to read the battery voltage. Maybe you have a problem in your hardware connection to pin A1?
    Also one suggestion: between sending 2 messages, I prefer to include a wait(50). I had problems with lost messages when sending too fast, maybe my caps were depleted and my voltage dropped during sending.
    For your other problem I know how to do this, here an example:

    int counter=0
    
    void loop()
    if counter=120 {
       sendBatteryLevel(batteryPcnt);
       counter=0;
    }
    counter++
    sleep(30000);
    

    That way your battery is transmitted only once an hour, I use this also for my own sensor and it works great.



  • @Anduril thanks
    I will try your code for sending the battery status once an hour
    As for the A0, A1, A2 etc pins when I am using them alone they worked just fine but when I have A0 on battery and A1 on soil moisture the A1 never sends any signal (for the battery I don't know as the sensor don't work I did not connect the battery)



  • Hell @Anduril I try to add your code for having moisture level every 30 seconds and battery level every 50 minutes but look at my serial monitor I get the two values at the same time.
    Probably I am doing something wrong. Could you have a look at the loop code one more time please

    2413 MCO:SLP:WUP=-1
    2415 TSF:MSG:READ,0-0-2,s=255,c=3,t=6,pt=0,l=6,sg=0:Metric
    2422 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=37,pt=2,l=2,sg=0,ft=0,st=OK:1021
    1021
    2433 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:100
    2439 MCO:SLP:MS=30000,SMS=0,I1=255,M1=255,I2=255,M2=255
    2444 MCO:SLP:TPD
    2446 MCO:SLP:WUP=-1
    2450 TSF:MSG:SEND,2-2-0-0,s=0,c=1,t=37,pt=2,l=2,sg=0,ft=0,st=OK:1022
    1022
    2460 TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=OK:100
    2467 MCO:SLP:MS=30000,SMS=0,I1=255,M1=255,I2=255,M2=255
    2472 MCO:SLP:TPD
    

    my loop code is here:

    void loop()
    {
    int sensorValue;
    sensorValue = analogRead(sensorPin);
    send(msg.set(sensorValue));
    
    if (sensorValue <= 800){
      tone(buzzer, 2000); 
      delay(1000);        
      noTone(buzzer);     
      delay(1000);        
    }
    else{
      }
    
    // Battery
      #define MIN_V 2700
      #define MAX_V 3700
      int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage
      int counter=0;
    
    if (counter = 120) {
       sendBatteryLevel(batteryPcnt);
       counter=0;
    }
    counter++;
    
    sleep(30000);
    }
    

  • ADMIN

    @bmanos

    I see an error, if (counter = 120) should be if (counter == 120)



  • thanks @jkandasa I will correct this
    Is the rest of code Ok?


  • ADMIN

    @bmanos I do not see any other issues



  • @bmanos you should declare int counterin the header, not in the void loop(). The way you did it I think it will be set to 0 in each loop, never reaching 120. And of course @jkandasa is right, it has to be if (counter == 120)



  • thanks again @jkandasa and @Anduril for your help


  • MOD

    @bmanos said in About battery level:

    delay until ne

    One thing i saw in your sketch is this line

      delay(1000);
    

    Delay will stop all processing, also the mysensors code...
    what you preferably should use is:

    wait(1000);
    

    In this case mysensors is still able to process
    (just a little tip which will help coding, see this link for more information)


 

Suggested Topics

8
Online

364
Users

350
Topics

2.1k
Posts