#define DISPENSE_TIME 10000 // 25000
#define MIN_BUT_TIME 500 // minimum time from each button presses
// Definition of custom struct
struct DrinkSelect_t {
const char* label;
uint8_t input;
uint8_t output;
uint32_t pushTime;
bool active;
};
// Declare and initialize an array of DrinkSelect_t struct
DrinkSelect_t drinkSelectors[] = {
{"CH1", 22, 26, 0, false},
{"CH2", 23, 27, 0, false},
};
void setup() {
Serial.begin(115200);
Serial.println();
/*
Input/Output setup: iterate the drinkSelectors array (> C++ 11)
https://en.cppreference.com/w/cpp/language/range-for
*/
for (DrinkSelect_t& drink : drinkSelectors ) {
pinMode(drink.input, INPUT_PULLUP);
// This avoid the output to be activated for small time at start-up
pinMode(drink.output, INPUT_PULLUP);
pinMode(drink.output, OUTPUT);
// Output active on LOW status
digitalWrite(drink.output, !drink.active);
}
}
void loop() {
// For each drink selector check input state and set output
for (DrinkSelect_t& drink : drinkSelectors) {
// Button pushed (pullup -> active state == LOW)
if (!digitalRead(drink.input) && !drink.active) {
// Avoids two simultaneous button presses
if (millis() - drink.pushTime > MIN_BUT_TIME) {
drink.pushTime = millis();
drink.active = true;
Serial.print("Selected drink on ");
Serial.println(drink.label);
}
}
// Stop drink dispensing after defined time
if (drink.active && millis() - drink.pushTime > DISPENSE_TIME) {
drink.active = false;
Serial.print("Stop dispensing drink on ");
Serial.println(drink.label);
}
// Stop manually drink dispensing
if (!digitalRead(drink.input) && drink.active) {
// Avoids two simultaneous button presses
if (millis() - drink.pushTime > MIN_BUT_TIME) {
drink.pushTime = millis();
drink.active = false;
Serial.print("Manual stop dispensing drink on ");
Serial.println(drink.label);
}
}
// Out active on LOW status
digitalWrite(drink.output, !drink.active);
}
delay(10); // Only for better performance with simulator
}