Hello, I need help with this for loop please. What I'm trying to accomplish is: The LDR (later will be a PIR) turns on LED 1 for 5 seconds and blinks the LED 2 on and off. But then stops after a short time. I thought I could adjust the time to turn off by adjusting the for loop. Now it just stays on while the LDR is covered.
//Umpteenth try to get one LED on for 5 seconds and the other Blink while its on then turn itself off.
unsigned long previousMillisLED_long = 0; //Set up PreviousMillis
unsigned long previousMillisLED_short = 0;
int ldrPin = A0;
int intervalLED_long = 5000; //Set up Intervals
int intervalLED_short = 200;
byte ldrState = 0;
boolean LED_2state = false;
boolean LED_3state = false;
void setup() {
pinMode(A0, INPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
Serial.begin(9600);
}
void loop() {
int ldrState = analogRead(ldrPin); //set up LRD
Serial.print(ldrState);
unsigned long currentMillis = millis();
if (ldrState <= 300) { //If it triggers
for (int i = 0; i < 20; i++) { // repeat twenty times
digitalWrite(2, HIGH);
if ((unsigned long)(currentMillis - previousMillisLED_long) >= intervalLED_long) {
LED_2state = !LED_2state;
previousMillisLED_long = currentMillis;
}
if ((unsigned long)(currentMillis - previousMillisLED_short) >= intervalLED_short) {
LED_3state = !LED_3state;
digitalWrite(3, LED_3state);
// save current time to pin 3's previousMillis
previousMillisLED_short = currentMillis;
}
}
}
else { //shut all off
digitalWrite(2, LOW);
digitalWrite(3, LOW);
}
}
Putting millis() timing inside a for loop is a waste of effort - there can be no cooperative multitasking happening until the loop exits. A simple delay() would work identically and be easier to read and troubleshoot.
If you need cooperative multitasking, you need to eliminate the for loop altogether and use a state machine instead.
aarg:
Putting millis() timing inside a for loop is a waste of effort - there can be no cooperative multitasking happening until the loop exits. A simple delay() would work identically and be easier to read and troubleshoot.
If you need cooperative multitasking, you need to eliminate the for loop altogether and use a state machine instead.
Thanks, but if I delay the long LED will this not stop the blinking LED from working? My hope is to have both work at the same time.
You don't want to be using a for() loop for timing. Look at the BlinkWithoutDelay example to see how to keep track of elapsed time without preventing your code from doing other things. Basically, like this
//Umpteenth try to get one LED on for 5 seconds and the other Blink while its on then turn itself off.
unsigned long startTime = 0; // time of trigger
unsigned long previousBlinkTime = 0;
const int ldrPin = A0;
const int led1Pin = 2;
const int led2Pin = 3;
const unsigned long triggerDelay = 5000; //Set up Intervals
const unsigned long blinkDelay = 200;
bool isTriggered = false;
void setup() {
pinMode(ldrPin, INPUT);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int ldrState = analogRead(ldrPin); //set up LRD
Serial.print(ldrState);
unsigned long currentMillis = millis();
if (ldrState <= 300 && isTriggered == false) {
// initial trigger so start timing
isTriggered = true;
startTime = currentMillis;
previousBlinkTime = currentMillis;
digitalWrite(led1Pin, HIGH );
digitalWrite(led2Pin, HIGH );
}
if ( isTriggered == true ) {
// trigger has already happened so check timing
// first check if time to blink led2
if ( currentMillis - previousBlinkTime >= blinkDelay ) {
digitalWrite(led2Pin, !digitalRead(led2Pin) ); // toggle the led
previousBlinkTime = currentMillis;
}
// check if it is time to finish
if ( currentMillis - startTime >= triggerDelay ) {
// all done so turn everything off and reset trigger so it can happen again
digitalWrite(led1Pin, LOW );
digitalWrite(led2Pin, LOW );
isTriggered = false;
}
}
}