I'm doing a Arduino controlled multitasking project, that need to do about 10 tasks. I was think to add 10 parameters based on the code below, but I really want to get help on a better solution if there are some .
Thanks
/* Multitasking using Arduino millis() function
Author : CircuitDigest (circuitdigest.com)
*/
int led1 = 6; // led1 connected at pin 6
int led2 = 7; // led1 connected at pin 7
int toggleLed = 5; // push button controlled led connected at pin 5
int pushButton = 2; // push butoon connected at pin 2 which is also interrupt pin
int ledState1 = LOW; // to determine the states of led1 and led2
int ledState2 = LOW;
unsigned long previousMillis1 = 0; //store last time LED1 was blinked
const long period1 = 1000; // period at which led1 blinks in ms
unsigned long previousMillis2 = 0; //store last time LED2 was blinked
const long period2 = 200; // period at which led1 blinks in ms
int debouncePeriod = 20; // debounce delay of 20ms
int debounceMillis = 0; // similar to previousMillis
bool buttonPushed = false; // interrupt routine button status
int ledChange = LOW; // to track the led status last
int lastState = HIGH; // to track last button state
void setup() {
pinMode(led1, OUTPUT); // define pins as input or output
pinMode(led2, OUTPUT);
pinMode(toggleLed, OUTPUT);
pinMode(pushButton, INPUT);
attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE); // use interrupt pin2
}
void pushButton_ISR()
{
buttonPushed = true; // ISR should be as short as possible
}
void loop() {
unsigned long currentMillis = millis(); // store the current time
if (currentMillis - previousMillis1 >= period1) { // check if 1000ms passed
previousMillis1 = currentMillis; // save the last time you blinked the LED
if (ledState1 == LOW) { // if the LED is off turn it on and vice-versa
ledState1 = HIGH; //change led state for next iteration
} else {
ledState1 = LOW;
}
digitalWrite(led1, ledState1); //set LED with ledState to blink again
}
if (currentMillis - previousMillis2 >= period2) { // check if 1000ms passed
previousMillis2 = currentMillis; // save the last time you blinked the LED
if (ledState2 == LOW) { // if the LED is off turn it on and vice-versa
ledState2 = HIGH;
} else {
ledState2 = LOW;
}
digitalWrite(led2, ledState2);//set LED with ledState to blink again
}
if (buttonPushed = true) // check if ISR is called
{
if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed) // generate 20ms debounce delay to avoid multiple presses
{
debounceMillis = currentMillis; // save the last debounce delay time
if (digitalRead(pushButton) == LOW && lastState == HIGH) // change the led after push button is pressed
{
ledChange = ! ledChange;
digitalWrite(toggleLed, ledChange);
lastState = LOW;
}
else if (digitalRead(pushButton) == HIGH && lastState == LOW)
{
lastState = HIGH;
}
buttonPushed = false;
}
}
}
How to you have your pushbutton wired up? Your code will demand a pullup resistor. Do you have it installed? An easier approach is to use the internal pullup by declaring the pin INPUT_PULLUP and wiring the pushbutton with one side to ground and one side to the input pin.
You can simplify your code by encapsulating all your tasks inside their own function.
/* Multitasking using Arduino millis() function
Author : CircuitDigest (circuitdigest.com)
*/
const int led1 = 6; // led1 connected at pin 6
const int led2 = 7; // led1 connected at pin 7
const int toggleLed = 5; // push button controlled led connected at pin 5
const int pushButton = 2; // push butoon connected at pin 2 which is also interrupt pin
void setup() {
pinMode(led1, OUTPUT); // define pins as input or output
pinMode(led2, OUTPUT);
pinMode(toggleLed, OUTPUT);
pinMode(pushButton, INPUT_PULLUP);
}
void loop() {
unsigned long currentMillis = millis(); // store the current time
blink1(currentMillis);
blink2(currentMillis);
checkButton(currentMillis);
}
void blink1(unsigned long now) {
const unsigned long period = 1000;
static unsigned long previousTime = 0;
if (now - previousTime >= period) {
previousTime = now; // save the last time you blinked the LED
digitalWrite(led1, !digitalRead(led1)); //set LED with ledState to blink again
}
}
void blink2(unsigned long now) {
const unsigned long period = 200;
static unsigned long previousTime = 0;
if (now - previousTime >= period) {
previousTime = now; // save the last time you blinked the LED
digitalWrite(led2, !digitalRead(led2)); //set LED with ledState to blink again
}
}
void checkButton(unsigned long now) {
const unsigned long period = 20; // debounce delay of 20ms
static unsigned long previousTime = 0;
static int lastButtonState;
int buttonState = digitalRead(pushButton);
if (now - previousTime >= period) {
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, toggle the LED
previousTime = now;
digitalWrite(toggleLed, !digitalRead(toggleLed));
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
}
}
Thanks.
I mean to do like :
unsigned long previousMillis1 = 0; //store last time LED1 was blinked
const long period1 = 1000;
unsigned long previousMillis2 = 0; //store last time LED1 was blinked
const long period2 = 2000;
…….
till
unsigned long previousMillis10 = 0; //store last time LED1 was blinked
const long period10 = 10000;
#include <mechButton.h>
#include <blinker.h>
int led1 = 6; // led1 connected at pin 6
int led2 = 7; // led1 connected at pin 7
int toggleLed = 5; // push button controlled led connected at pin 5
int pushButton = 2; // push butoon connected at pin 2 which is also interrupt pin
blinker LEDOne(led1); // Default blinking.
blinker LEDTwo(led2,10,100); // Different speed..
mechButton aButton(pushButton); // Button debouncer etc.
void setup() {
aButton.setCallback(myCallback); // Set up our callback. (Also calls hookup() for idling.)
pinMode(toggleLed, OUTPUT); // Set up toggled LED.
LEDOne.setOnOff(true); // Fire up first blinker.
delay(200); // Give it an offset. just for fun.
LEDTwo.setOnOff(true); // Fire up second LED.
}
// This is the guy that's called when the button changes state.
void myCallback(void) { digitalWrite(toggleLed,!aButton.trueFalse()); }
void loop() {
idle(); // Let the background tasks have their day in the sun.
}
If you would like to try it this way, you’ll need to install the LC_baseTools library from the library manager.
Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.