esp01s-serial-remote-controller

Serial communication from ESP-01S served webpage
Index Commits Files Refs README LICENSE
commit 1eee37beb9e2f05b84d59c0a8bf93fe989e9e17f
parent eccbcb8a5ed2d4f07254132a6fcebaad8ac95ea4
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Sat, 11 Apr 2026 21:43:40 -0300

Add tmeperature controls

Diffstat:
Mdata/index.html | 98++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Mdata/main.js | 35+++++++++++++++++++++++++++++++++--
Mdata/style.css | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mplatformio.ini | 4++++
Msrc/main.cpp | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
5 files changed, 281 insertions(+), 67 deletions(-)
diff --git a/data/index.html b/data/index.html
@@ -1,47 +1,79 @@
 <!DOCTYPE html>
 <html>
     <head>
-        <title>ESP8266 Web Server</title>
+        <title>Derretidor de miel</title>
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <meta charset="UTF-8">
         <link rel="icon" href="data:,">
         <link rel="stylesheet" type="text/css" href="style.css">
         <script type="text/javascript" src="main.js"></script>
     </head>
     <body>
         <div id="main-div">
-            <h1 id="title">ESP8266 Remote Panel</h1>
+            <h1 id="title">Derretidor de miel</h1>
             <div id="buttons-div">
-                <div id="main-toggle-div" onclick="handle_click('main-toggle')">
-                    <table>
-                        <tr style="vertical-align: bottom;">
-                            <td>
-                                Main output enabled
-                            </td>
-                            <td id="main-checkbox-td">
-                                <div id="main-checkbox" checked="">
-                                    <svg id="checkmark-svg"
-                                     version="1.0"
-                                     xmlns="http://www.w3.org/2000/svg"
-                                     viewBox="0 0 64.000000 64.000000"
-                                     preserveAspectRatio="xMidYMid meet">
-                                        <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)"
-                                        fill="currentColor" stroke="currentColor">
-                                        <path d="M380 419 l-142 -211 -67 66 c-38 38 -75 66 -87 66 -25 0 -84 -60 -84
-                                        -86 0 -11 45 -65 113 -132 121 -121 145 -132 184 -89 49 54 343 502 343 523 0
-                                        27 -62 74 -96 74 -16 0 -53 -48 -164 -211z"/>
-                                        </g>
-                                    </svg>
-                                </div>
-                            </td>
-                        </tr>
-                    </table>
+                <div id="main">
+                    <div id="main-toggle" onclick="handle_click('main-toggle')">
+                        <table>
+                            <tr style="vertical-align: bottom;">
+                                <td>
+                                    Calefactor activo
+                                </td>
+                                <td id="main-checkbox-td">
+                                    <div id="main-checkbox" checked="">
+                                        <svg id="checkmark-svg"
+                                         version="1.0"
+                                         xmlns="http://www.w3.org/2000/svg"
+                                         viewBox="0 0 64.000000 64.000000"
+                                         preserveAspectRatio="xMidYMid meet">
+                                            <g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)"
+                                            fill="currentColor" stroke="currentColor">
+                                            <path d="M380 419 l-142 -211 -67 66 c-38 38 -75 66 -87 66 -25 0 -84 -60 -84
+                                            -86 0 -11 45 -65 113 -132 121 -121 145 -132 184 -89 49 54 343 502 343 523 0
+                                            27 -62 74 -96 74 -16 0 -53 -48 -164 -211z"/>
+                                            </g>
+                                        </svg>
+                                    </div>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div id="main-sep"></div>
+                    <div id="main-now">
+                        <table>
+                            <tr style="vertical-align: bottom;">
+                                <td>
+                                    Temperatura actual
+                                </td>
+                                <td id=main-now-value>
+                                    0
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div id="main-set">
+                        <table>
+                            <tr style="vertical-align: bottom;">
+                                <td>
+                                    Temperatura establecida
+                                </td>
+                                <td>
+                                    <input id="main-set-value" type="number"
+                                    value="25" min=0 max="80"/>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div id="main-save-div">
+                        <input type="button" value="Aplicar" id="main-save">
+                    </div>
                 </div>
                 <div id="timer">
                     <div id="timer-enable" onclick="handle_click('timer-toggle')">
                         <table>
                             <tr>
                                 <td>
-                                    Timer enabled
+                                    Timer activo
                                 </td>
                                 <td id="timer-checkbox-td">
                                     <div id="timer-checkbox" checked="">
@@ -67,7 +99,7 @@
                         <table>
                             <tr>
                                 <td>
-                                    From
+                                    Desde
                                 </td>
                                 <td>
                                     <input id="from-time" type="time" value="18:00"/>
@@ -75,7 +107,7 @@
                             </tr>
                             <tr>
                                 <td>
-                                    Until
+                                    Hasta
                                 </td>
                                 <td>
                                     <input id="to-time" type="time" value="00:00"/>
@@ -84,7 +116,7 @@
                         </table>
                     </div>
                     <div id="timer-save-div">
-                        <input type="button" value="Save" id="timer-save">
+                        <input type="button" value="Aplicar" id="timer-save">
                     </div>
                 </div>
             </div>
@@ -101,7 +133,7 @@
                     </tr>
                     <tr>
                         <td>
-                            WiFi Strength
+                            WiFi RSSI
                         </td>
                         <td>
                             <div id="wifi-rssi"></div>
@@ -109,7 +141,7 @@
                     </tr>
                     <tr>
                         <td>
-                            Local IP address
+                            Direccion IP local
                         </td>
                         <td>
                             <a id="system-ip-addr"></a>
@@ -117,7 +149,7 @@
                     </tr>
                     <tr>
                         <td>
-                            System time
+                            Reloj del sistema
                         </td>
                         <td>
                             <div id="system-time"></div>
diff --git a/data/main.js b/data/main.js
@@ -2,7 +2,8 @@ var received_data;
 var main_checkbox, timer_checkbox;
 var time_div, system_ip_addr, wifi_ssid, wifi_rssi;
 var system_time, system_time_elem;
-var to_time, from_time, timer_save_button;
+var to_time, from_time, temp_now, temp_set_value;
+var temp_save_button, timer_save_button;
 
 const time_formatter = new Intl.DateTimeFormat('en-GB', {
     timeZone: 'America/Argentina/Buenos_Aires',
@@ -18,7 +19,8 @@ const query_types = {
     "QUERY_STATUS":             0,
     "QUERY_MAIN_OUTPUT_TOGGLE": 1,
     "QUERY_TIMER_TOGGLE":       2,
-    "QUERY_TIMER_SET_VALUES":   3
+    "QUERY_TIMER_SET_VALUES":   3,
+    "QUERY_TEMP_SET":           4
 }
 
 function rssi_to_percentage(rssi) {
@@ -46,6 +48,15 @@ function update_time() {
         .replaceAll(",", "") + " GMT-3";
 }
 
+function update_now_temp() {
+    temp_now.textContent = received_data["temp-now"] + "°C";
+}
+
+function update_temp() {
+    temp_now.textContent = received_data["temp-now"] + "°C";
+    temp_set_value.value = received_data["temp-set"];
+}
+
 function update_timer() {
     from_time.value = received_data["timer"]["from"]["hour"] + ":"
         + received_data["timer"]["from"]["minute"];
@@ -57,6 +68,7 @@ function update_all() {
     update_checkbox();
     update_time();
     update_timer();
+    update_temp();
 
     system_ip_addr.href = received_data["system-ip-addr"];
     system_ip_addr.innerHTML = received_data["system-ip-addr"];
@@ -83,6 +95,12 @@ function socket_onmessage_handler(event) {
         case "timer":
             update_timer();
             break;
+        case "temp-values":
+            update_temp();
+            break;
+        case "temp-now-values":
+            update_now_temp();
+            break;
         default:
             console.log("[SOCKET] received_data: type not known, updating all...");
             update_all();
@@ -122,6 +140,14 @@ function timer_set_time() {
     socket.send(query_types["QUERY_TIMER_SET_VALUES"] + JSON.stringify(query_json));
 }
 
+function temp_set() {
+    var query_json = new Object();
+
+    query_json.temp_set_point_new = temp_set_value.value.slice(0, 2);
+    socket.send(query_types["QUERY_TEMP_SET"] + JSON.stringify(query_json));
+}
+
+
 function query_data() {
     main_checkbox = document.getElementById("main-checkbox");
     timer_checkbox = document.getElementById("timer-checkbox");
@@ -133,6 +159,11 @@ function query_data() {
     from_time = document.getElementById("from-time");
     to_time = document.getElementById("to-time");
 
+    temp_now = document.getElementById("main-now-value");
+    temp_set_value = document.getElementById("main-set-value");
+    temp_save_button = document.getElementById("main-save");
+    temp_save_button.addEventListener( "click", temp_set, false);
+
     timer_save_button = document.getElementById("timer-save");
     timer_save_button.addEventListener( "click", timer_set_time, false);
 
diff --git a/data/style.css b/data/style.css
@@ -36,22 +36,58 @@ h1 {
     font-size: 36px;
 }
 
-#main-toggle-div {
+#main {
+    /*
     margin-bottom: 0.5em;
     cursor: pointer;
     padding: 1.25em 28px 1.00em 28px;
     border-radius: 8px;
     border: 1px solid #E3E3E3;
+    */
 }
 
-#timer {
+#main, #timer {
     border-radius: 8px;
     border: 1px solid #E3E3E3;
 }
 
+#timer {
+    margin-top: 1em;
+}
+
+#main-set,
+#main-toggle,
 #timer-enable {
     cursor: pointer;
-    padding: 27.5px 28px 16px 28px;
+}
+
+#main-now,
+#main-set {
+    font-size: 20px;
+}
+
+#main-now-value {
+    font-family: monospace;
+}
+
+#timer-enable {
+    padding: 28px 28px 12px 28px;
+}
+
+#main-toggle {
+    padding: 28px 28px 12px 28px;
+}
+
+#main-now {
+    padding: 18px 28px 2px 28px;
+}
+
+#main-sep {
+    padding: 0px 28px 0px 28px;
+}
+
+#main-set {
+    padding: 0px 28px 0px 28px;
 }
 
 #timer-picker {
@@ -59,7 +95,7 @@ h1 {
     font-size: 20px;
 }
 
-#timer-sep {
+#timer-sep, #main-sep {
     border-bottom: 1px solid #E3E3E3;
     margin: 0 30px 0 30px;
 }
@@ -74,12 +110,12 @@ h1 {
     background-color: white;
 }
 
-#timer-save-div {
+#timer-save-div, #main-save-div {
     padding: 18px 30px 30px 30px;
     text-align: center;
 }
 
-#timer-save {
+#timer-save, #main-save {
     margin-right: 0px;
     box-shadow: none;
     border: 1px solid #E3E3E3;
@@ -88,28 +124,54 @@ h1 {
     border-radius: 5px;
     cursor: pointer;
     height: 32px;
-    font-size: 14px;
+    font-size: 16px;
     width: 100%;
-    font-weight: bold;
+    font-weight: normal;
 }
 
-#timer-save:active {
+#timer-save:active, #main-save:active {
   background-color: #E3E3E3;
   border: none;
 }
 
+#main-set-value {
+    font-size: 18px;
+    font-weight: normal;
+    font-family: monospace;
+    width: 50px;
+    border: 1px solid #E3E3E3;
+    border-radius: 5px;
+    padding: 2px;
+    font-size: 18px;
+    height: 22px;
+
+    /*
+    margin: 0px;
+    border: 1px solid #E3E3E3;
+    cursor: pointer;
+
+    margin-right: 0px;
+    box-shadow: none;
+    background-color: white;
+    border-radius: 5px;
+    cursor: pointer;
+    */
+}
+
 @media (hover: hover) and (pointer: fine) {
-    #main-toggle-div:hover #main-checkbox,
+    #main-toggle:hover #main-checkbox,
     #timer-enable:hover #timer-checkbox,
     #from-time:hover, #to-time:hover,
     #main-checkbox:hover, #timer-checkbox:hover,
-    #timer-save:hover {
+    #main-set-value:hover,
+    #timer-save:hover, #main-save:hover {
         border: 1px solid #999999;
     }
 }
 
 #from-time:focus-visible,
-#to-time:focus-visible {
+#to-time:focus-visible,
+#main-set-value:focus-visible {
     border: 1px solid #999999;
     outline: none;
 }
@@ -206,28 +268,28 @@ h1 {
         border: none;
     }
 
-    #main-toggle-div, #timer {
+    #main, #timer {
         background-color: #232326;
         border: none;
     }
 
-    #timer-sep {
+    #timer-sep, #main-sep {
         border-bottom-color: #3E3E42;
     }
 
-    #timer-save {
+    #timer-save, #main-save {
         border-color: #999999;
         color: white;
         background-color: #303033;
         border-color: #3E3E42;
     }
 
-    #timer-save:active {
+    #timer-save:active, #main-save:active {
         background-color: #3E3E42;
         border: none;
     }
 
-    #from-time, #to-time {
+    #from-time, #to-time, #main-set-value {
         background-color: #303033;
         color: white;
         border-color: #3E3E42;
@@ -244,17 +306,18 @@ h1 {
     }
 
     @media (hover: hover) and (pointer: fine) {
-        #main-toggle-div:hover #main-checkbox,
+        #main-toggle:hover #main-checkbox,
         #timer-enable:hover #timer-checkbox,
         #from-time:hover, #to-time:hover,
         #main-checkbox:hover, #timer-checkbox:hover,
-        #timer-save:hover {
+        #timer-save:hover, #main-save:hover {
             border: 1px solid #828282;
         }
     }
 
     #from-time:focus-visible,
-    #to-time:focus-visible {
+    #to-time:focus-visible,
+    #main-set-value:focus-visible {
         border: 1px solid #828282;
     }
 }
diff --git a/platformio.ini b/platformio.ini
@@ -18,3 +18,7 @@ board_build.ldscript = eagle.flash.4m1m.ld
 
 ; Set filesystem to LittleFS
 board_build.filesystem = littlefs
+
+build_flags =
+    -D WIFI_SSID=\"${sysenv.WIFI_SSID}\"
+    -D WIFI_PASSWD=\"${sysenv.WIFI_PASSWD}\"
diff --git a/src/main.cpp b/src/main.cpp
@@ -11,10 +11,16 @@
 #endif
 
 #define REMOTE_LED_PIN 2
-#define WIFI_SSID      "abcdefgh"
-#define WIFI_PASSWD    "12345678"
 #define LOG_ENABLE     false
 
+#ifndef WIFI_SSID
+#define WIFI_SSID "abcdefgh"
+#endif
+
+#ifndef WIFI_PASSWD
+#define WIFI_PASSWD "12345678"
+#endif
+
 #if true == LOG_ENABLE
 #define LOG(fmt, ...) do {             \
         Serial.printf(fmt, ##__VA_ARGS__); \
@@ -32,20 +38,25 @@ typedef enum {
     TX_DATA_MAIN_OUTPUT_TOGGLE = 'B',
     TX_DATA_TIMER_TOGGLE       = 'C',
     TX_DATA_TIMER_SET_VALUES   = 'D',
+    TX_DATA_TEMP_STATUS        = 'E',
+    TX_DATA_TEMP_SET           = 'F'
 } uart_tx_data_e;
 
 typedef enum {
     RX_DATA_STATUS_OK             = 'A',
     RX_DATA_MAIN_OUTPUT_TOGGLE_OK = 'B',
     RX_DATA_TIMER_TOGGLE_OK       = 'C',
-    RX_DATA_TIMER_SET_VALUES_OK   = 'D'
+    RX_DATA_TIMER_SET_VALUES_OK   = 'D',
+    RX_DATA_TEMP_STATUS_OK        = 'E',
+    RX_DATA_TEMP_SET_OK           = 'F'
 } uart_rx_data_e;
 
 typedef enum {
     QUERY_STATUS = 0,
     QUERY_MAIN_OUTPUT_TOGGLE,
     QUERY_TIMER_TOGGLE,
-    QUERY_TIMER_SET_VALUES
+    QUERY_TIMER_SET_VALUES,
+    QUERY_TEMP_SET
 } query_type_e;
 
 typedef struct {
@@ -59,11 +70,11 @@ typedef struct {
 ESP8266WebServer server(80);
 WebSocketsServer web_socket = WebSocketsServer(81);
 uint8_t remote_devices, main_output_enabled;
-uint32_t t, system_time_dt;
 time_t system_time;
 timer_param_t timer, new_timer;
 JSONVar data, timer_data;
 queue_t uart_queue_tx, uart_queue_rx;
+int16_t temp_now, temp_now_new, temp_set_point, temp_set_point_new;
 
 void setup_wifi();
 void setup_websocket();
@@ -154,6 +165,34 @@ void webserver_update_all_clients_timer_values()
     web_socket.broadcastTXT(output_data_as_json.c_str());
 }
 
+void webserver_update_all_clients_temp_now_value()
+{
+    JSONVar output_data;
+    String output_data_as_json;
+
+    output_data["type"] = "temp-now-values";
+    output_data["temp-now"] = temp_now;
+
+    // web_socket.broadcastTXT(JSON.stringify(output_data).c_str());
+    output_data_as_json = JSON.stringify(output_data);
+    web_socket.broadcastTXT(output_data_as_json.c_str());
+}
+
+
+void webserver_update_all_clients_temp_values()
+{
+    JSONVar output_data;
+    String output_data_as_json;
+
+    output_data["type"] = "temp-values";
+    output_data["temp-now"] = temp_now;
+    output_data["temp-set"] = temp_set_point;
+
+    // web_socket.broadcastTXT(JSON.stringify(output_data).c_str());
+    output_data_as_json = JSON.stringify(output_data);
+    web_socket.broadcastTXT(output_data_as_json.c_str());
+}
+
 void websocket_event_handler(uint8_t num, WStype_t type, uint8_t *payload, size_t len)
 {
     IPAddress ip;
@@ -229,6 +268,16 @@ void websocket_event_handler(uint8_t num, WStype_t type, uint8_t *payload, size_
 
                 break;
 
+                case QUERY_TEMP_SET: {
+                    payload++; // skip query type
+                    JSONVar temp_data;
+                    temp_data = JSON.parse((char *)payload);
+                    temp_set_point_new = (uint8_t)String(temp_data["temp_set_point_new"]).toInt();
+                    queue_enqueue(&uart_queue_tx, TX_DATA_TEMP_SET);
+                    queue_enqueue(&uart_queue_tx, (uint8_t)temp_set_point_new);
+                }
+                break;
+
                 default:
                 break;
             }
@@ -328,6 +377,8 @@ void update_data() {
     data["wifi-rssi"]           = WiFi.RSSI();
     update_timer_data();
     data["timer"] = timer_data;
+    data["temp-now"] = temp_now;
+    data["temp-set"] = temp_set_point;
 }
 
 void uart_rx_handler(void)
@@ -341,9 +392,15 @@ void uart_rx_handler(void)
 
     uint8_t rx_data_type = queue_peek(&uart_queue_rx);
 
-    // Wait for additional data to arrive
     if ((rx_data_type == RX_DATA_STATUS_OK) && (queue_count(&uart_queue_rx) < 10))
     {
+        // Wait for additional data to arrive
+        return;
+    }
+
+    if ((rx_data_type == RX_DATA_TEMP_STATUS_OK) && (queue_count(&uart_queue_rx) < 2))
+    {
+        // Wait for additional data to arrive
         return;
     }
 
@@ -372,6 +429,9 @@ void uart_rx_handler(void)
             timer.to_hour     = queue_dequeue(&uart_queue_rx);
             timer.to_minute   = queue_dequeue(&uart_queue_rx);
 
+            temp_now       = queue_dequeue(&uart_queue_rx);
+            temp_set_point = queue_dequeue(&uart_queue_rx);
+
             update_data();
             data["type"] = "all";
 
@@ -406,7 +466,28 @@ void uart_rx_handler(void)
 
         break;
 
+        case RX_DATA_TEMP_SET_OK:
+
+            temp_set_point = temp_set_point_new;
+            webserver_update_all_clients_temp_values();
+
+        break;
+
+        case RX_DATA_TEMP_STATUS_OK:
+
+            temp_now_new = queue_dequeue(&uart_queue_rx);
+            temp_set_point = queue_dequeue(&uart_queue_rx); // discard value
+
+            if (temp_now_new != temp_now)
+            {
+                temp_now = temp_now_new;
+                webserver_update_all_clients_temp_now_value();
+            }
+
+        break;
+
         default:
+            queue_dequeue(&uart_queue_rx);
         break;
     }
 }
@@ -435,8 +516,11 @@ void setup()
     timer.to_minute = 0;
 
     main_output_enabled = 0;
-    t = 0;
-    system_time_dt = 0;
+
+    temp_now = 0;
+    temp_now_new = 0;
+    temp_set_point = 0;
+    temp_set_point_new = 0;
 
     time(&system_time); // read the current time
 
@@ -454,13 +538,13 @@ void setup()
 
 void loop()
 {
-    if (Serial.available() > 0)
+    while (Serial.available() > 0)
     {
         int16_t byte = Serial.read();
 
         if (byte >= 0)
         {
-            queue_enqueue(&uart_queue_rx, byte);
+            queue_enqueue(&uart_queue_rx, (uint8_t)byte);
         }
     }
 
@@ -469,10 +553,10 @@ void loop()
         uart_rx_handler();
     }
 
-    if (!queue_is_empty(&uart_queue_tx))
+    while (!queue_is_empty(&uart_queue_tx))
     {
         uint8_t value = queue_dequeue(&uart_queue_tx);
-        LOG_INFO("Sending byte 0x%2X...\n", value);
+        LOG_INFO("Sending byte 0x%02X...\n", value);
         Serial.write(value);
         LOG("\n");
     }