BH1750 won't work while using for statement

Hello, Can someone help me why my BH1750 sensor won't work and only show -1.00 whenever i use for statement in my project? I also use RTC DS3231 in this project.

Can someone please help me found the mistake?

#include <Wire.h>
#include <RTClib.h>
#include <BH1750.h>
#include <FastLED.h>

#define LED_PIN D0
#define NUM_LEDS 5

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
BH1750 lightMeter;
CRGB leds[NUM_LEDS];

void setup () {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  rtc.adjust(DateTime(__DATE__, __TIME__));
  FastLED.addLeds <WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  lightMeter.begin();
  

}

void loop () {
    DateTime now = rtc.now();
    float lux = lightMeter.readLightLevel();
    
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(" - ");
    Serial.print(now.day(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.year(), DEC);
    Serial.print(" - ");
    Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print("Light: ");
    Serial.print(lux);
    Serial.println(" lx");
    

    for (int i = 0; i <= NUM_LEDS; i++) {
      //Jam 6-10
      if ((now.hour() >= 6) && (now.hour() < 10)){
        leds[i] = CRGB (255 ,255, 0);
        if ((lux > 350)){
          FastLED.setBrightness(10);
        }
        else if ((lux <= 350)&&(lux >= 280)){
          FastLED.setBrightness(26);
        }
        else if ((lux <= 279)&&(lux >= 210)){
          FastLED.setBrightness(64);
        }
        else if ((lux <= 209)&&(lux >= 140)){
          FastLED.setBrightness(128);
        }
        else if ((lux <= 139)&&(lux >= 70)){
          FastLED.setBrightness(192);
        }
        else{
          FastLED.setBrightness(255);
        }
        FastLED.show();
      }
      //Jam 10-14
     else if ((now.hour() >= 10) && (now.hour() < 14)){
        leds[i] = CRGB (255, 255, 255);
        if ((lux > 350)){
          FastLED.setBrightness(10);
        }
        else if ((lux <= 350)&&(lux >= 280)){
          FastLED.setBrightness(26);
        }
        else if ((lux <= 279)&&(lux >= 210)){
          FastLED.setBrightness(64);
        }
        else if ((lux <= 209)&&(lux >= 140)){
          FastLED.setBrightness(128);
        }
        else if ((lux <= 139)&&(lux >= 70)){
          FastLED.setBrightness(192);
        }
        else{
          FastLED.setBrightness(255);
        }
       FastLED.show();
     }
     //Jam 14-18
     else if ((now.hour() >= 14) && (now.hour() < 18)){
        leds[i] = CRGB (255 ,255, 0);
        if ((lux > 350)){
          FastLED.setBrightness(10);
        }
        else if ((lux <= 350)&&(lux >= 280)){
          FastLED.setBrightness(26);
        }
        else if ((lux <= 279)&&(lux >= 210)){
          FastLED.setBrightness(64);
        }
        else if ((lux <= 209)&&(lux >= 140)){
          FastLED.setBrightness(128);
        }
        else if ((lux <= 139)&&(lux >= 70)){
          FastLED.setBrightness(192);
        }
        else{
          FastLED.setBrightness(255);
        }
       FastLED.show();
     }
     //Jam 18 - 6
     else{
       leds[i] = CRGB (255, 255, 255);
       if ((lux > 350)){
          FastLED.setBrightness(10);
        }
        else if ((lux <= 350)&&(lux >= 280)){
          FastLED.setBrightness(26);
        }
        else if ((lux <= 279)&&(lux >= 210)){
          FastLED.setBrightness(64);
        }
        else if ((lux <= 209)&&(lux >= 140)){
          FastLED.setBrightness(128);
        }
        else if ((lux <= 139)&&(lux >= 70)){
          FastLED.setBrightness(192);
        }
        else{
          FastLED.setBrightness(255);
        }
       FastLED.show();
     }
    }
  delay(1000);
    
}

I don't know much about lightmeter, but your for loop is very inefficient. Why do you adjust the brightness inside the lopp? It would be better set the color to each led first and than set the bright level to whole strip.

I see. I'm still learning about making a project like this. Thanks for the advice btw

i'm assuming you are using this library. It says that -1 means no valid return value. Not really sure why without knowing more information, but i think:

  • check that your wiring and or pins are correct
  • explicitly set what measurement mode when you lightMeter.begin(*mode*)

have a look at the example codes in the library, and maybe follow how they setup

Is what you are saying that if you remove the for statement, the sensor shows a different value, like 1000 or 10000?

Yeah. The sensor only won't work when i add for, while, and if statement on the program. When i remove it, the program work correctly, and i still don't know why

That's very strange. As already pointed out, your for loop is very inefficient and unnecessarily repetitive, but I don't see how it could interfere with the operation of the sensor, however it was written.

Post the working code (without the for loop) and some example output please. Also post a schematic. Hand-drawn is fine. Some bright, sharp photos might also help diagnose the problem.

It's not 100% same, but the schematic looks like this.

here's the working code and output without for statement.

#include <Wire.h>
#include <RTClib.h>
#include <BH1750.h>
#include <FastLED.h>

#define LED_PIN D0
#define NUM_LEDS 5

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
BH1750 lightMeter;
CRGB leds[NUM_LEDS];

void setup () {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  rtc.adjust(DateTime(__DATE__, __TIME__));
  FastLED.addLeds <WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  lightMeter.begin();
  

}

void loop () {
    DateTime now = rtc.now();
    float lux = lightMeter.readLightLevel();
    
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(" - ");
    Serial.print(now.day(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.year(), DEC);
    Serial.print(" - ");
    Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(("Light: "));
    Serial.print(lux);
    Serial.println(" lx");
    delay(1000);
}

I'm not add the fastLED function yet because it should in the loop

Thanks for the schematic, it's pretty good. One thing it doesn't show is how the NodeMCU is powered. USB?

WS2812 needs 5V, not 3.3V, so try powering the LEDs from Vin pin (which should be 5V direct from USB, check that also).

Normally, ws2812 LEDs need to be powered with an external 5V PSU, but you only have 5 LEDs, which should only require 250~300mA, plus another 80mA for the NodeMCU itself and very little at all for the sensor and RTC. You should still be within the 500mA maximum for USB. But make sure to are using a good quality USB cable. Try a few different ones to see if that makes any difference.

Put a large-ish cap across the 5V and ground lines near the LEDs. 100uF at least.

I wonder if having to power the LEDs in addition to its own current is causing problems for the 3.3V regulator on the NodeMCU.

Note: please don't post images of serial monitor. Copy the text from serial monitor and paste that into your forum post, between code tags.

You don't seem to be using the WiFi on the NodeMCU, so you could reduce the power needed by putting the ESP chip into "modem sleep". That should reduce current requirements by around 60mA.

If you do plan to use wi-fi, you don't really need an RTC in the circuit. It's pretty easy to have the NodeMCU get the time from a Network Time Server (NTP) when it starts up, and again every few hours or once per day to keep it's internal clock accurate.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.