resetting code through use of light sensor and if statement

Hey everyone,
In my code a led goes off after 5 seconds.
I then have a reset function that is connected to my light sensor through an if statement. This will then turn the light back on
However what I have been trying to do with the help of my tutors in class is to get the code to reset after the code detects that the light sensor had detected light under a certain number for a solid 10 seconds.
However our attempts have just led to the code making the code reset after 10 seconds and the light sensor detects darkness for even a fraction of a second.

Any help would be great.

Please note I know the code at the bottom is incorrect and will never work. It is just there to show what me and my tutors were trying to do.

Thank you

int led8 = 8;

unsigned long currentMillis;
unsigned long previousMillis = 0;

unsigned long interval = 5 * 1000UL;
unsigned long interval2 = 10 * 1000UL;

int sensorPin = 0;	// light sensor is connected to analog pin 0
int sensorValue;

long startTime ;                    // start time for stop watch

long elapsedTime ; 

void setup () {
  
  pinMode(led8, OUTPUT);
   digitalWrite(led8, HIGH);
  
  Serial.begin (9600 );
  
}

void(* resetFunc) (void) = 0;

void loop ()
{
 sensorValue = analogRead(sensorPin); // read the value of the sensor 
Serial.println (sensorValue);

currentMillis = millis();
  //led7turnoff
  if(currentMillis - previousMillis > interval) {   
    digitalWrite(led8, LOW);
  }
   if(sensorValue <= 0) {
    
    
    startTime = millis();
    
    
    elapsedTime =   millis() - startTime; 

if ((sensorValue <= 0) && (startTime += interval2))
  {
  
   resetFunc(); //call reset  
  
  

  }
   }
}

I then have a reset function that is connected to my light sensor through an if statement.


This makes no sense. An if statement can not connect a reset function to a light sensor. Nothing can make the light sensor trigger the reset function. Only the Arduino can call the reset function, possibly based on data read from sensors.

However what I have been trying to do with the help of my tutors in class is to get the code to reset after the code detects that the light sensor had detected light under a certain number for a solid 10 seconds.

Frankly, resetting the Arduino under these conditions makes no sense. You really need to find another approach. What is it that you are trying to accomplish if the sensor gets insufficient light for 10 full seconds?

   if(sensorValue <= 0) {

The analogRead() function does not return negative numbers. There is no point in checking from them.

    startTime = millis();
    
    
    elapsedTime =   millis() - startTime; 

if ((sensorValue <= 0) && (startTime += interval2))

Why are you incrementing the value of startTime in an if statement? After having done that, what do you suppose that the value in parentheses returns? True or false? Is that different from what was returned before the increment? In other words, that test is silly.

Please note I know the code at the bottom is incorrect and will never work.

Start by writing out in words, not code, exactly what you want to have happen.

Read the sensor.
If the value is less than some threshold, but was above it before, record the time (this is when it got dark).
If the value is above the threshold, clear the recorded time (it isn't dark, so there is no need to reset anything).
If there is a recorded time, and now minus then is greater than the allowable dark time, reset the Arduino (stupid, IMO).

Now, create some functions, like readSensor(), isItDarkButWasLight(), itsNotDark(), howLongHasItBeenDark(), resetTheArduino(), etc. Put the appropriate code in each one.

Then, loop() is pretty simple:

unsigned long darkTime;
int oldSensorValue;
void loop()
{
   int sensorVal = readSensor();
   if(isItDarkButWasLight())
     recordDarkTime();
   else
     itsNotDark();

   if(howLongItsBeenDark() > darkTooLong)
      resetTheArduino();
}

All you have to do is implement the individual functions correctly. Perhaps the names even give you enough clues.

I know it looks silly with only one led, this is the code simplified down to one l.e.d. In reality there are 8 l.e.ds each going off 2 hours apart,
And sorry I meant the Arduino will call the reset function through the if statement.

And that’s what I meant about the last bit of the code, doesn’t make sense but it shows an attempt.

Any advice to make an if statement that would reset the code if the sensor detected light under 20 for at least 10 seconds?

Thank you very much for the hints and advice, really appreciate it :slight_smile:

This demo several things at a time illustrates how to use millis() for timing things.

If you want to check that something is continuous over a period you need to keep checking its status and if it FAILS the test then you reset the clock to start counting again. If it gets as far as the full count without being reset then you know it has been continuous for the required period.

For example, set a variable startMillis = millis() at the start of the period and compare that to millis() at intervals. if (millis() - startMillis > interval) you will have achieved the continuous period. If, during the period one of your readings is too low or too high then you set startMillis = millis() again - which effectively restarts the timing.

...R

omegaforshort:
I know it looks silly with only one led, this is the code simplified down to one l.e.d. In reality there are 8 l.e.ds each going off 2 hours apart,
And sorry I meant the Arduino will call the reset function through the if statement.

And that’s what I meant about the last bit of the code, doesn’t make sense but it shows an attempt.

Any advice to make an if statement that would reset the code if the sensor detected light under 20 for at least 10 seconds?

So, try something like this:

#define PRINT_SPACE Serial.print(F(" "))

int ledPin8 = 8;
int lightSensorPin = 0;
unsigned long ledStartTime = 0;
unsigned long ledOnInterval = 5000UL;
unsigned long resetStartTime;
unsigned long resetInterval = 10000UL;
int lastSensorValue;
boolean wasZero;
//
//
void(* resetFunc) (void) = 0;
//
//
void setup () 
{
  pinMode(ledPin8, OUTPUT);
  digitalWrite(ledPin8, HIGH);
  Serial.begin (9600);
}
//
void loop ()
{
  int sensorValue = analogRead(lightSensorPin);
  if (sensorValue != lastSensorValue)
  {
    Serial.print(F("Light Level: "));
    if (sensorValue < 1000) PRINT_SPACE;
    if (sensorValue < 100) PRINT_SPACE;
    if (sensorValue < 10) PRINT_SPACE;
    Serial.println (sensorValue);  
  }
  if(millis() - ledStartTime >= ledOnInterval) 
  {   
    digitalWrite(ledPin8, LOW);
  }
  if (sensorValue < 20)
  {
    if (wasZero)
    {
      if (millis() - resetStartTime >= resetInterval)
      {
        resetFunc();
      }
    }
    else
    {
      resetStartTime = millis();// start the millis() timer when the state change occurs
      wasZero = true;  // set the flag to remember last reading
    }
  }
  else 
  {
    wasZero = false;
  }
  lastSensorValue = sensorValue;
}