/*
Forum: https://forum.arduino.cc/t/replace-delay-with-milllis/1421640
Wokwi: https://wokwi.com/projects/451598397933631489
2025/12/28
ec2021
Example using arrays and boolean variables to control the function handleLeds()
SerialCommand library used for this example:
https://www.arduinolibraries.info/libraries/serial-command-advanced
*/
#include "MegunoLink.h"
#include "CommandHandler.h"
CommandHandler<5, 92, 34> SerialCommandHandler;
//InterfacePanel MyPanel;
unsigned long s1 = 3;
unsigned long s2 = 1;
unsigned long s3 = 4;
int v1 = 2;
int v2 = 4;
int v3 = 3;
constexpr int noOfItems = 3;
unsigned long multiplier[noOfItems] {s1, s2, s3};
int pin[noOfItems] {v1, v2, v3};
boolean startCmdReceived = false;
boolean stopCmdReceived = false;
// Commands Start and Stop
// set boolean variables to true
// that enable the required functionality
void Cmd_Start()
{
Serial.println(F("The Start command is handled"));
startCmdReceived = true;
}
void Cmd_Stop()
{
Serial.println(F("The Stop command is handled"));
stopCmdReceived = true;
}
void Cmd_SetValues(CommandParameter &Parameters)
{
s1 = Parameters.NextParameterAsUnsignedLong();
s2 = Parameters.NextParameterAsUnsignedLong();
s3 = Parameters.NextParameterAsUnsignedLong();
v1 = Parameters.NextParameterAsInteger();
v2 = Parameters.NextParameterAsInteger();
v3 = Parameters.NextParameterAsInteger();
Serial.println(F("The SetValues command is handled"));
}
// Invalid commands leave a message
void unrecognized(const char *command) {
Serial.println("Invalid command ..");
}
// The function handleLeds()
// handles Start and Stop command
// On Stop command
// * all leds are switched off
// * the local static variables are set to their start values
// * the booleans that control handleLeds() are set to false
// On Start command
// * the items are handled according to the index itemNo
// * in the first loop the item is switched on and the recent time is stored
// * in further loops, when the delay time has expired, everything is prepared
// for the next item
// * if all items have been handled, itemNo is set to 0 and startCmdReceived
// is cleared (set to false)
void handleLeds() {
static byte itemNo = 0;
static unsigned long switchOnTime = 0;
static boolean isSwitchedOff = true;
if (stopCmdReceived) {
for (int i = 0; i < noOfItems; i++) {
digitalWrite(pin[i], LOW);
}
itemNo = 0;
startCmdReceived = false;
isSwitchedOff = true;
stopCmdReceived = false;
return; // Not really necessary in this case as the rest of the function depends on startCmdReceived = true
}
if (startCmdReceived) {
if (isSwitchedOff) {
digitalWrite(pin[itemNo], HIGH);
isSwitchedOff = false;
switchOnTime = millis();
}
if (millis() - switchOnTime > multiplier[itemNo] * 1000) {
digitalWrite(pin[itemNo], LOW);
isSwitchedOff = true;
itemNo++;
}
if (itemNo >= noOfItems) {
itemNo = 0;
startCmdReceived = false;
}
}
}
// The following function blinks the blue led
// to verify that handleLeds() is not blocking
// loop()
void doSomethingElseAllTheTime(unsigned long interval) {
constexpr byte bluePin {LED_BUILTIN};
static unsigned long lastChange = 0;
if (lastChange == 0) pinMode(bluePin, OUTPUT);
if (millis() - lastChange > interval) {
lastChange = millis();
byte state = digitalRead(bluePin);
digitalWrite(bluePin, !state);
}
}
void setup()
{
Serial.begin(9600);
SerialCommandHandler.AddCommand(F("Start"), Cmd_Start);
SerialCommandHandler.AddCommand(F("SetValues"), Cmd_SetValues);
SerialCommandHandler.AddCommand(F("Stop"), Cmd_Stop);
Serial.println("Begin");
for (int i = 0; i < noOfItems; i++) {
pinMode(pin[i], OUTPUT);
}
}
void loop()
{
SerialCommandHandler.Process();
handleLeds();
doSomethingElseAllTheTime(500);
}