/*
A Group of several objects
a simple on/off relay
a retriggerable Monoflop
a button to read
https://forum.arduino.cc/t/delay-turning-led-off-after-button-press/1105635/
2023-03-25 by noiasca
to be deleted: 2023-06
refactored to composition
*/
constexpr uint8_t noPin = 255; // unused dummy GPIO
void release(uint8_t); // only a prototype - just the signature of a function implemented later in the code
// a simple button read in OOP
class Button {
const uint8_t pin;
const uint8_t active = LOW;
public:
Button(uint8_t pin) : pin{pin} {}
void begin() {
pinMode(pin, INPUT_PULLUP);
}
uint8_t getPin() {
return pin;
}
bool isPressed() {
if (digitalRead(pin) == active ) return true; else return false;
}
};
// a simple on/off output
class OnOff {
const uint8_t pin; // the ouput pin
const uint8_t active = HIGH;
const uint8_t inactive = LOW;
public:
OnOff(uint8_t pin) : pin{pin}
{}
void begin() {
pinMode(pin, OUTPUT);
}
void on() {
digitalWrite(pin, active);
}
void off() {
digitalWrite(pin, inactive);
}
};
// a class to "switch off a pin" after a certain time
class Monoflop {
const uint8_t pin; // the output GPIO, active HIGH
bool state = false; // timer is running or not
uint32_t previousMillis = 0; // time management
public:
Monoflop(uint8_t pin) : pin{pin}
{}
void begin() { // to be called in setup()
pinMode(pin, OUTPUT);
}
void on(uint32_t currentMillis = millis()) {
previousMillis = currentMillis;
digitalWrite(pin, HIGH);
state = true;
}
void off() { // handles switching off
digitalWrite(pin, LOW);
state = false;
}
void update(uint32_t currentMillis = millis()) { // to be called in loop()
if (state && currentMillis - previousMillis > 3000) {
off();
}
}
};
// composite serveral harware belonging together
// a class for one button, one LED, one Relay
class Group {
Button button;
Monoflop led;
OnOff relay;
public:
Group(uint8_t buttonPin, uint8_t ledPin, uint8_t relayPin)
: button(buttonPin), led(ledPin), relay(relayPin)
{};
void begin() {
button.begin();
led.begin();
relay.begin();
}
void off() {
led.off();
relay.off();
}
uint8_t getButtonPin() {
return button.getPin();
}
void update(uint32_t currentMillis = millis()) {
if (button.isPressed()) {
release(button.getPin()); // call release with the current pressed button
led.on();
relay.on();
}
led.update(currentMillis); // the led needs to be updated;
}
};
//create 3 instances (each with one button, one LED, one relay)
Group amplifier[] {
{A2, 12, 7}, // buttonPin, ledPin, relayPin
{A1, 11, 8},
{A0, 10, 9},
};
Button offButton(A3); // a master off button
void release(uint8_t currentPin = noPin) {
for (auto &i : amplifier) {
if (currentPin != i.getButtonPin())
i.off();
}
}
void setup() {
Serial.begin(115200);
for (auto &i : amplifier) i.begin();
offButton.begin();
}
void loop() {
if (offButton.isPressed()) release();
for (auto &i : amplifier) i.update();
}