From ee3a392d5a01dc02ed0764f69f0576c44f2e3f35 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 21 Jun 2025 13:42:18 -0600 Subject: [PATCH] Receive power value from MQTT and set output --- firmware/firmware.ino | 176 +++++++++++++++++++++++++++++++++++++ firmware/secrets.h.example | 2 + 2 files changed, 178 insertions(+) create mode 100644 firmware/firmware.ino create mode 100644 firmware/secrets.h.example diff --git a/firmware/firmware.ino b/firmware/firmware.ino new file mode 100644 index 0000000..69030bd --- /dev/null +++ b/firmware/firmware.ino @@ -0,0 +1,176 @@ +// Board: Wemos D1 Mini + +#include +#include +#include +#include // v2.2.9 + +#include "secrets.h" + +WiFiClient wc; +MqttClient mqttClient(wc); +ESP8266WebServer server(80); + +#define OUTPUT_PIN 4 + + +const char broker[] = "192.168.69.106"; +int port = 1883; +const char topic[] = "iot/airmega/speed"; +#define QOS_2 2 + +void (* resetFunc) (void) = 0; + +void setup() { + pinMode(OUTPUT_PIN, OUTPUT); + digitalWrite(OUTPUT_PIN, LOW); + analogWriteFreq(120); + + Serial.begin(115200); + Serial.println(""); + Serial.println(""); + Serial.println("===== BOOT UP ====="); + + static int error_count = 0; + + WiFi.hostname("airmega"); + WiFi.mode(WIFI_STA); + WiFi.begin(SECRET_SSID, SECRET_PASS); + + Serial.print("[WIFI] Attempting to connect to wifi"); + while (WiFi.status() != WL_CONNECTED) { + error_count += 1; + delay(500); + Serial.print("."); + + if (error_count > 20) { + Serial.println(""); + Serial.println("[WIFI] Unable to connect, resetting..."); + resetFunc(); + } + } + + Serial.println(""); + Serial.println("[WIFI] Connected to the network"); + Serial.println(); + + Serial.print("[WIFI] Connected to: "); + Serial.print(SECRET_SSID); + Serial.print(", IP address: "); + Serial.println(WiFi.localIP()); + + // Synchronize time using NTP. This is necessary to verify that + // the TLS certificates offered by the server are currently valid. + Serial.print("[TIME] Setting time using NTP"); + configTime(8 * 3600, 0, "pool.ntp.org", "time.nist.gov"); + time_t now = time(nullptr); + while (now < 8 * 3600 * 2) { + delay(500); + Serial.print("."); + now = time(nullptr); + } + Serial.println(); + struct tm timeinfo; + gmtime_r(&now, &timeinfo); + Serial.print("[TIME] Current time: "); + Serial.print(asctime(&timeinfo)); + Serial.println(" UTC"); + + server.on("/", []() { + server.send(200, "text/html", "SEE YOU STEEL COWBOY..."); + }); + + ElegantOTA.begin(&server); // Start ElegantOTA + server.begin(); + Serial.println("[HTTP] server started"); + + mqttClient.setId("airmega"); + + Serial.print("[MQTT] Attempting to connect to the MQTT broker: "); + Serial.println(broker); + + if (!mqttClient.connect(broker, port)) { + Serial.print("MQTT connection failed! Error code = "); + Serial.println(mqttClient.connectError()); + Serial.println("Reseting..."); + resetFunc(); + } + + Serial.println("[MQTT] Connected to the MQTT broker."); + + mqttClient.onMessage(onMqttMessage); + + Serial.print("[MQTT] Subscribing to topic: "); + Serial.println(topic); + + mqttClient.subscribe(topic, QOS_2); + + Serial.println("[MQTT] Waiting for messages."); +} + +void loop() { + static int error_count = 0; + + if (WiFi.status() != WL_CONNECTED) { + error_count += 1; + Serial.println("[WIFI] Lost connection. Reconnecting..."); + WiFi.begin(SECRET_SSID, SECRET_PASS); + delay(5000); + } else if (!mqttClient.connected()) { + error_count += 1; + Serial.print("[MQTT] Not connected! Error code = "); + Serial.println(mqttClient.connectError()); + Serial.println("[MQTT] Reconnecting..."); + mqttClient.connect(broker, port); + delay(5000); + + Serial.print("[MQTT] Subscribing to topic: "); + Serial.println(topic); + mqttClient.subscribe(topic, QOS_2); + } else { + error_count = 0; + mqttClient.poll(); + } + + if (error_count > 10) { + Serial.println("Over 10 errors, resetting..."); + resetFunc(); + } + + server.handleClient(); + +} + +void onMqttMessage(int messageSize) { + String msgTopic = mqttClient.messageTopic(); + Serial.print("[MQTT] Received a message with topic '"); + Serial.print(msgTopic); + Serial.print("', length "); + Serial.print(messageSize); + Serial.println(" bytes:"); + + String message = ""; + + while (mqttClient.available()) { + message += (char)mqttClient.read(); + } + + Serial.println(message); + + if (msgTopic != topic) { + Serial.println("[MQTT] Invalid topic, returning."); + return; + } + + int64_t num = message.toInt(); + processControlCommand(num); +} + +void processControlCommand(int64_t num) { + static int64_t prev_num = 0; + + Serial.print("[MEGA] Setting power: "); + Serial.println(num); + + analogWrite(OUTPUT_PIN, num); +} diff --git a/firmware/secrets.h.example b/firmware/secrets.h.example new file mode 100644 index 0000000..0c9fdd5 --- /dev/null +++ b/firmware/secrets.h.example @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS ""