/*
Arduino Forum
Topics: 2 pushbutton on / off
Sub-Category: Programming Questions
Category: Using Arduino
Link: https://forum.arduino.cc/t/2-pushbutton-on-off/1293385
*/
#define DIM_MAX 255 // Maximum dim Value
#define DIM_MIN 0 // Mininum dim value
#define DEBOUNCE_TIME 10 // Debounce time delay
#define REPEAT_RATE 50 // Repeat rate 50 millisecond delay
#define OFFSET 5 // Increase/Decrease offset
#define ledPin 5
typedef struct {
uint8_t pin; // Button pin
bool state; // Button State, FALSE = Pressed, TRUE = Released
bool input; // Input State
bool pressed; // Pressed state
unsigned long startTime; // Start Time for buttonRead and repeat
} pullupButton; // Pullup Button State
const uint8_t numberOfButtons = 2; // Number of LED/Button groups
const uint8_t pbPins[numberOfButtons] = {A0, A1}; // LED output pins
pullupButton buttons[numberOfButtons]; // pullupButton state
int dimValue; // Dimmer Value
bool increase; // Dimmer operator, FALSE = decrease, TRUE = increase
enum dimmerOperator : bool {DECREASE, INCREASE}; // Dimmer Operator
void setup() {
Serial.begin(115200); // Serial baud rates
increase = INCREASE; // Dimmer operator
dimValue = 255; // Set dim value
initial(); // Button & LED pin mode, with an initial state
}
void loop() {
dimControl(); // Dim the LED
}
void initial() {
for (uint8_t index = 0; index < numberOfButtons; index++) {
buttons[index].pin= pbPins[index]; // Input Pin mode - INPUT_PULLUP: TRUE = PRESSED, FALSE = RELEASED
pinMode(buttons[index].pin, INPUT_PULLUP); // Input Pin mode - INPUT_PULLUP: TRUE = PRESSED, FALSE = RELEASED
buttons[index].input = HIGH; // Inital input with TRUE
}
pinMode(ledPin, OUTPUT); // LED Pin mode
}
void dimControl() {
for (uint8_t index = 0; index < numberOfButtons; index++) {
bool repeat = buttonRepeat(index); // Get repeat action
if (buttons[index].pressed) increase = !increase; // Toggle dim operator
if (!repeat) return; // Repeat condition
increase == INCREASE ? dimValue += OFFSET : dimValue -= OFFSET; // Increase/Decrease dim value
if (dimValue > 255) dimValue = DIM_MAX; // Maximum limit
else if (dimValue < 0) dimValue = DIM_MIN; // Minimum limit
}
analogWrite(ledPin, dimValue); // Set LED brightness
serialPrint(); // Serial Print
}
bool buttonRepeat(uint8_t index) {
buttonRead(index);
if (buttons[index].state) return LOW; // Return if the button is released - INPUT_PULLUP: TRUE = PRESSED, FALSE = RELEASED
unsigned long currTime = millis(); // Set current time with "millis"
if ( currTime - buttons[index].startTime < REPEAT_RATE) return LOW; // Return FALSE if elapsed less than the repeat rate
buttons[index].startTime = currTime; // Reload start time with current "millis"
return HIGH;
}
bool buttonRead(uint8_t index) {
bool previnput = buttons[index].input; // Set the previous state with the previous input value
buttons[index].input = digitalRead(buttons[index].pin); // Read Input state
buttons[index].pressed = LOW; // Reset pressed state
if (buttons[index].input == buttons[index].state) return LOW; // Return TRUE if the current state is equal to the previous value.
unsigned long currTime = millis(); // Set current time with "millis"
if (buttons[index].input != previnput) buttons[index].startTime = currTime; // reload if button is pressed
if ( currTime - buttons[index].startTime < DEBOUNCE_TIME) return LOW; // Return FALSE if elapsed less than the repeat delay
buttons[index].startTime = currTime; // Reload start time with current "millis"
buttons[index].state = buttons[index].input; // Button state
buttons[index].pressed = buttons[index].state == LOW; // Pressed state
return buttons[index].pressed; // return pressed state
}
void serialPrint() {
Serial.println(", Dimmer Value:= " + String(dimValue)); // Print dim value
}