Light sensor with battery level problem



  • Hello all,

    I made a light sensor node and uploaded the example sketch. This is working fine!.
    But the node will be supplies by 2 AA batteries so i would like to see the battery level. I tried it like this but it does not work can anyone help me?

    #include <SPI.h>
    #include <MySensor.h>  
    
    #define NODE_ID 1
    #define CHILD_ID_LIGHT 0
    #define LIGHT_SENSOR_ANALOG_PIN 0
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    MySensor gw;
    MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    int lastLightLevel;
    
    void setup()  
    { 
      gw.begin(NULL, NODE_ID, false);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Light Sensor", "1.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    }
    
    void loop()      
    {     
      int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 
      Serial.println(lightLevel);
      if (lightLevel != lastLightLevel) {
          gw.send(msg.set(lightLevel));
          lastLightLevel = lightLevel;
      }
      gw.sleep(SLEEP_TIME);
    }
    
    #define MIN_V 2700
    #define MAX_V 3200
    int batteryPcnt = min(map(readVcc(), MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage
    
    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
    }
    ``


  • Hi derksuh,

    The code for the battery level should be in the loop, you've put it somewhere outside, although the sketch compiles....
    I think you should have a look at an specific example that comes with the mysensors library. Look at BatteryPoweredSensor. In that you'll find the code for sending the battery level. Now combine that with your sketch.

    good luck,

    Boozz



  • I've made some alterations to your code:
    Haven't tested is, but it compiles....😏

        #include <SPI.h>
        #include <MySensor.h>  
    
        #define NODE_ID 1
        #define CHILD_ID_LIGHT 0
        #define LIGHT_SENSOR_ANALOG_PIN 0
    
        int BATTERY_SENSE_PIN = A1;  // select the input pin for the battery sense point
        int oldBatteryPcnt = 0;
    
        unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
        MySensor gw;
        MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
        int lastLightLevel;
    
        void setup()  
        { 
          gw.begin(NULL, NODE_ID, false);
    
          // Send the sketch version information to the gateway and Controller
          gw.sendSketchInfo("Light Sensor", "1.0");
    
          // Register all sensors to gateway (they will be created as child devices)
          gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    
          
    
        }
    
        void loop()      
        {     
          int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 
          Serial.println(lightLevel);
          if (lightLevel != lastLightLevel) {
              gw.send(msg.set(lightLevel));
              lastLightLevel = lightLevel;
          }
          // get the battery Voltage
          int sensorValue = analogRead(BATTERY_SENSE_PIN);
    
          //2AA = approx. 3VDC --> sensorValue: 618  (3/5*1023)
          //sensorValue / 6.18 = 100  (%); rough estimate...
       
          int batteryPcnt = sensorValue / 6.18;
          if (batteryPcnt != oldBatteryPcnt) {
              gw.sendBatteryLevel(batteryPcnt);
              oldBatteryPcnt = batteryPcnt;
          }
          gw.sleep(SLEEP_TIME);
        }
    
    


  • @boozz

    I see what you did but that means that have to put a resistor in line with the battery and put that on A1. The sketch i meant measured the voltage supplied on vcv in the atmega 328



  • @derksuh

    Ok, but it still needs your code to find a place within the loop if I'm not mistaken?

    I'm not a c-programmer, so now and then I'm somewhat confused by the code of others. I learn by doing, which is now and then a process of copy-paste and at other moments analysing how others did it.

    BR,

    Boozz


 

420
Online

7.9k
Users

8.8k
Topics

93.8k
Posts