As you can see, at second 20, tasks 1 and 2 should execute at the same time, i.e. both LEDs should turn on together. But in reality, with my code, only the red LED turns on at second 20. Apart from that, my code produces correct results (see code below).
/*
task 1: turn on red LED for 1 second, execute every 4 seconds
task 2: turn on green LED for 1 second, execute every 10 seconds
*/
const long eventTime_Red = 4000; //execute every 4 seconds
const long eventTime_Green = 10000; //execute every 10 seconds
const long red_period = 1000; //keep red LED on for 1 second
const long green_period = 1000; //keep green LED on for 1 second
unsigned long previousTime_Red = 0;
unsigned long previousTime_Green = 0;
const byte LED_Red = 15; //LED red connected to pin 15
const byte LED_Green = 21; //LED green connected to pin 21
void setup() {
Serial.begin(9600);
pinMode(LED_Red, OUTPUT); //configure pin 15 to behave as an output
pinMode(LED_Green, OUTPUT); //configure pin 21 to behave as an output
digitalWrite(LED_Red, LOW); //have the red LED initially off
digitalWrite(LED_Green, LOW); //have the green LED initially off
}
void loop() {
unsigned long presentTime = millis();
//for task 1
if (presentTime - previousTime_Red >= eventTime_Red) {
while (millis() <= (presentTime + red_period)) {
//keep Red on for 1 sec
digitalWrite(LED_Red, HIGH);
Serial.print(presentTime / 1000);
Serial.println("Red ON");
}
digitalWrite(LED_Red, LOW);
previousTime_Red = presentTime;
}
//for task 2
if (presentTime - previousTime_Green >= eventTime_Green) {
while (millis() <= (presentTime + green_period)) {
//keep Red on for 1 sec
digitalWrite(LED_Green, HIGH);
Serial.print(presentTime / 1000);
Serial.println("Green ON");
}
previousTime_Green = presentTime;
digitalWrite(LED_Green, LOW);
}
}
I tried using the millis() function instead of delay() to avoid other instructions from being blocked.
I'm using ESP32 and see below for the circuit.
Thanks for the replies. But from what I can understand, Using millis() for timing. A beginners guide - Using Arduino / Introductory Tutorials - Arduino Forum and the BlinkWithoutDelay IDE example only take care of scheduling the tasks, which is something I've done using the instruction if (presentTime - previousTime_Red >= eventTime_Red)
my problem is not how to schedule tasks without using delay, it's how to execute two tasks at once.
UKHeliBob, I tried using 'if' instead of 'while' and it appears to instruct both LEDs to turn on (from what I see on the serial monitor) however, in reality, I can't see either of the LEDs turn on, ever.
Actually, that is your problem. You are using while-loops to make the code stay in the while-loop until millis() hits a particular value. That's what the delay() function does. So your code behaves like you are using delay().
Take a look at Arduino Protothreads. It's a lightweight solution. It does have some limitations but overall it's pretty usable for basic multitasking. The example I linked can be used directly for blinking two LEDs.
what if the other LED needs to be turned on (and possibly off), while one LED is on?
a task generally uses processors cycles to accomplish something -- not wait? that's a feature of multi-tasking and use of interrupts, while one task has nothing to do, such as waiting for input, another task can run
The most simple basic use of millis() is in my opinion a millis-timer of 1 second and two counters.
I have not thought it through, but it could look like this:
const unsigned long interval = 1000UL;
void loop()
{
if( currentMillis - previousMillis >= interval)
{
previousMillis += interval; // this is to keep the millis-timer in sync with the time
if( countToFour == 3) // the drawing is not consistant, start at 4 means also start at 0 ?
digitalWrite( redLedPin, HIGH);
countToFour++;
if( countToFour >= 4)
countToFour = 0;
countToTen++;
}
}