I am designing a turn signal bicycle blinker using two pushbuttons as input, one for each side, with a corresponding light for each button. The idea is this:
- Pressing one side makes same side start blinking;
- Pressing same side again to turn it off;
- Pressing other side turns off this side and turns other side on;
- (now the tricky part!) if both buttons are pressed (or more precisely, if one button is pressed before the other is released), then - and only then - I start blinking both sides ("warning signal" feature).
As I see it, the problem is that I need to wait until I release a single button (that would be one complete click) to turn a single side on, because if I press the second while the first remains pressed, that would be another event/gesture ("both_click", for lack of a better name).
Another design option would be to turn a single light on immediately on press, and if I press the second before release the first, then in would also turn the other light (thus comprising the "warning", both-lights-blinking mode). While that sounds feasible, there is all the debouncing logic in the Button ("Botao") class, and I am afraid I painted myself into a corner with the specific object-oriented design choices I've made.
I'm posting my current code (relevant parts only). Note there is a comment in the loop where I think I should detect double click.
Main .ino file:
#include "PiscaPisca.cpp" #include "Botao.cpp" PiscaPisca pisca; Botao botao1; Botao botao4; void setup() { pisca.configure(LEFT, RIGHT, BUZZER); botao1.configure(BUTTON1); botao4.configure(BUTTON4); } void loop() { // HOW SHOULD I DETECT BOTH WERE PRESSED?? // if (bothPressed()) { pisca.toggleWarning(); } if (botao1.wasPressed()) { pisca.toggleLeft(); } if (botao4.wasPressed()) { pisca.toggleRight(); } pisca.run(); } Botao.cpp (this is a button class with debounce)
#include <Arduino.h> class Botao { int _pino; const int DEBOUNCE_DELAY = 30; int buttonState; int lastState = HIGH; int lastDebounceTime; public : void configure(int pino) { _pino = pino; pinMode(pino, INPUT_PULLUP); } public : boolean wasPressed() { return debounce(LOW); } public : boolean wasReleased() { return debounce(HIGH); } public : boolean debounce(int state) { boolean gotEvent = false; int reading = digitalRead(_pino); if (reading != lastState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { if (reading != buttonState) { buttonState = reading; if (buttonState == state) { gotEvent = true; } } } lastState = reading; return gotEvent; } };