Created
October 19, 2024 20:57
-
-
Save ivesdebruycker/73beddf6964e9e6a3553975f35f1b0e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file main.cpp | |
* @brief ESP8266 MQTT Relay Controller | |
* | |
* This file contains the implementation of an ESP8266-based relay controller | |
* that connects to a WiFi network and communicates with an MQTT broker. | |
* | |
* The controller subscribes to various MQTT topics to control four relays and | |
* a master switch. It also supports firmware updates via MQTT. | |
* | |
* @details | |
* - To install the ESP8266 board, (using Arduino 1.6.4+): | |
* - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs": | |
* http://arduino.esp8266.com/stable/package_esp8266com_index.json | |
* - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266 | |
* - Select your ESP8266 in "Tools -> Board" | |
* | |
* @author Ives | |
* | |
* @section Dependencies | |
* - ESP8266WiFi.h | |
* - PubSubClient.h | |
* - firmware_update.h | |
* | |
* @section Configuration | |
* - WiFi SSID and password | |
* - MQTT server IP address | |
* | |
* @section Pins | |
* - RELAY1: D7 | |
* - RELAY2: D6 | |
* - RELAY3: D5 | |
* - RELAY4: D0 | |
* | |
* @section Functions | |
* - setup_wifi(): Connects to the WiFi network. | |
* - logToMQTT(char *msg): Logs messages to the MQTT broker. | |
* - callback(char *topic, byte *payload, unsigned int length): Handles incoming MQTT messages. | |
* - reconnect(): Reconnects to the MQTT broker if the connection is lost. | |
* - setup(): Initializes the hardware and connects to WiFi and MQTT broker. | |
* - loop(): Main loop that maintains the MQTT connection and handles relay control. | |
* | |
* @section MQTT Topics | |
* - cv-relay/relay1: Control relay 1 | |
* - cv-relay/relay2: Control relay 2 | |
* - cv-relay/relay3: Control relay 3 | |
* - cv-relay/relay4: Control relay 4 | |
* - cv-relay/master: Enable/disable master control | |
* - cv-relay/update: Trigger firmware update | |
* - cv-relay/logs: Log messages | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <PubSubClient.h> | |
#include "firmware_update.h" | |
const char *ssid = "*******"; | |
const char *password = "*******"; | |
const char *mqtt_server = "192.168.1.1"; | |
const int RELAY1 = D7; | |
const int RELAY2 = D6; | |
const int RELAY3 = D5; | |
const int RELAY4 = D0; | |
WiFiClient espClient; | |
PubSubClient client(espClient); | |
unsigned long lastMsg = 0; | |
int value = 0; | |
bool master = true; | |
void setup_wifi() | |
{ | |
delay(10); | |
Serial.println(); | |
Serial.print("Connecting to "); | |
Serial.println(ssid); | |
// connect to wifi | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
void logToMQTT(char *msg) | |
{ | |
Serial.println(msg); | |
client.publish("cv-relay/logs", msg); | |
} | |
void callback(char *topic, byte *payload, unsigned int length) | |
{ | |
unsigned long now = millis(); | |
lastMsg = now; | |
digitalWrite(LED_BUILTIN, LOW); | |
Serial.print("Message arrived ["); | |
Serial.print(topic); | |
Serial.print("] "); | |
// check if the topic is one of cv-relay/relay1 to cv-relay/relay4 | |
if (strcmp(topic, "cv-relay/relay1") == 0) | |
{ | |
if ((char)payload[0] == '1' && master) | |
{ | |
digitalWrite(RELAY1, HIGH); | |
logToMQTT("RELAY1 ON"); | |
} | |
else | |
{ | |
digitalWrite(RELAY1, LOW); | |
logToMQTT("RELAY1 OFF"); | |
} | |
} | |
else if (strcmp(topic, "cv-relay/relay2") == 0) | |
{ | |
if ((char)payload[0] == '1' && master) | |
{ | |
digitalWrite(RELAY2, HIGH); | |
logToMQTT("RELAY2 ON"); | |
} | |
else | |
{ | |
digitalWrite(RELAY2, LOW); | |
logToMQTT("RELAY2 OFF"); | |
} | |
} | |
else if (strcmp(topic, "cv-relay/relay3") == 0) | |
{ | |
if ((char)payload[0] == '1' && master) | |
{ | |
digitalWrite(RELAY3, HIGH); | |
logToMQTT("RELAY3 ON"); | |
} | |
else | |
{ | |
digitalWrite(RELAY3, LOW); | |
logToMQTT("RELAY3 OFF"); | |
} | |
} | |
else if (strcmp(topic, "cv-relay/relay4") == 0) | |
{ | |
if ((char)payload[0] == '1' && master) | |
{ | |
digitalWrite(RELAY4, HIGH); | |
logToMQTT("RELAY4 ON"); | |
} | |
else | |
{ | |
digitalWrite(RELAY4, LOW); | |
logToMQTT("RELAY4 OFF"); | |
} | |
} | |
else if (strcmp(topic, "cv-relay/master") == 0) | |
{ | |
if ((char)payload[0] == '1') | |
{ | |
master = true; | |
logToMQTT("Master on"); | |
} | |
else | |
{ | |
logToMQTT("Master off"); | |
digitalWrite(RELAY1, LOW); | |
digitalWrite(RELAY2, LOW); | |
digitalWrite(RELAY3, LOW); | |
digitalWrite(RELAY4, LOW); | |
master = false; | |
} | |
} | |
else if (strcmp(topic, "cv-relay/update") == 0) | |
{ | |
if ((char)payload[0] == '1') | |
{ | |
Serial.print("Update firmware ("); | |
Serial.println(now); | |
Serial.println(")"); | |
int res = doFirmwareUpdate(logToMQTT); | |
} | |
} | |
} | |
void reconnect() | |
{ | |
// Loop until we're reconnected | |
while (!client.connected()) | |
{ | |
Serial.print("Attempting MQTT connection..."); | |
// Create a random client ID | |
String clientId = "cv-relay-ESP8266-"; | |
clientId += String(random(0xffff), HEX); | |
// Attempt to connect | |
if (client.connect(clientId.c_str())) | |
{ | |
Serial.println("connected"); | |
// Once connected, publish an announcement... | |
logToMQTT("hello world"); | |
// ... and subscribe to wildcard topic | |
client.subscribe("cv-relay/#"); | |
} | |
else | |
{ | |
Serial.print("failed, rc="); | |
Serial.print(client.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
void setup() | |
{ | |
pinMode(LED_BUILTIN, OUTPUT); // Initialize the BUILTIN_LED pin as an output | |
pinMode(RELAY1, OUTPUT); | |
pinMode(RELAY2, OUTPUT); | |
pinMode(RELAY3, OUTPUT); | |
pinMode(RELAY4, OUTPUT); | |
Serial.begin(115200); | |
setup_wifi(); | |
client.setServer(mqtt_server, 1883); | |
client.setCallback(callback); | |
} | |
void loop() | |
{ | |
if (!client.connected()) | |
{ | |
reconnect(); | |
} | |
client.loop(); | |
// keep led on for 2 seconds after last message | |
unsigned long now = millis(); | |
if (now - lastMsg > 2000) | |
{ | |
digitalWrite(LED_BUILTIN, HIGH); | |
} | |
delay(1000); // Wait for 1 second | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment