esp8266-remote-timer

ESP8266 based timer w/ remote control and NTP sync
Index Commits Files Refs README LICENSE
commit c2490d54146ecacd0c43735afda40ec0d7294ceb
parent 8db169c80be64a7b022e79da3d960ac30d19d187
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Tue,  1 Apr 2025 23:20:50 -0300

move `setup` and `loop` to bottom and rearrange functions

Diffstat:
Msrc/main.cpp | 234++++++++++++++++++++++++++++++++++++-------------------------------------------
1 file changed, 107 insertions(+), 127 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
@@ -7,8 +7,8 @@
 #include <time.h>
 #include <coredecls.h> // settimeofday_cb() callback
 
-#define REMOTE_LED_PIN LED_BUILTIN
-#define MAIN_OUTPUT_PIN 5
+#define REMOTE_LED_PIN        LED_BUILTIN
+#define MAIN_OUTPUT_PIN       5
 #define MAIN_SWITCH_INPUT_PIN 4
 
 #define WIFI_SSID "hello-world"
@@ -18,7 +18,14 @@
 #define MY_NTP_SERVER "pool.ntp.org"
 #define MY_TZ "<-03>3"
 
-#define MAIN_SWITCH_REPEAT_TIME 200
+#define MAIN_SWITCH_REPEAT_TIME 500
+
+typedef enum {
+    MAIN_OUTPUT_STATUS = 0,
+    MAIN_OUTPUT_TOGGLE,
+    TIMER_TOGGLE,
+    TIMER_SET_VALUES
+} query_t;
 
 typedef struct {
     uint8_t from_hour, from_minute;
@@ -31,23 +38,21 @@ JSONVar data, timer_data;
 timer_values_t timer_values;
 
 time_t system_time, last_ntp_sync;
-tm tm;
 uint8_t remote_devices = 0, timer_enabled = 0, main_output_enabled = 0;
-
-void webp_socket_event(uint8_t, WStype_t, uint8_t *, size_t);
-void webp_handler();
-
-void main_output_toggle();
-void update_all_socket_clients();
+uint32_t t = 0, system_time_dt = 0, main_output_dt = 0, timer_dt = 0;
 
 void setup_wifi();
 void setup_websocket();
 void setup_webserver();
 void setup_mdns();
 void setup_fs();
+
 void update_timer_values(const timer_values_t);
 void update_timer_data();
 void update_all_clients_checkbox();
+void update_all_socket_clients();
+
+void websocket_event_handler(uint8_t, WStype_t, uint8_t *, size_t);
 
 void save_timer_values_to_file() {
     const char* file_path = "timer_values.json";
@@ -60,7 +65,6 @@ void save_timer_values_to_file() {
 
     update_timer_data();
     if (file.print(JSON.stringify(timer_data).c_str())) {
-        Serial.printf("[LITTLEFS] writing `%s` to file\n", JSON.stringify(timer_data).c_str());
         Serial.println("[LITTLEFS] Timer values saved");
     } else {
         Serial.println("[LITTLEFS] Timer values write failed");
@@ -84,10 +88,7 @@ void read_timer_values_from_file() {
     String timer_values_json = file.readString();
     file.close();
 
-    Serial.printf("[LITTLEFS] Read `%s` from %s\n", timer_values_json.c_str(), file_path);
-
     JSONVar timer_values = JSON.parse(timer_values_json.c_str());
-
     if(JSON.typeof(timer_values) == "undefined") {
         Serial.println("[SOCKET] Parsing file `timer-values.json` failed");
         return;
@@ -111,6 +112,8 @@ void read_timer_values_from_file() {
 }
 
 void show_time(bool from_sntp = false) {
+    tm tm;
+
     time(&system_time);              // read the current time
     localtime_r(&system_time, &tm);  // update the structure tm with the current time
 
@@ -136,43 +139,10 @@ uint32_t sntp_update_delay_MS_rfc_not_less_than_15000 () {
     return 8 * 60 * 60 * 1000UL; // 8*60 mins
 }
 
-void setup() {
-    pinMode(REMOTE_LED_PIN, OUTPUT);
-    pinMode(MAIN_OUTPUT_PIN, OUTPUT);
-    pinMode(MAIN_SWITCH_INPUT_PIN, INPUT);
-
-    digitalWrite(REMOTE_LED_PIN, HIGH); // led builtin uses inverted logic
-    digitalWrite(MAIN_OUTPUT_PIN, LOW);
-
-    Serial.begin(115200);
-    Serial.setDebugOutput(false);
-    Serial.printf("\n\n\n");
-    delay(1000);
-
-    Serial.printf("[SETUP] Booting");
-    for(uint8_t t = 10; t > 0; t--) {
-        Serial.print(".");
-        Serial.flush();
-        delay(150);
-    }
-    Serial.print("\n");
-
-    setup_wifi();
-    setup_fs();
-    setup_websocket();
-    setup_mdns();
-    setup_webserver();
-    configTime(MY_TZ, MY_NTP_SERVER); // Here is the IMPORTANT ONE LINER needed in your sketch!
-    settimeofday_cb(show_time);       // ntp update callback
-    show_time();
-    read_timer_values_from_file();
-}
-
-uint32_t t = 0, timer_dt = 0, clock_dt = 0, main_output_dt = 0;
-
 void update_timer_output() {
-    // check timer output every minute
-    if((t - clock_dt) > 60*1000) {
+    // check timer output every 10 seconds
+    if((t - timer_dt) > 10*1000) {
+        tm tm;
         localtime_r(&system_time, &tm);  // update the structure tm with the current time
         if((timer_enabled) && (!main_output_enabled)) {
             if((tm.tm_hour >= timer_values.from_hour)
@@ -193,67 +163,6 @@ void update_timer_output() {
     }
 }
 
-void loop() {
-    t = millis();
-
-    if((t - main_output_dt) > MAIN_SWITCH_REPEAT_TIME) {
-        if(digitalRead(MAIN_SWITCH_INPUT_PIN)) {
-            main_output_dt = millis();
-            main_output_toggle();
-            update_all_clients_checkbox();
-        }
-    }
-
-    MDNS.update();
-    web_socket.loop();
-    server.handleClient();
-
-    // update `system_time` every 5s
-    if((t - clock_dt) > 5000){
-        clock_dt = millis();
-        time(&system_time); // read the current time
-    }
-
-    update_timer_output();
-}
-
-void setup_wifi() {
-    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
-
-    Serial.printf("[SETUP] Connecting to WiFi");
-    while(WiFi.status() != WL_CONNECTED) {
-        delay(200);
-        Serial.print(".");
-    }
-    Serial.printf("\n[SETUP] Connected to '%s' IP address ", WIFI_SSID);
-    Serial.println(WiFi.localIP());
-}
-
-void setup_mdns() {
-    if (!MDNS.begin(MDNS_DOMAIN)) {
-        Serial.println("[SETUP] Error setting up MDNS responder!");
-        while(1) { delay(100); }
-    }
-
-    MDNS.addService("http", "tcp", 80);
-    Serial.printf("[SETUP] mDNS started domain '%s.local'\n", MDNS_DOMAIN);
-}
-
-void main_output_toggle() {
-    if(main_output_enabled) {
-        // GPOC = (1 << MAIN_OUTPUT_PIN); // low
-        digitalWrite(MAIN_OUTPUT_PIN, LOW);
-    } else {
-        // GPOS = (1 << MAIN_OUTPUT_PIN);  // high
-        digitalWrite(MAIN_OUTPUT_PIN, HIGH);
-    }
-    main_output_enabled = !main_output_enabled;
-}
-
-void timer_toggle() {
-    timer_enabled = !timer_enabled;
-}
-
 void clear_data() {
     JSONVar keys = data.keys();
     for (int i = 0; i < keys.length(); i++) {
@@ -316,14 +225,7 @@ void update_timer_values(const timer_values_t new_values) {
             timer_values.to_hour, timer_values.to_minute);
 }
 
-typedef enum {
-    MAIN_OUTPUT_STATUS = 0,
-    MAIN_OUTPUT_TOGGLE,
-    TIMER_TOGGLE,
-    TIMER_SET_VALUES
-} query_t;
-
-void webp_socket_event(uint8_t num, WStype_t type, uint8_t *payload, size_t len) {
+void websocket_event_handler(uint8_t num, WStype_t type, uint8_t *payload, size_t len) {
     switch(type) {
     case WStype_DISCONNECTED:
         Serial.printf("[SOCKET] %d: Disconnected\n", num);
@@ -343,11 +245,11 @@ void webp_socket_event(uint8_t num, WStype_t type, uint8_t *payload, size_t len)
 
             switch(query_type) {
             case MAIN_OUTPUT_TOGGLE:
-                main_output_toggle();
+                digitalWrite(MAIN_OUTPUT_PIN, main_output_enabled ^= 1);
                 update_all_clients_checkbox();
                 break;
             case TIMER_TOGGLE:
-                timer_toggle();
+                timer_enabled = !timer_enabled;
                 update_all_clients_checkbox();
                 break;
             case TIMER_SET_VALUES: {
@@ -385,16 +287,10 @@ void webp_socket_event(uint8_t num, WStype_t type, uint8_t *payload, size_t len)
     case WStype_BIN:
         Serial.printf("[SOCKET][%u] get binary length: %u\n", num, len);
         hexdump(payload, len);
-        // web_socket.sendBIN(num, payload, len);
         break;
     }
 }
 
-void setup_websocket() {
-    web_socket.begin();
-    web_socket.onEvent(webp_socket_event);
-}
-
 int webserver_get_file(String path, String &return_page) {
     if(LittleFS.exists(path)) {
         Serial.printf("[SERVER] Serving file '%s'\n", path.c_str());
@@ -447,6 +343,33 @@ void webserver_handle_root() {
     server.send(response_code, "text/html", index_page.c_str());
 }
 
+void setup_wifi() {
+    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
+
+    Serial.printf("[SETUP] Connecting to WiFi");
+    while(WiFi.status() != WL_CONNECTED) {
+        delay(200);
+        Serial.print(".");
+    }
+    Serial.printf("\n[SETUP] Connected to '%s' IP address ", WIFI_SSID);
+    Serial.println(WiFi.localIP());
+}
+
+void setup_mdns() {
+    if (!MDNS.begin(MDNS_DOMAIN)) {
+        Serial.println("[SETUP] Error setting up MDNS responder!");
+        while(1) { delay(100); }
+    }
+
+    MDNS.addService("http", "tcp", 80);
+    Serial.printf("[SETUP] mDNS started domain '%s.local'\n", MDNS_DOMAIN);
+}
+
+void setup_websocket() {
+    web_socket.begin();
+    web_socket.onEvent(websocket_event_handler);
+}
+
 void setup_webserver() {
     Serial.println("[SETUP] loading server response from file 'index.html'");
 
@@ -467,3 +390,60 @@ void setup_fs() {
     uint8_t percentage_usad = (fs_info.usedBytes/fs_info.totalBytes)*100;
     Serial.printf("[SETUP] LittleFS started: spaced used %d%%\n", percentage_usad);
 }
+
+void setup() {
+    pinMode(REMOTE_LED_PIN, OUTPUT);
+    pinMode(MAIN_OUTPUT_PIN, OUTPUT);
+    pinMode(MAIN_SWITCH_INPUT_PIN, INPUT);
+
+    digitalWrite(REMOTE_LED_PIN, HIGH); // led builtin uses inverted logic
+    digitalWrite(MAIN_OUTPUT_PIN, LOW);
+
+    Serial.begin(115200);
+    Serial.setDebugOutput(false);
+    Serial.printf("\n\n\n");
+    delay(1000);
+
+    Serial.printf("[SETUP] Booting");
+    for(uint8_t i = 10; i > 0; i--) {
+        Serial.print(".");
+        Serial.flush();
+        delay(150);
+    }
+    Serial.print("\n");
+
+    setup_wifi();
+    setup_fs();
+    setup_websocket();
+    setup_mdns();
+    setup_webserver();
+
+    configTime(MY_TZ, MY_NTP_SERVER); // configure builtin ntp!
+    settimeofday_cb(show_time);       // ntp update callback
+
+    show_time();
+    read_timer_values_from_file();
+}
+
+void loop() {
+    t = millis();
+
+    if((t - main_output_dt) > MAIN_SWITCH_REPEAT_TIME) {
+        if(digitalRead(MAIN_SWITCH_INPUT_PIN)) {
+            main_output_dt = millis();
+            digitalWrite(MAIN_OUTPUT_PIN, main_output_enabled ^= 1);
+            update_all_clients_checkbox();
+        }
+    }
+
+    // update `system_time` every 5s
+    if((t - system_time_dt) > 5000){
+        system_time_dt = millis();
+        time(&system_time); // read the current time
+    }
+
+    update_timer_output();
+    MDNS.update();
+    web_socket.loop();
+    server.handleClient();
+}