Problem with if statements

I am reading a digital light sensor that outputs light value in lux. The unit will periodically give me a negative number and a zero during the day when it is in full sun.

I created a set of if statements, to trap the negative and the zero during light hours. My statements don’t seem to work right. If works fine until the sunsets then it jumps to 30000 and stays there the rest of the night. What i want is a negative or zero between 7am and 8pm to be capped at 30000 but after 8pm i want this to actually be a zero until morning.

I am sure i am missing something simple here but i can’t see it. thanks in advance.

here is the code

#if defined(light_on)
  Wire.begin();
  BH1750_Init(BH1750_address); 
  delay(200);
  long valf=0;   
  if(BH1750_Read(BH1750_address)==2){
    
    valf=((buff[0]<<8)|buff[1])/1.2;
  }
  LightRawValue = valf;
   
  if (LightRawValue < 0){
    LightRawValue = 28000;
  }
  
  if (hour() >= 7 && hour() <= 20 && LightRawValue == 0){
    LightRawValue = 30000;
          } 
  if (hour() >= 20 && hour() <= 21 && LightRawValue == 0){
    LightRawValue = 5;
          }          
  if (hour() >= 21 && hour() <= 24 || hour() >= 0 && hour() < 7  && LightRawValue == 0){
    LightRawValue = 10;
          }
  else           
  LightValue = LightRawValue;
#else
  LightRawValue = 0;
  LightValue = 0;
#endif

Snippets R Us!

My bad…this is the full code for the function to read the sensor.

 /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !!LIGHT SENSOR!!LIGHT SENSOR!!LIGHT SENSOR!!LIGHT SENSOR!!LIGHT SENSOR!!LIGHT SENSOR!!LIGHT SENSOR!!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
 //******************************* GY-30 DIGITAL LIGHT SENSOR ***************************

#if defined(light_on)
  Wire.begin();
  BH1750_Init(BH1750_address); 
  delay(200);
  long valf=0;   
  if(BH1750_Read(BH1750_address)==2){
    
    valf=((buff[0]<<8)|buff[1])/1.2;
  }
  LightRawValue = valf;
   
  if (LightRawValue < 0){
    LightRawValue = 28000;
  }
  
  if (hour() >= 7 && hour() <= 20 && LightRawValue == 0){
    LightRawValue = 30000;
          }
  else if (hour() >= 20 && hour() <= 21 && LightRawValue == 0){
    LightRawValue = 5;
          }          
  else if (hour() >= 21 && hour() <= 24 || hour() >= 0 && hour() < 7  && LightRawValue == 0){
    LightRawValue = 10;
          }
  else           
  LightValue = LightRawValue;
#else
  LightRawValue = 0;
  LightValue = 0;
#endif  
  if (isnan(LightValue)) {
    LightValue = -1;
  } 
  PString my_Light_string(Light_char, sizeof(Light_char));
  my_Light_string.print(LightValue);
  if (LightValue < 10){
    my_Light_string.println("% "); 
  } 
  else {
    my_Light_string.println("%"); 
  }

added attachment image of graph output

I was really hinting that you should post, (or attach if it’s too big), all of your code and not just part of it.

Anyway, if you want constant zeroes between 8pm and 7am, why read the sensor at all during that period? Just hard-code a zero. Or still read the sensor, then if the time is within that period, set the ‘LightRawValue’ to zero.

And if you do want zeroes between those hours, this won’t do that:-

else if (hour() >= 20 && hour() <= 21 && LightRawValue == 0){
    LightRawValue = 5;

And neither will this:-

else if (hour() >= 21 && hour() <= 24 || hour() >= 0 && hour() < 7  && LightRawValue == 0){
    LightRawValue = 10;

If works fine until the sunsets then it jumps to 30000 and stays there the rest of the night.

30,000 or 28,000? The only one of your conditionals that sets it to 30,000 is this one:-

if (hour() >= 7 && hour() <= 20 && LightRawValue == 0)
{
    LightRawValue = 30000;
}

and it looks like it should only have an effect between 7am and 8pm as it’s supposed to.

My thought, (if you’re actually getting 28,000 all night, is that the sensor might be returning negative values, in which case this will set it to 28,000:-

if (LightRawValue < 0){
    LightRawValue = 28000;
  }

and none of your conditionals will then have an effect because they rely on a ‘LightRawValue’ of zero.

If that’s not the case, and you’re really getting 30,000 at night and not 28,000, then I can’t see where the error is.

Bottom line, I guess, is that if it works fine during the day, and you want zero all night, just hard-code the zero between 8pm and 7am. (What happens when the seasons change? Will you still use the same threshold times?)

What kind of code is that, and what device is it for?

INTP:
What kind of code is that, and what device is it for?

Are you wondering about this?:-

PString my_Light_string(Light_char, sizeof(Light_char));

The sensor is the GY-30 digital light sensor

The code i added is just for that sensor, its 1 of 22 other sensors being read so the full document would be too large to post here.

The issue is with the code that should set the output to 30000 only between 7am and 8pm it seems to get stuck at that point.

if (hour() >= 7 && hour() <= 20 && LightRawValue == 0)
{
    LightRawValue = 30000;
}

What i expected was for the output to got to 5

else if (hour() >= 20 && hour() <= 21 && LightRawValue == 0){
    LightRawValue = 5;

and then to go to 10 at 9pm

else if (hour() >= 21 && hour() <= 24 || hour() >= 0 && hour() < 7  && LightRawValue == 0){
    LightRawValue = 10;

Right now the time in the system would be 00:23 yet the light sensor is showing and output of 30000 the attachment is a screenshot of the graph for today.

OldSteve:
Are you wondering about this?:-

PString my_Light_string(Light_char, sizeof(Light_char));

Wondering about the whole thing. No setup, no loop, etc.

You didn’t describe what you wanted very well in your opening post:-

but after 8pm i want this to actually be a zero until morning.

because you actually want it to be 5 or 10, not 0.

Seems to me that if this isn’t working:-

else if (hour() >= 20 && hour() <= 21 && LightRawValue == 0)
{
    LightRawValue = 5;
}

then one of the conditions isn’t being met, so if the hour is actually 20 or 21, then ‘LightRawValue’ must not be 0.

The code i added is just for that sensor, its 1 of 22 other sensors being read so the full document would be too large to post here.

That’s why I suggested attaching it instead of posting it, (if it’s too big). You should try to always show the full code, not just the bits that you think are relevant.

INTP:
Wondering about the whole thing. No setup, no loop, etc.

I’ve been trying to get the full code. (And the ‘PString’ stuff is just a lib.)

Anyway, here are the essential parts of what I was using for my lux meter (I had it print to an lcd screen since it was a portable unit). Maybe it can be of some use. The variable ‘lux’ can then be manipulated in whatever way.

/*
  BH1750 Lux sensor
*/

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

BH1750 lightMeter;

void setup() {
  Serial.begin(9600);
  lightMeter.begin();
}


void loop() {
  uint16_t lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lux");
    delay(500);
}

Although I’m not sure what any of your code has to do with a light sensor since you’re hard coding values based on time, it seems.

Also this bit and parts like it are weird
if (hour() >= 7 && hour() <= 20
else if (hour() >= 20 && hour() <= 21

What happens if the hour is 20? It is >7, =20, =20, AND <21 all at the same time.

INTP:
Anyway, here are the essential parts of what I was using for my lux meter (I had it print to an lcd screen since it was a portable unit). Maybe it can be of some use. The variable ‘lux’ can then be manipulated in whatever way.

/*

BH1750 Lux sensor
*/

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

BH1750 lightMeter;

void setup() {
 Serial.begin(9600);
 lightMeter.begin();
}

void loop() {
 uint16_t lux = lightMeter.readLightLevel();
 Serial.print(“Light: “);
 Serial.print(lux);
 Serial.println(” lux”);
   delay(500);
}





Although I'm not sure what any of your code has to do with a light sensor since you're hard coding values based on time, it seems.


Also this bit and parts like it are weird
if (hour() >= 7 && hour() <= 20 
else if (hour() >= 20 && hour() <= 21 

What happens if the hour is 20? It is >7, =20, =20, AND <21 all at the same time.

If you put your light sensor since its the same one i am using in the clear view of the sun you will find when in full sunshine it outputs both negative numbers and zero when in full sunlight. this part of my code is more error checking. If its between 7am and 8pm and i get a zero i know the sensor is actually maxed out. If at anytime i get a negative its maxed out. It will also output a valid zero when ramping down at sunset. I have two months worth of sql data on this sensor.

I want the sensor to read light at night in relation to an AS3935 sensor the reason why i am not shutting it off completely. IE Lightning flashes. So after dark a zero becomes a zero and its not clipped to max during these hours.

You may have shown me the error in your post i am going to remove the = sign in the last half of the statment and reflash it. so that

changing this

if (hour() >= 7 && hour() <= 20 && LightRawValue == 0)
{
    LightRawValue = 30000;
}

to this which should make the statement not true once it hits 20 hours

if (hour() >= 7 && hour() < 20 && LightRawValue == 0)
{
    LightRawValue = 30000;
}

I changed the code to this, i tweaked the checks in the if statements to not include the = in the last part and i deleted the ELSE statement just before the LightValue=LightRawValue line. This else statement seemed to be causing it to skip the actual checks. With these changes and the code as shown below, after checking with print statements that the raw reading was in fact zero and that my hour variable contained the right time (0-23) it is now giving me my test value of 10 for the current time. Looks like the else was the culprit in the code stopping the checks from happening properly. Will wait to see what it does tomorrow morning. I have 5 and 10 right now for testing so i can tell which line it executed once I know the checks are working i will simply the statements again since 5 and 10 code is a bit redundant and will eventually just be a single check.

 //******************************* GY-30 DIGITAL LIGHT SENSOR ***************************

#if defined(light_on)
  Wire.begin();
  BH1750_Init(BH1750_address); 
  delay(200);
  long valf=0;   
  if(BH1750_Read(BH1750_address)==2){
    
    valf=((buff[0]<<8)|buff[1])/1.2;
  }
  LightRawValue = valf;
  
//  Serial.println(LightRawValue); 
//  Serial.println(hour()); 
 
  if (LightRawValue < 0){
    LightRawValue = 28000;
  }

  if (hour() >= 7 && hour() < 20 && LightRawValue == 0){
    LightRawValue = 30000;
          }
  if (hour() >= 20 && hour() <= 23 && LightRawValue == 0){
    LightRawValue = 5;
          }          
  if (hour() >= 0 && hour() < 7  && LightRawValue == 0){
    LightRawValue = 10;
          }
            
  LightValue = LightRawValue;
#else
  LightRawValue = 0;
  LightValue = 0;
#endif  
  if (isnan(LightValue)) {
    LightValue = -1;
  } 
  PString my_Light_string(Light_char, sizeof(Light_char));
  my_Light_string.print(LightValue);
  if (LightValue < 10){
    my_Light_string.println("% "); 
  } 
  else {
    my_Light_string.println("%"); 
  }