Lux sensor (BH1750) sending battery level (V)

  • Hi,

    I really enjoy using MySensors!

    Got a small general question though: I'm using a BH1750 light sensor, powered by a 3V battery and I'd like to keep an eye on the battery status.

    I have added a line to the existing BH1750 scetch:

    #define CHILD_ID_VCC = 1
    MyMessage msgVcc(CHILD_ID_VCC, V_VOLTAGE);
    void Presentation() {
      sendSketchInfo("Light Lux Sensor", "1.1");
      present(CHILD_ID_VCC, S_MULTIMETER);
    Loop() {
    uint16_t lux = lightSensor.readLightLevel();
    float Vcc = ReadVcc();

    Domoticz recieves the data now, but the Voltage is reading 2968V because readVcc delivers mV
    If I change the code to:

    float Vcc = readVcc()/1000;

    I get an error message "call of overloaded 'set(float&)'is ambiguous"
    How can I send decimal values to the Domoticz controller from MySensors?

    Regards, Frank

  • @frankvk No programming skills, but is it correct trying to calculate in a procedure call rather than insert an intermediate step?
    If the ReadVcc() procedure call returns millivolts, suggest preceding the "float Vcc = ReadVcc();" with "int Voltage= ReadVcc();" and change the "float Vcc = ReadVcc();" to "float Vcc = Voltage/1000;", it should then do as you want.

  • Hi Zboblamont,

    Thanks for your response, but the error occurs in the line, obviously because Vcc is of the type 'float'


  • @frankvk I'm no expert on this, but do know all my nodes send battery as a float for the last 2 years, excerpt as follows:

    // Call for battery reading, send in every 12th RTC call?
       digitalWrite(BatteryOn, HIGH);
       voltread = analogRead(BatteryIn);
       float voltage = (7.272 * voltread) / 1024;
       digitalWrite(BatteryOn, LOW);
       halfday=0;//Reset for 12 hourly cycle
       halfday++;//Increment hourly cycle

    That is based on the internal value defined without any complications, but note that the message is sent to 2 decimal places, whether that truncation is essential for the MySensors environment I do not know, it was all I required.

  • Is there a typo in your message or in your code?
    First you used ReadVcc(), then readVcc()

  • Mod

    @frankvk could you post the entire sketch, including where readVcc comes from? Seeing the code will make it much easier to help you.

  • The line

    float Vcc = readVcc()/1000;

    should be:

    float Vcc = readVcc()/1000.;

    to start with. Note the decimal point! If read Vcc() returns a float, you cannot divide by an integer.

  • @bgunnarb
    But readVcc returns long

    long readVcc() {
      long result;
      // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Convert
      while (bit_is_set(ADCSRA,ADSC));
      result = ADCL;
      result |= ADCH<<8;
      result = 1126400L / result; // Back-calculate AVcc in mV
      return result;

  • Mod

    A float can be divided by an integer. The result will be a float.

    A long can be divided by an integer or a float. The result will differ though.
    2968/1000 will give the integer 2
    2968/1000.0 will give the float 2.968

    See "Integer and floating point division" at

  • @mfalkvidd @bgunnarb Something new learned from that, hadn't realised a procedure call could be mathematically manipulated like that, nor the subtle differences in the outputs...

  • Actually, I needed to change 2 things: first one was dividing by 1000.0 rather than 1000 and the other one was calling send(msgVcc.set(Vcc, 2)); rather than send(msgVcc.set(Vcc)); Now the log reads 2.95V.

    Thanks Mikael (@mfalkvidd) & everyone! Happy coding!

  • @mfalkvidd
    Yep, this is a great way of introducing errors that will be nearly impossible to find!😀

Log in to reply

Suggested Topics

  • 1
  • 2
  • 5
  • 2
  • 2
  • 10