#include <Preferences.h>
// Settings
int TIMINGS[] = {-1, 1000, 5000, 10000 };
int BUTTONS[] = {16, 17, 18, 19 };
int LEDS[] = {27, 26, 25, 33 };
String COLORS[] = {"Grün", "Gelb", "Blau", "Weiss"};
String DESC = "GYBW";
int VALVE = 23;
// Variable Initialization
Preferences preferences;
String last_pressed = "";
String btn_edit_btn = "";
String mode = "";
int btn_edit_value = 0;
int time_target = 0;
int liters2time(int liters) {
if (liters < 1) {
return liters;
}
return liters * 1000;
}
int time2liters(int time) {
if (time < 1) {
return time;
}
return time / 1000;
}
void led_write(String active) {
for (int i = 0; i < sizeof(LEDS) / sizeof(LEDS[0]); i++) {
digitalWrite(LEDS[i], LOW);
}
for (int i = 0; i < active.length(); ++i) {
digitalWrite(LEDS[DESC.indexOf(active[i])], HIGH);
}
}
void startup_sequence() {
led_write("G");
delay(250);
led_write("Y");
delay(250);
led_write("B");
delay(250);
led_write("W");
delay(250);
led_write("");
delay(250);
led_write("GYBW");
delay(250);
led_write("");
delay(250);
led_write("GYBW");
delay(250);
led_write("");
}
int get_timing(String button) {
return preferences.getInt((button + "_TIMING").c_str());
}
void set_timing(String button, int value) {
preferences.putInt((button + "_TIMING").c_str(), value);
}
String get_pressed() {
String pressed = "";
for (int i = 0; i < sizeof(BUTTONS) / sizeof(BUTTONS[0]); i++) {
if (digitalRead(BUTTONS[i]) == HIGH) {
pressed += DESC[i];
}
}
return pressed;
}
void setup() {
Serial.begin(115200);
Serial.println("[DEBUG] Initializing...");
preferences.begin("Water_Station", false);
pinMode(VALVE, OUTPUT);
for (int i = 0; i < sizeof(BUTTONS) / sizeof(BUTTONS[0]); i++) {
pinMode(BUTTONS[i], INPUT);
}
for (int i = 0; i < sizeof(LEDS) / sizeof(LEDS[0]); i++) {
pinMode(LEDS[i], OUTPUT);
}
for (int i = 0; i < sizeof(TIMINGS) / sizeof(TIMINGS[0]); i++) {
if (get_timing(String(DESC[i])) == 0) {
set_timing(String(DESC[i]), TIMINGS[i]);
Serial.print("[DEBUG] The Timing of ");
Serial.print(COLORS[i]);
Serial.println(" was not saved in Memory!");
}
}
delay(250);
led_write("");
delay(250);
startup_sequence();
Serial.println("[DEBUG] Finished Initialization!");
}
void loop() {
if (time_target != 0) {
if (millis() > time_target) {
time_target = 0;
mode = "";
led_write(mode);
digitalWrite(VALVE, LOW);
}
}
String pressed = get_pressed();
if (last_pressed != pressed) {
delay(50);
pressed = get_pressed();
last_pressed = pressed;
if (pressed.length() == 0) {
if (mode == "restart") {
for (int i = 0; i < 10; ++i) {
led_write("GYBW");
delay(250);
led_write("");
delay(250);
}
ESP.restart();
}
} else {
if (pressed.length() == 1) {
if (mode == "") {
mode = pressed;
led_write(mode);
int start_time = millis();
digitalWrite(VALVE, HIGH);
if (get_timing(mode) >= 0) {
time_target = start_time + get_timing(mode);
}
} else if (mode == pressed){
time_target = 0;
mode = "";
led_write(mode);
digitalWrite(VALVE, LOW);
} else if (mode == "btn_edit_select_btn") {
btn_edit_btn = pressed;
btn_edit_value = time2liters(get_timing(btn_edit_btn));
mode = "btn_edit_select_value";
led_write(btn_edit_btn);
delay(500);
led_write("");
} else if (mode == "btn_edit_select_value") {
if (pressed == "G") {
if (btn_edit_value == -1) {
led_write("GB");
delay(500);
led_write("");
} else {
int sub = 0;
int values[DESC.length()];
for (int i = DESC.length() - 1; i > 0; i--) {
int power = pow(10, DESC.length() - i);
int val = btn_edit_value % int(power) - sub;
sub += val;
values[i] = val / (power / 10);
}
while (true) {
int sum = 0;
for (int i = 1; i < sizeof values/sizeof values[0]; ++i) {
sum += values[i];
}
if (sum == 0) {
break;
}
String active = "";
for (int i = 1; i < sizeof values/sizeof values[0]; ++i) {
if (values[i] != 0) {
active += DESC[i];
values[i] -= 1;
}
}
led_write(active);
delay(250);
led_write("");
delay(250);
}
}
} else {
if (btn_edit_value == -1) {
for (int i = 0; i < 5; ++i) {
led_write("GB");
delay(250);
led_write("");
delay(250);
}
} else {
int modifier = pow(10, DESC.length() - DESC.indexOf(pressed));
btn_edit_value = ((btn_edit_value + (modifier / 10)) % modifier) + (floor(btn_edit_value / modifier) * modifier);
led_write(pressed);
delay(100);
led_write("");
}
}
}
} else {
if (pressed == "GY") {
led_write("GYBW");
mode = "restart";
Serial.println("[DEBUG] Restarting...");
} else if (pressed == "GYBW") {
for (int i = 0; i < DESC.length(); i++) {
set_timing(String(DESC[i]), 0);
led_write("GYBW");
mode = "restart";
Serial.println("[DEBUG] Resetting...");
}
} else if (mode == "") {
if (pressed == "BW") {
led_write("GYBW");
mode = "btn_edit_select_btn";
}
} else if (mode == "btn_edit_select_value") {
if (pressed == "BW") {
set_timing(btn_edit_btn, liters2time(btn_edit_value));
Serial.print("[DEBUG] Timing of Button ");
Serial.print(COLORS[DESC.indexOf(btn_edit_btn)]);
Serial.print(" was changed to ");
Serial.print(liters2time(btn_edit_value));
Serial.print(" (");
Serial.print(btn_edit_value);
Serial.println(" Liters).");
mode = "";
for (int i = 0; i < 2; ++i) {
led_write("GYBW");
delay(250);
led_write("");
delay(250);
}
} else if (pressed == "GB") {
if (btn_edit_value == -1) {
btn_edit_value = 0;
} else {
btn_edit_value = -1;
}
led_write("GB");
delay(500);
led_write("");
}
}
}
}
}
}