Create a program with a delay

Hello, i want to make small project for my house with this code for learning purposes. https://www.instructables.com/How-to-use-a-photoresistor-or-photocell-Arduino-Tu/.
But i want to modify this code like if photoresistor detects selected value for 3 seconds, for example, than it turns on led. I tried to use delay function after ''if'' but it slows down all program, because i want to use serial plotter to see photoresistors values in real time, but if i put delay function there, graphs become very slow. Can somebody help me out?

capture a timestamp of when the event first occurs and then use millis() to determine when 3 secs has past since that timestamp and perform some action.

once the action is executed, there's no need to compare the timestamp to millis()

Hello
Post your sketch, well formated, with comments and in so called code tags "</>" and schematic to see how we can help.
Have a nice day and enjoy coding in C++.

1 Like

You can use a simple state machine, such as this example:

#define TRIG_THRESHOLD      500
#define TRIG_TIME           3000ul
#define TRIG_LEDTIME        5000ul

const uint8_t pinTrigger = A0;
const uint8_t pinLED = LED_BUILTIN;

//give each of the states in the state machine names for ease of reading
typedef enum eStates
{
    ST_IDLE = 0,
    ST_TIME,
    ST_LED
        
}eStates_t;

eStates_t
    stateLED = ST_IDLE;
    
uint32_t
    tNow,
    tTrigger;

void setup() 
{
    pinMode( pinLED, OUTPUT );      //LED pin as output
    digitalWrite( pinLED, LOW );    //LED off
    tTrigger = millis();
        
}//setup

void loop() 
{
    //check in on LED state machine rapidly
    DoLED();
    
    //...do other stuff, none of it "blocking"
    
}//loop

void DoLED( void )
{
    //log the "time" now
    tNow = millis();
    
    switch( stateLED )
    {
        case    ST_IDLE:
            //waiting for the trigger input to go above the threshold
            if( analogRead( pinTrigger ) >= TRIG_THRESHOLD )
            {
                //it has; log the time it happened and move to time it
                tTrigger = tNow;
                stateLED = ST_TIME;
                
            }//if
            
        break;

        case    ST_TIME:
            //if the input falls below the trigger threshold, go back to IDLE state
            if( analogRead( pinTrigger ) < TRIG_THRESHOLD )
            {
                stateLED = ST_IDLE;
            }
            else if( (tNow - tTrigger) >= TRIG_TIME )
            {
                //if here, the input been above the threshold for the required 3-seconds
                digitalWrite( pinLED, HIGH );   //turn on the LED
                tTrigger = tNow;                //log the time we turn the LED on
                stateLED = ST_LED;                 //move to time the LED on-time
                
            }//else
            
        break;

        case    2:
            //when the LED has been on for the on-time...
            if( (tNow - tTrigger) >= TRIG_LEDTIME )
            {
                //turn it off and move back to the IDLE state
                digitalWrite( pinLED, LOW );
                stateLED = ST_IDLE;
                
            }//if
            
        break;
        
    }//switch
    
}//DoLED
1 Like

I was distracted by a strange compiler-errorness I suspect somehow caused by windumb ehm sorry windows

I made a version with more self-explaining names and re-worded comments and more comments that shall make the code easier to understand

This code has the exact same functionality as the one Blackfin posted just changed names and more comments

const unsigned long TRIG_THRESHOLD = 500;
const unsigned long TRIG_TIME   = 3000; // 3000 milliseconds as unsigned long
const unsigned long LED_ON_TIME = 5000; // 5000 milliseconds as unsigned long

const uint8_t pinPhotoCell = A0;
const uint8_t pinLED = LED_BUILTIN;

const byte ST_IDLE         = 0;
const byte ST_Check_Time   = 1;
const byte ST_LED_On_Timer = 2;

byte stateLED; // declare a variable with name "stateLED"

unsigned long timeNow;                   // stores actual timestamp
unsigned long timePhotocellAboveThresh;  // stores timestamp when sensor reading is above threshold
unsigned long timeStartLED_On;           // stores timestamp when LED is switched ON

void DoLED() {
  timeNow = millis();  // update variable with the actual time

  switch ( stateLED ) {

    case ST_IDLE:
      //check if value of photocell goes above the threshold
      if ( analogRead( pinPhotoCell ) >= TRIG_THRESHOLD ) {
        //measured value IS above threshold-value
        timePhotocellAboveThresh = timeNow;   // store timestamp when this happened
        stateLED = ST_Check_Time; // change to the state that checks how long the value stays above threshold value
      }//end of if
      break;

    case ST_Check_Time:
      // if the value of photocell  falls below the trigger threshold,
      if ( analogRead( pinPhotoCell ) < TRIG_THRESHOLD ) {
        stateLED = ST_IDLE; // go back to IDLE state
      }

      // check if more than the minimum-time defined in TRIG_TIME has passed by
      // with photocell value ABOVE threshold-value
      else if ( (timeNow - timePhotocellAboveThresh) >= TRIG_TIME ) {
        // value of photocell IS  more than the minimum-time above threshold
        digitalWrite( pinLED, HIGH );   // turn on the LED
        timeStartLED_On = timeNow;         // log the time we turn the LED on
        stateLED = ST_LED_On_Timer;              // move to state that does the timing for the LED beeing switched on
      }//end of else if
      break;

    case ST_LED_On_Timer:
      //check how long the LED has been ON
      if ( (timeNow - timeStartLED_On) >= LED_ON_TIME ) {
        // if more time than defined in LED_ON_TIME has passed by

        digitalWrite( pinLED, LOW ); // turn LED off
        stateLED = ST_IDLE;          // and change "state" back to the IDLE state
      }//end of if
      break;

  }//end of switch

}// end of DoLED


void setup() {
  pinMode( pinLED, OUTPUT );      //LED pin as output
  digitalWrite( pinLED, LOW );    //LED off
  timeStartLED_On = millis();
  stateLED = ST_IDLE; // initialise variable with value "ST_IDLE"
} //end of setup


void loop() {
  DoLED(); // execute the state-machine

  //...do other stuff, none of it "blocking" i.e. your serial output

}//end of loop

best regards Stefan

1 Like

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