#include #include #include #include #include "config.h" #define WIFI_TIMEOUT 30000 // ms #define LED_PIN D1 #define INPUT1 D2 #define INPUT2 D5 #define INPUT3 D6 #define INPUT4 D7 int input1_value = 0; int input2_value = 0; int input3_value = 0; int input4_value = 0; int led_timeout = 1000; long led_time = 0; long last_wifi_check_time = 0; long lastReconnectAttempt = 0; long reconnectAttempts = 0; long debouncing_time = 1000; volatile unsigned long last_micros; long lastTimesignalTime = 0; bool button1_pressed = 0; bool button2_pressed = 0; bool button3_pressed = 0; bool button4_pressed = 0; WiFiClient espClient; PubSubClient client(espClient); void setup_ota() { // Hostname defaults to esp8266-[ChipID] ArduinoOTA.setHostname(wifi_hostname); ArduinoOTA.setPassword(ota_password); ArduinoOTA.onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) { type = "sketch"; } else { // U_SPIFFS type = "filesystem"; } // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }); ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) { Serial.println("Auth Failed"); } else if (error == OTA_BEGIN_ERROR) { Serial.println("Begin Failed"); } else if (error == OTA_CONNECT_ERROR) { Serial.println("Connect Failed"); } else if (error == OTA_RECEIVE_ERROR) { Serial.println("Receive Failed"); } else if (error == OTA_END_ERROR) { Serial.println("End Failed"); } }); ArduinoOTA.begin(); } void setup_wifi() { // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.hostname(wifi_hostname); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } randomSeed(micros()); Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } boolean reconnect() { reconnectAttempts++; String clientID = "ESP8266Client-"; clientID += String(random(0xffff), HEX); if (client.connect(clientID.c_str(), NULL, NULL, willTopic, 0, 1, "0")) { Serial.println("MQTT Connected"); client.publish(willTopic, "1", true); client.subscribe(timeTopic); } else { Serial.print("MQTT failed, rc="); Serial.print(client.state()); Serial.println("Trying again"); } return client.connected(); } void callback(char* topic, byte* payload, unsigned int length) { Serial.println("Timesignal received"); lastTimesignalTime = millis(); } void setup() { pinMode(BUILTIN_LED, OUTPUT); pinMode(LED_PIN, OUTPUT); pinMode(INPUT1, INPUT_PULLUP); pinMode(INPUT2, INPUT_PULLUP); pinMode(INPUT3, INPUT_PULLUP); pinMode(INPUT4, INPUT_PULLUP); Serial.begin(115200); setup_wifi(); setup_ota(); client.setServer(mqtt_server, 1883); client.setCallback(callback); attachInterrupt(INPUT1, debounceInterrupt1, RISING); attachInterrupt(INPUT2, debounceInterrupt2, RISING); attachInterrupt(INPUT3, debounceInterrupt3, RISING); attachInterrupt(INPUT4, debounceInterrupt4, RISING); } void debounceInterrupt1() { Serial.println("debounce 1"); if((long)(micros() - last_micros) >= debouncing_time * 1000) { schedule_function(Button1); last_micros = micros(); } } void debounceInterrupt2() { Serial.println("debounce 2"); if((long)(micros() - last_micros) >= debouncing_time * 1000) { schedule_function(Button2); last_micros = micros(); } } void debounceInterrupt3() { Serial.println("debounce 3"); if((long)(micros() - last_micros) >= debouncing_time * 1000) { schedule_function(Button3); last_micros = micros(); } } void debounceInterrupt4() { Serial.println("debounce 4"); if((long)(micros() - last_micros) >= debouncing_time * 1000) { schedule_function(Button4); last_micros = micros(); } } void Button1() { Serial.println("Button 1 pressed"); client.publish(outTopic, "1", true); digitalWrite(LED_PIN, 1); led_time = millis(); } void Button2() { Serial.println("Button 2 pressed"); client.publish(outTopic, "2", true); digitalWrite(LED_PIN, 1); led_time = millis(); } void Button3() { Serial.println("Button 3 pressed"); client.publish(outTopic, "3", true); digitalWrite(LED_PIN, 1); led_time = millis(); } void Button4() { Serial.println("Button 4 pressed"); client.publish(outTopic, "4", true); digitalWrite(LED_PIN, 1); led_time = millis(); } void loop() { if (millis() - lastTimesignalTime > 180000) { Serial.println("Timesignal is missing, restarting"); ESP.restart(); } if (millis() - last_wifi_check_time > WIFI_TIMEOUT) { Serial.print("Checking WiFi... "); if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi connection lost. Reconnecting..."); setup_wifi(); } else { Serial.println("OK"); } last_wifi_check_time = millis(); } if (!client.connected()) { if (millis() - lastReconnectAttempt > 5000) { lastReconnectAttempt = millis(); // Attempt to reconnect Serial.println("Attempting MQTT reconnect"); if (reconnect()) { reconnectAttempts = 0; lastReconnectAttempt = millis(); } if (reconnectAttempts > 5) { Serial.println("mqtt failed too many times, restarting wifi"); setup_wifi(); } } } else { client.loop(); } if (millis() - led_time > led_timeout) { digitalWrite(LED_PIN, 0); } ArduinoOTA.handle(); }