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++.
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
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
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.