I wish to make an arduino output pin, say 13 go high after an IR sensor senses an obstacle at pin 2 (input pin). pin 13 should stay high for 5 seconds and go low even if the obstacle is still present. To make pin 13 high again, the obstacle should move away for a second and come back.
below is my intended Sketch:
const int IRval = 2; //Pin2 as IR sense pin.
const int LEDpin = 13; //Pin13 as Output pin.
int Time = 5000; // time delay.
void setup() {
pinMode(LEDpin, OUTPUT);
pinMode(IRval, INPUT);
}
void loop() {
if (digitalRead(IRval) == LOW) {
digitalWrite(LEDpin, HIGH);
delay(Time);
digitalWrite(LEDpin, LOW);
}
else {
digitalWrite(LEDpin, LOW);
}
}
Yes please.
so far as there is an obstacle pin 13 stays high, but i want it (pin 13) to low after 5 seconds even if the obstacle is still present.
thanks
I moved your topic to an appropriate forum category @kofii .
In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.
You could use a simple finite state machine model. The states could be :
waiting_for_detection
detected_led_on
detected_led_off
no_detection_wait.
The device is normally in state 1). On triggering the IR detector the state changes to 2) and the led is switched on. After 5 seconds in state 2) the led is switched off and the state changes to 3). If in state 3) the IR detector is no longer triggered the state changes to 4). If in state 4) there is a re-trigger, the state changes back to 3). If, however, the state is 4) for more than 1 second then the state changes to 1).
your applciation is pretty typical. So I decided to write a demo-code for it and to add it to my state-machine tutorial.
In the WOKSim the PIR-Sensor has a Ontime of 15 seconds.
(Can be adjusted in the JSON-tab)
to demonstrate led goes off after 5 seconds code keeps on waiting until PIR is low
and then waits an additional second.
const byte IR_Pin = 2; //Pin2 as IR sense pin.
const byte LEDpin = 13; //Pin13 as Output pin.
const byte heartBeatLED_Pin = 12;
enum myStates {
waiting_for_detection,
detected_led_on,
detected_led_off,
no_detection_wait
} myStateVar;
unsigned long myTimer = 0; // Timer-variables MUST be of type unsigned long
const unsigned long LED_OnTime = 5000;
const unsigned long noObstacleWaitTime = 1000;
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
PrintFileNameDateTime();
pinMode(IR_Pin, INPUT);
pinMode(LEDpin, OUTPUT);
pinMode(heartBeatLED_Pin, OUTPUT);
myStateVar = waiting_for_detection;
}
void loop() {
BlinkHeartBeatLED(heartBeatLED_Pin, 250);
myMonoStableStateMachine();
}
void myMonoStableStateMachine() {
switch (myStateVar) {
case waiting_for_detection:
if (digitalRead(IR_Pin) == HIGH ) {
Serial.println( F("object detected switching on LED") );
myTimer = millis(); // store snapshot of time
digitalWrite(LEDpin, HIGH);
myStateVar = detected_led_on;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
case detected_led_on:
Print_a_dot(500);
if ( TimePeriodIsOver(myTimer, LED_OnTime) ) {
Serial.println( F("LED ON-time over switching LED off") );
digitalWrite(LEDpin, LOW);
myStateVar = detected_led_off;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
case detected_led_off:
Print_a_dot(500);
if (digitalRead(IR_Pin) == LOW ) {
Serial.println( F("No object start ignore-waiting") );
myTimer = millis();
myStateVar = no_detection_wait;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
case no_detection_wait:
Print_a_dot(500);
if ( TimePeriodIsOver(myTimer, noObstacleWaitTime) ) {
Serial.println( F("ignore-waiting is over start wait for detection") );
Serial.println();
Serial.println();
myStateVar = waiting_for_detection;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
} // END-OF-SWITCH
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
void Print_a_dot(unsigned long interval) {
static unsigned long myWaitTimer;
if ( TimePeriodIsOver (myWaitTimer,interval) ) {
Serial.print(".");
}
}
This is the state model as far as I have interpreted the OP's requirements and should also match the description in post #8. On quick inspection, not all the solutions presented so far have respected the "1 second" condition following the switching off of the LED.
There are lots of such state machine templates, however, sometimes the compexity of the chosen state machine engine can obscure the basic simplicity of the approach, at least when trying to convince a new user of the benefits of this type of solution.
Setup-Start
Code running comes from file
/tmp/build-9RVG5H/sketch/sketch.ino
compiled Aug 6 2023 12:56:37
object detected switching on LED
...........LED ON-time over switching LED off
...................No object start ignore-waiting
...ignore-waiting is over start wait for detection