[SOLVED] BH1750 Light level sensor not reading after sleep



  • I'm having an issue with a BH1750 light sensor where it only reads once and won't read again if I use sleep. I was initially building a multi sensor for motion, temperature and light level, and got the motion and temperature working fine, but hit this issue when adding the light level sensor. I assumed it was my code so stripped the whole thing back to basics and created a basic sensor with just an Arduino and the BH1750, all worked fine reading the levels.

    I then tried to create just a light level sensor using mysensors and even when using the example code had the issue where it would read once and send the info to the controller, but then just hangs on the second read (after sleeping). Specifically this line:

    lux = lightSensor.readLightLevel();
    

    I can make it work by removing the sleep command and adding a delay, but this is no good if I want to use it with a motion sensor!

    I've searched the forums and stumbled across this thread with a similar issue but the resolution was to use 2.3.1 beta and I am on 2.3.2 already. I also tried adding waits either side of the point where it hangs to give the sensor time to wake up after sleep, but that didn't help either!

    My code (which is derived from the mysensors sample code and the homeassistant sample, which happens to be for this exact sensor!!):

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    
    //define ID
    #define MY_NODE_ID 95
    #define MY_PARENT_NODE_ID 0
    
    #include <MySensors.h>  
    #include <BH1750.h>
    #include <Wire.h>
    
    #define LIGHT_CHILD_ID 3
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) (shortened for testing purposes!)
    
    BH1750 lightSensor;
    
    MyMessage msg(LIGHT_CHILD_ID, V_LEVEL);
    uint16_t lastlux = 0;
    uint16_t lux;
    bool initialValueSent = false;
    
    void setup()  
    { 
      lightSensor.begin();
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Light Lux Sensor", "1.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(LIGHT_CHILD_ID, S_LIGHT_LEVEL);
    }
    
    void loop()
    {
      if (!initialValueSent) {
        Serial.println("Sending initial value");
        send(msg.set(lastlux));
        Serial.println("Requesting initial value from controller");
        request(LIGHT_CHILD_ID, V_LEVEL);
        wait(2000, C_SET, V_LEVEL);
      }
      wait(10000);
      Serial.println("Reading Light Level"); //added for debugging
      lux = lightSensor.readLightLevel();  // Get Lux value
      wait(20);
      Serial.print("Value is: ");
      Serial.println(lux); //added for debugging
      if (lux != lastlux) {
          send(msg.set(lux));
          lastlux = lux;
      }
    
      sleep(SLEEP_TIME);
    }
    
    void receive(const MyMessage &message) {
      if (message.type == V_LEVEL) {
        if (!initialValueSent) {
          Serial.println("Receiving initial value from controller");
          initialValueSent = true;
        }
      }
    }
    

    The serial monitor output is:

     __  __       ____
    |  \/  |_   _/ ___|  ___ _ __  ___  ___  _ __ ___
    | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __|
    | |  | | |_| |___| |  __/ | | \__ \  _  | |  \__ \
    |_|  |_|\__, |____/ \___|_| |_|___/\___/|_|  |___/
            |___/                      2.3.2
    
    16 MCO:BGN:INIT NODE,CP=RNNNA---,FQ=16,REL=255,VER=2.3.2
    26 TSM:INIT
    28 TSF:WUR:MS=0
    34 TSM:INIT:TSP OK
    36 TSM:INIT:STATID=95
    38 TSF:SID:OK,ID=95
    39 TSM:FPAR
    44 ?TSF:MSG:SEND,95-95-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    632 TSF:MSG:READ,11-11-95,s=255,c=3,t=8,pt=1,l=1,sg=0:1
    637 TSF:MSG:FPAR OK,ID=11,D=2
    2052 TSM:FPAR:OK
    2053 TSM:ID
    2054 TSM:ID:OK
    2056 TSM:UPL
    2059 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    2081 TSF:MSG:READ,0-11-95,s=255,c=3,t=25,pt=1,l=1,sg=0:2
    2086 TSF:MSG:PONG RECV,HP=2
    2089 TSM:UPL:OK
    2091 TSM:READY:ID=95,PAR=11,DIS=2
    2096 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    2106 TSF:MSG:READ,0-11-95,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    2118 TSF:MSG:SEND,95-95-11-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.3.2
    2126 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:11
    2163 TSF:MSG:READ,0-11-95,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    2170 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=11,pt=0,l=16,sg=0,ft=0,st=OK:Light Lux Sensor
    2181 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0
    2198 TSF:MSG:SEND,95-95-11-0,s=3,c=0,t=16,pt=0,l=0,sg=0,ft=0,st=OK:
    2204 MCO:REG:REQ
    2211 TSF:MSG:SEND,95-95-11-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    2225 TSF:MSG:READ,0-11-95,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    2230 MCO:PIM:NODE REG=1
    2233 MCO:BGN:STP
    2254 MCO:BGN:INIT OK,TSP=1
    2257 TSF:MSG:READ,0-11-95,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    2263 MCO:PIM:NODE REG=1
    Sending initial value
    2271 TSF:MSG:SEND,95-95-11-0,s=3,c=1,t=37,pt=3,l=2,sg=0,ft=0,st=OK:0
    Requesting initial value from controller
    2279 TSF:MSG:SEND,95-95-11-0,s=3,c=2,t=37,pt=0,l=0,sg=0,ft=0,st=OK:
    2318 TSF:MSG:READ,0-11-95,s=3,c=1,t=37,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    Reading Light Level
    Value is: 4
    12344 TSF:MSG:SEND,95-95-11-0,s=3,c=1,t=37,pt=3,l=2,sg=0,ft=0,st=OK:4
    12351 MCO:SLP:MS=10000,SMS=0,I1=255,M1=255,I2=255,M2=255
    12356 TSF:TDI:TSL
    12358 MCO:SLP:WUP=-1
    12360 TSF:TRI:TSB
    Reading Light Level
    
    

    My controller is Homeassistant, and it get's the initial read from the sensor fine. If I remove the sleep command it works and the sensor updates in homeassistant when the level changes but clearly it loops without a sleep/delay and therefore sends the data way more frequently than I want/need!

    My ultimate goal is to add the sensor to my 'multi sensor' but I've hit this stumbling block just creating a basic light level sensor. Any help/advice would be gratefully received as I am completely stuck at this point.

    Thanks in advance!



  • Hi @Steve-Parsons, I had also some trouble with reading light level after sleep. My solution is to read the sensor twice. Also you should use in setup() the one-time-mode:

    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE)
    

    This is an excerpt of my battery powered garden sensor sketch.
    It runs on an Arduino Pro Mini clone:

    #include <BH1750.h>
    
    BH1750 lightMeter(0x23);
    
    void setup()
    {
      // begin returns a boolean that can be used to detect setup problems.
      if (lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE)) {
    	Serial.println(F(("BH1750 Advanced begin"));
      } else {
    	Serial.println(F(("Error initialising BH1750"));
      }
    }
    
    void getLightLevel()
    {
      lightMeter.readLightLevel();
      wait(20); // First measurement after sleep is wrong, take the seconde reading
      float lux = lightMeter.readLightLevel();
      if (lux >= 0.0) {
    	// Round lux to 0.1
            // May be this rounding can be improved
    	lux = floor(lux * 5 + 0.5) / 5;
    	send(lightMsg.set(lux, 1));
    
    	Serial.print(F("BH1750 - Light = "));
    	Serial.print(lux);
    	Serial.println(F(" lx"));
    
      } else {
    	Serial.println(F("=> BH1750 Error!"));
      }
    }
    
    void loop()
    {
      static uint32_t lastMillis = 0 - measurementPeriod;
      if (millis() - lastMillis >= measurementPeriod)
      {
    	getLightLevel();
    	lastMillis = millis();
      }
    
      unsigned long sleeptime = 60000ul; // 60 sec
      Serial.println(F("Sensors node - Go to sleep"));
      bool smart = true;
      sleep(sleeptime, smart);
      Serial.println(F("Sensors node - Waking up"));
    }
    

    HTH Immo



  • @virtualmkr thank you for taking the time to read my post and offering a solution.

    I've amended my setup as follows:

    void setup()  
    { 
      lightSensor.begin(BH1750::ONE_TIME_HIGH_RES_MODE);
    }
    

    I also amended my loop to the following:

    Serial.println("Reading Light Level");
      Serial.println("First Read");
      lightSensor.readLightLevel();
      wait(20);
      Serial.println("Second Read & Variable Set");
      lux = lightSensor.readLightLevel();  // Get Lux value
      wait(20);
    

    But I'm still having the same issue. I added the first and second read serial output lines for debugging so I could see where it stops, and it still hangs on the first read after sleep:

     __  __       ____
    |  \/  |_   _/ ___|  ___ _ __  ___  ___  _ __ ___
    | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __|
    | |  | | |_| |___| |  __/ | | \__ \  _  | |  \__ \
    |_|  |_|\__, |____/ \___|_| |_|___/\___/|_|  |___/
            |___/                      2.3.2
    
    16 MCO:BGN:INIT NODE,CP=RNNNA---,FQ=16,REL=255,VER=2.3.2
    26 TSM:INIT
    28 TSF:WUR:MS=0
    34 TSM:INIT:TSP OK
    36 TSM:INIT:STATID=95
    38 TSF:SID:OK,ID=95
    39 TSM:FPAR
    44 ?TSF:MSG:SEND,95-95-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    396 TSF:MSG:READ,0-0-95,s=255,c=3,t=8,pt=1,l=1,sg=0:0
    401 TSF:MSG:FPAR PREF
    403 TSF:MSG:FPAR OK,ID=0,D=1
    405 TSM:FPAR:OK
    407 TSM:ID
    408 TSM:ID:OK
    409 TSM:UPL
    446 !TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=NACK:1
    698 TSF:MSG:READ,11-11-95,s=255,c=3,t=8,pt=1,l=1,sg=0:1
    703 !TSF:MSG:FPAR INACTIVE
    2453 TSM:UPL
    2456 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=1,st=OK:1
    2467 TSF:MSG:READ,0-0-95,s=255,c=3,t=25,pt=1,l=1,sg=0:1
    2472 TSF:MSG:PONG RECV,HP=1
    2475 TSM:UPL:OK
    2477 TSM:READY:ID=95,PAR=0,DIS=1
    2482 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    2491 TSF:MSG:READ,0-0-95,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    2498 TSF:MSG:SEND,95-95-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.3.2
    2507 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    2536 TSF:MSG:READ,0-0-95,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    2543 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=11,pt=0,l=16,sg=0,ft=0,st=OK:Light Lux Sensor
    2557 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0
    2566 TSF:MSG:SEND,95-95-0-0,s=3,c=0,t=16,pt=0,l=0,sg=0,ft=0,st=OK:
    2572 MCO:REG:REQ
    2575 TSF:MSG:SEND,95-95-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    2583 TSF:MSG:READ,0-0-95,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    2588 MCO:PIM:NODE REG=1
    2590 MCO:BGN:STP
    2612 MCO:BGN:INIT OK,TSP=1
    Sending initial value
    2617 TSF:MSG:SEND,95-95-0-0,s=3,c=1,t=37,pt=3,l=2,sg=0,ft=0,st=OK:0
    Requesting initial value from controller
    2627 TSF:MSG:SEND,95-95-0-0,s=3,c=2,t=37,pt=0,l=0,sg=0,ft=0,st=OK:
    2652 TSF:MSG:READ,0-0-95,s=3,c=1,t=37,pt=0,l=1,sg=0:0
    Receiving initial value from controller
    Reading Light Level
    First Read
    Second Read & Variable Set
    Value is: 10
    12701 TSF:MSG:SEND,95-95-0-0,s=3,c=1,t=37,pt=3,l=2,sg=0,ft=0,st=OK:10
    12707 MCO:SLP:MS=10000,SMS=0,I1=255,M1=255,I2=255,M2=255
    12712 TSF:TDI:TSL
    12715 MCO:SLP:WUP=-1
    12717 TSF:TRI:TSB
    Reading Light Level
    First Read
    
    

    It just stops here and never goes anywhere.

    I should probably add that I am using a Nano (clone), wired up as per the BH1750 example on the MySensors site. It's powered through USB, and have tried a different Nano, and NRF24L01 without success.

    I took delivery of some more BH1750's today so going to solder one of those up and swap it out to see if that makes any difference!



  • Ok, so I have managed to get it working. I switched out the BH1750 for a new one and it was reading successfully after sleep and updating the controller, although the level wasn't changing regardless of how light/dark it was.

    I reverted back to my original code (so taking out the 'ONE_TIME_HIGH_RES_MODE') and it all appears to be working as expected, updating the level and the sensor on the controller.

    Thanks for your help, looks like it was a duff sensor in the end! Now just need to get it working with my 'multi sensor' 🙂



  • Hi @Steve-Parsons,
    short question: do you have applied the external pull-up resistors for the two I2C bus lines? Some modules have them built-in but others not. E.g. the Lolin Wemos shield has them already connected to power with two 4.7k resistors. See schematic for it: sch_bh1750_v1.0.0.pdf

    If not, you should try this.
    May be your first module is not defect, but only the resistors are missing?


Log in to reply
 

Suggested Topics

  • 3
  • 1
  • 6
  • 2
  • 6
  • 5

14
Online

11.4k
Users

11.1k
Topics

112.7k
Posts