Internet of Things (Part 1)

Neil HaddleyMarch 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

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

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 Manager...

Boards package

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)"

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

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

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

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

MQTT Explorer connecting to the MQTT broker

ESP8266 is publishing "outTopic" messages 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 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}