diff --git a/platformio.ini b/platformio.ini index d1f99ca..1728680 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,3 +12,4 @@ platform = espressif32 board = esp-wrover-kit framework = arduino +lib_deps = knolleary/PubSubClient@^2.8 diff --git a/src/main.cpp b/src/main.cpp index 58b344c..9c029c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,166 @@ #include +#include +#include -void setup() { - // put your setup code here, to run once: +// Set the PIN of the output LED +#define O_LED 13 + +// WiFi name +const char* ssid = "........"; +// WiFi password +const char* password = "........"; +// MQTT broker URI +const char* mqtt_broker = "........"; + +// Create a new WiFi client +WiFiClient espClient; +// Create a new MQTT client +PubSubClient client(espClient); +// Create a variable to store the incoming message +String lastMsg; +// Set the size of the message buffer (where the message is stored before it goes into the variable) +#define MSG_BUFFER_SIZE (50) +// Create an array (a list) of characters for the incomming message, the length of the array is the aforementioned buffersize +char msg[MSG_BUFFER_SIZE]; + +// Create a function to handle setting up of the WiFi +// This function is of the type "void" which means that it doesn't have a return value +void setup_wifi() { + // Wait 10 milliseconds + delay(10); + // Write a message to the serial monitor so we know that it is connection to the WiFi + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + // Set a standard WiFi mode + WiFi.mode(WIFI_STA); + // Connect to the WiFi using the given SSID (WiFi name) and password + WiFi.begin(ssid, password); + + // While the status of the WiFi is not connected + while (WiFi.status() != WL_CONNECTED) { + // Wait 500 milliseconds + delay(500); + // Wrint a "." to the serial monitor + Serial.print("."); + } + + // If the code gets to here that means you have successfully connected to the WiFi network + + // For proper pseudo-random number generation you need a different seed (base of the number generation) each time, set that here + randomSeed(micros()); + + // Print a status update to the serial monitor with the IP the EPS32 received + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); } +// Create a function for the MQTT library to run when it receives a message. +// This function takes 3 variables: +// 1. The topic the message arrived in +// 2. The payload aka the actual message content +// 3. The length of the message +// The "*" symbol at the end of the variable types means that it is an array with an undefined length +// This function is of the type "void" which means that it doesn't have a return value +void callback(char* topic, byte* payload, unsigned int length) { + // Print to the serial monitor that you have received a message and which topic it came from + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + // For each character in the message payload (content) print it to the serial monitor and add it to the variable called + for (int i = 0; i < length; i++) { + // Print the currect character in the payload to the serial monitor. + Serial.print((char)payload[i]); + // Add the current character in the payload to the message string + lastMsg += (char)payload[i]; + } + // Print an empty line to the serial monitor once the writing of the entire payload to the serial monitor has completed + Serial.println(); + + // If the first character in the payload (message) is a "1" turn the output LED on + if ((char)payload[0] == '1') { + // Write the pin that the output LED is connected to HIGH (on) + digitalWrite(O_LED, HIGH); + } else { + // Write the pin that the output LED is connected to LOW (off) + digitalWrite(O_LED, LOW); + } +} + +// Create a function to reconnect to the MQTT broker in case the connection drops +// This function is of the type "void" which means that it doesn't have a return value +void reconnect() { + // Whole the MQTT client is NOT connected + while (!client.connected()) { + // Write the current status to the serial monitor + Serial.print("Attempting MQTT connection..."); + // Create a random client ID (the name of the MQTT client) starting with "ESP32Client-" + String clientId = "ESP32Client-"; + // Add some random hex characters at the end of the client ID string + clientId += String(random(0xffff), HEX); + + // Attempt to connect to the MQTT broker + + // If the client connected successfully using the aforementioned clientID + if (client.connect(clientId.c_str())) { + // Print that you have connected to the serial monitor + Serial.println("connected"); + + // When it has connected to the MQTT broker publish a message announcing the connection + // This is not required, but is considered good practice + // The publish function takes two arguments: + // 1. The topic to which the payload should be delivered + // 2. The payload itself + client.publish("ClientAnnouncements", "Hello, world!"); + + // Subscribe to the desired topic(s) + // The subscribe function takes one argument + // 1. The topic to subscribe to + // Subscribing to a topic means the client will receieve all messages published in said topic + client.subscribe("inTopic"); + + // If the MQTT client coulld not successfully connect to the broker + } else { + // Print a status update to the serial monitor with the reason it failed and the current connection state + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +// Create the "setup" function, this is automatically called once upon boot +// The setup function is as the name implies usually used for one time setup upon boot +// This function is of the type "void" which means that it doesn't have a return value +void setup() { + // Set the LED pin as an output + pinMode(O_LED, OUTPUT); + // Start serial communication at a baud rate (speed) of 115200Hz + Serial.begin(115200); + // Run the setup WiFi function to connect to the WiFi network + setup_wifi(); + // Set the client's MQTT broker (server) to the one we specified earlier using the standard unencrypted MQTT communication port (1883) + // The "setServer" function takes two arguments + // 1. The URI of the MQTT broker + // 2. The port the communication happens on + client.setServer(mqtt_broker, 1883); + // Tell the MQTT client which function to call when it receives a message + client.setCallback(callback); +} + +// Create the loop function, this runst continually and loops forever until power loss +// This function is of the type "void" which means that it doesn't have a return value void loop() { - // put your main code here, to run repeatedly: + // If the MQTT client is not connected use the reconnect function + if (!client.connected()) { + reconnect(); + } + // Loop the MQTT client to make sure it doesn't disconnect + client.loop(); } \ No newline at end of file