Hello SierraGolfMike
Yes, there is. The magic word is OOP.
Below you will see a simple example to do this with several objects and a service that handle the button and blink business.
/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
Many thanks to LarryD
https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
https://forum.arduino.cc/t/monitoring-sketch/996076
Tested with Arduino: Mega[ ] - UNO [ ] - Nano [ ]
*/
#define ProjectName "Monitoring Sketch"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte ButtonPins[] {A0,A1,A2}; // portPin o---|button|---GND
constexpr byte LedPins[] {9, 10, 11}; // portPin o---|220|---|LED|---GND
constexpr unsigned long BlinkRate[] {100,500,1000};
#define OutPutTest
constexpr unsigned long OutPutTestTime {1000};
// CONSTANT DEFINITION
enum {One, Two, Three};
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
enum {Stop, Start, Blink};
enum {Released, Pressed};
struct TIMER { // has the following members
unsigned long duration; // memory for interval time
unsigned long stamp; // memory for actual time
int onOff; // control for stop/start/blink
};
struct BUTTON { // has the following members
byte pin; // port pin
bool statusQuo; // current state
TIMER scan; // see timer struct
};
struct MONITOR {
byte led;
BUTTON knop;
TIMER flash;
} monitors[] {
{LedPins[One], ButtonPins[One], false, 20, 0, Blink, BlinkRate[One], 0, false},
{LedPins[Two], ButtonPins[Two], false, 20, 0, Blink, BlinkRate[Two], 0, false},
{LedPins[Three], ButtonPins[Three], false, 20, 0, Blink, BlinkRate[Three], 0, false},
};
// time handler
bool timerEvent (TIMER &timer) {
bool reTurn = currentTime - timer.stamp >= timer.duration && timer.onOff;
if (reTurn) timer.onOff == Blink ? timer.stamp = currentTime : timer.onOff = Stop;
return reTurn;
}
// -------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
// https://www.learncpp.com/cpp-tutorial/for-each-loops/
for (auto monitor : monitors) pinMode(monitor.knop.pin, INPUT_PULLUP);
for (auto monitor : monitors) pinMode(monitor.led, OUTPUT);
#ifdef OutPutTest
// check outputs
for (auto monitor : monitors) digitalWrite(monitor.led, HIGH), delay(OutPutTestTime);
for (auto monitor : monitors) digitalWrite(monitor.led, LOW), delay(OutPutTestTime);
#endif
}
void loop () {
currentTime = millis();
digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
for (auto &monitor : monitors) {
if (timerEvent (monitor.knop.scan)) {
int stateNew = !digitalRead(monitor.knop.pin);
if (monitor.knop.statusQuo != stateNew) {
monitor.knop.statusQuo = stateNew;
switch (stateNew) {
case Pressed:
digitalWrite(monitor.led, HIGH);
monitor.flash.stamp = currentTime;
monitor.flash.onOff = Blink;
break;
case Released:
digitalWrite(monitor.led, LOW);
monitor.flash.onOff = Stop;
break;
}
}
if (timerEvent (monitor.flash)) digitalWrite(monitor.led, !digitalRead(monitor.led));
}
}
}
Have a nice day and enjoy coding in C++.
Дайте миру шанс!