Internet of Things (Part 1)
Neil Haddley • March 3, 2021
ESP8266 is a low-cost Wi-Fi microchip, with a full TCP/IP stack and microcontroller capability.
Breadboard
Here an ESP8266 device is connected to a DHT11 temperature and humidity sensor.
With the Hardware assembled we can create and configure the Internet of Things (IoT) software.
An MQTT publish/subscribe broker will be at the center of the software configuration. We will upload code to the ESP8266 that will allow the ESP8266 device to communicate with other devices via the MQTT broker.

ESP8266 with DHT Sensor
Arduino IDE setup
The Arduino Integrated Development Environment (IDE) can be used to create and upload C++ code to an ESP8266.
To add support for ESP8266 boards to the Arduino IDE select the "Arduino|Preferences..." menu item and add this url to the "additional boards manager" text box:
http://arduino.esp8266.com/stable/package_esp8266com_index.json

Arduino IDE Preferences
Support for the ESP8266 board
Use the "Tools|Board|Boards Manager..." menu item to install support for the ESP8266 boards.

Boards Manager...

Boards package
GitHub boards
The ESP8266 boards information is maintained in a GitHub repository
https://github.com/esp8266/Arduino
Once the boards package is installed the correct ESP8266 board can be selected.

Selecting "NodeMCU (ESP-12E Module)"
ESP8622 Libraries
Arduino libraries can downloaded to the Arduino IDE using the "Tools|Manage Libraries..." menu item.
The PubSubClient library allows the ESP8266 to connect to an MQTT broker.

PubSubClient Library
PubSubLibrary example
knolleary/pubsubclient is licensed under the MIT License.
Once the PubSubClient Library is installed the mqtt_esp8266 example sketch is added to the "File|Examples" Menu.

An example ESP8266 sketch
The mqtt_esp8266 example sketch
The mqtt_esp8266 example sketch subscribes to an MQTT server's "inTopic" messages.
When an "inTopic" message is received by the ESP8266 the example code's "callback" function is executed. If the payload of the "inTopic" message is the string "1" the ESP8266's builtin LED is turned on.
Every two seconds the example sketch publishes a "hello world" message to "outTopic".
MQTT
MQTT is a publish/subscribe messaging system commonly used by IoT devices.
The 'eclipse-mosquitto' Docker container image can be used to establish a test MQTT broker.
$ docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto:1.4.8

eclipse-mosquitto Docker image
MQTT Explorer
Desktop and mobile applications are able to connect to an MQTT broker showing messages that are being published. Desktop and mobile applications allow users to manually publish messages to an MQTT broker.

MQTT Explorer connecting to the MQTT broker

ESP8266 is publishing "outTopic" messages to the MQTT broker

MQTT explorer publishes an "inTopic" message with payload "1" to the MQTT broker and the ESP8266's LED turns on.
mqtt_esp8266.ino
TEXT
1/* 2 Basic ESP8266 MQTT example 3 This sketch demonstrates the capabilities of the pubsub library in combination 4 with the ESP8266 board/library. 5 It connects to an MQTT server then: 6 - publishes "hello world" to the topic "outTopic" every two seconds 7 - subscribes to the topic "inTopic", printing out any messages 8 it receives. NB - it assumes the received payloads are strings not binary 9 - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led, 10 else switch it off 11 It will reconnect to the server if the connection is lost using a blocking 12 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to 13 achieve the same result without blocking the main loop. 14 To install the ESP8266 board, (using Arduino 1.6.4+): 15 - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs": 16 http://arduino.esp8266.com/stable/package_esp8266com_index.json 17 - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266" 18 - Select your ESP8266 in "Tools -> Board" 19*/ 20 21/**/ 22 23#include <ESP8266WiFi.h> 24#include <PubSubClient.h> 25 26// Update these with values suitable for your network. 27 28const char* ssid = "........"; 29const char* password = "........"; 30const char* mqtt_server = "broker.mqtt-dashboard.com"; 31 32WiFiClient espClient; 33PubSubClient client(espClient); 34unsigned long lastMsg = 0; 35#define MSG_BUFFER_SIZE (50) 36char msg[MSG_BUFFER_SIZE]; 37int value = 0; 38 39void setup_wifi() { 40 41 delay(10); 42 // We start by connecting to a WiFi network 43 Serial.println(); 44 Serial.print("Connecting to "); 45 Serial.println(ssid); 46 47 WiFi.mode(WIFI_STA); 48 WiFi.begin(ssid, password); 49 50 while (WiFi.status() != WL_CONNECTED) { 51 delay(500); 52 Serial.print("."); 53 } 54 55 randomSeed(micros()); 56 57 Serial.println(""); 58 Serial.println("WiFi connected"); 59 Serial.println("IP address: "); 60 Serial.println(WiFi.localIP()); 61} 62 63void callback(char* topic, byte* payload, unsigned int length) { 64 Serial.print("Message arrived ["); 65 Serial.print(topic); 66 Serial.print("] "); 67 for (int i = 0; i < length; i++) { 68 Serial.print((char)payload[i]); 69 } 70 Serial.println(); 71 72 // Switch on the LED if an 1 was received as first character 73 if ((char)payload[0] == '1') { 74 digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level 75 // but actually the LED is on; this is because 76 // it is active low on the ESP-01) 77 } else { 78 digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH 79 } 80 81} 82 83void reconnect() { 84 // Loop until we're reconnected 85 while (!client.connected()) { 86 Serial.print("Attempting MQTT connection..."); 87 // Create a random client ID 88 String clientId = "ESP8266Client-"; 89 clientId += String(random(0xffff), HEX); 90 // Attempt to connect 91 if (client.connect(clientId.c_str())) { 92 Serial.println("connected"); 93 // Once connected, publish an announcement... 94 client.publish("outTopic", "hello world"); 95 // ... and resubscribe 96 client.subscribe("inTopic"); 97 } else { 98 Serial.print("failed, rc="); 99 Serial.print(client.state()); 100 Serial.println(" try again in 5 seconds"); 101 // Wait 5 seconds before retrying 102 delay(5000); 103 } 104 } 105} 106 107void setup() { 108 pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output 109 Serial.begin(115200); 110 setup_wifi(); 111 client.setServer(mqtt_server, 1883); 112 client.setCallback(callback); 113} 114 115void loop() { 116 117 if (!client.connected()) { 118 reconnect(); 119 } 120 client.loop(); 121 122 unsigned long now = millis(); 123 if (now - lastMsg > 2000) { 124 lastMsg = now; 125 ++value; 126 snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value); 127 Serial.print("Publish message: "); 128 Serial.println(msg); 129 client.publish("outTopic", msg); 130 } 131}