ESP MQTT
1
/*********
2
Rui Santos
3
Complete project details at https://randomnerdtutorials.com
4
*********/
5
6
#include <WiFi.h>
7
#include <PubSubClient.h>
8
#include <Wire.h>
9
#include <Adafruit_BME280.h>
10
#include <Adafruit_Sensor.h>
11
12
// Replace the next variables with your SSID/Password combination
13
const char* ssid = "REPLACE_WITH_YOUR_SSID";
14
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
15
16
// Add your MQTT Broker IP address, example:
17
//const char* mqtt_server = "192.168.1.144";
18
const char* mqtt_server = "YOUR_MQTT_BROKER_IP_ADDRESS";
19
20
WiFiClient espClient;
21
PubSubClient client(espClient);
22
long lastMsg = 0;
23
char msg[50];
24
int value = 0;
25
26
//uncomment the following lines if you're using SPI
27
/*#include <SPI.h>
28
#define BME_SCK 18
29
#define BME_MISO 19
30
#define BME_MOSI 23
31
#define BME_CS 5*/
32
33
Adafruit_BME280 bme; // I2C
34
//Adafruit_BME280 bme(BME_CS); // hardware SPI
35
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
36
float temperature = 0;
37
float humidity = 0;
38
39
// LED Pin
40
const int ledPin = 4;
41
42
void setup() {
43
Serial.begin(115200);
44
// default settings
45
// (you can also pass in a Wire library object like &Wire2)
46
//status = bme.begin();
47
if (!bme.begin(0x76)) {
48
Serial.println("Could not find a valid BME280 sensor, check wiring!");
49
while (1);
50
}
51
setup_wifi();
52
client.setServer(mqtt_server, 1883);
53
client.setCallback(callback);
54
55
pinMode(ledPin, OUTPUT);
56
}
57
58
void setup_wifi() {
59
delay(10);
60
// We start by connecting to a WiFi network
61
Serial.println();
62
Serial.print("Connecting to ");
63
Serial.println(ssid);
64
65
WiFi.begin(ssid, password);
66
67
while (WiFi.status() != WL_CONNECTED) {
68
delay(500);
69
Serial.print(".");
70
}
71
72
Serial.println("");
73
Serial.println("WiFi connected");
74
Serial.println("IP address: ");
75
Serial.println(WiFi.localIP());
76
}
77
78
void callback(char* topic, byte* message, unsigned int length) {
79
Serial.print("Message arrived on topic: ");
80
Serial.print(topic);
81
Serial.print(". Message: ");
82
String messageTemp;
83
84
for (int i = 0; i < length; i++) {
85
Serial.print((char)message[i]);
86
messageTemp += (char)message[i];
87
}
88
Serial.println();
89
90
// Feel free to add more if statements to control more GPIOs with MQTT
91
92
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
93
// Changes the output state according to the message
94
if (String(topic) == "esp32/output") {
95
Serial.print("Changing output to ");
96
if(messageTemp == "on"){
97
Serial.println("on");
98
digitalWrite(ledPin, HIGH);
99
}
100
else if(messageTemp == "off"){
101
Serial.println("off");
102
digitalWrite(ledPin, LOW);
103
}
104
}
105
}
106
107
void reconnect() {
108
// Loop until we're reconnected
109
while (!client.connected()) {
110
Serial.print("Attempting MQTT connection...");
111
// Attempt to connect
112
if (client.connect("ESP8266Client")) {
113
Serial.println("connected");
114
// Subscribe
115
client.subscribe("esp32/output");
116
} else {
117
Serial.print("failed, rc=");
118
Serial.print(client.state());
119
Serial.println(" try again in 5 seconds");
120
// Wait 5 seconds before retrying
121
delay(5000);
122
}
123
}
124
}
125
void loop() {
126
if (!client.connected()) {
127
reconnect();
128
}
129
client.loop();
130
131
long now = millis();
132
if (now - lastMsg > 5000) {
133
lastMsg = now;
134
135
// Temperature in Celsius
136
temperature = bme.readTemperature();
137
// Uncomment the next line to set temperature in Fahrenheit
138
// (and comment the previous temperature line)
139
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit
140
141
// Convert the value to a char array
142
char tempString[8];
143
dtostrf(temperature, 1, 2, tempString);
144
Serial.print("Temperature: ");
145
Serial.println(tempString);
146
client.publish("esp32/temperature", tempString);
147
148
humidity = bme.readHumidity();
149
150
// Convert the value to a char array
151
char humString[8];
152
dtostrf(humidity, 1, 2, humString);
153
Serial.print("Humidity: ");
154
Serial.println(humString);
155
client.publish("esp32/humidity", humString);
156
}
157
}
Copied!

Subscribing to MQTT topics

In the reconnect() function, you can subscribe to MQTT topics. In this case, the ESP32 is only subscribed to the esp32/output:
1
client.subscribe("esp32/output");
Copied!
In the callback() function, the ESP32 receives the MQTT messages of the subscribed topics. According to the MQTT topic and message, it turns the LED on or off:
1
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
2
// Changes the output state according to the message
3
if (String(topic) == "esp32/output") {
4
Serial.print("Changing output to ");
5
if (messageTemp == "on") {
6
Serial.println("on");
7
digitalWrite(ledPin, HIGH);
8
}
9
else if (messageTemp == "off") {
10
Serial.println("off");
11
digitalWrite(ledPin, LOW);
12
}
13
}
Copied!

Publishing MQTT messages

In the loop(), new readings are being published every 5 seconds:
1
if (now - lastMsg > 5000) { ... }
Copied!
By default the ESP32 is sending the temperature in Celsius, but you can uncomment the last line to send the temperature in Fahrenheit:
1
// Temperature in Celsius
2
temperature = bme.readTemperature();
3
// Uncomment the next line to set temperature in Fahrenheit
4
// (and comment the previous temperature line)
5
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit
Copied!
You need to convert the temperature float variable to a char array, so that you can publish the temperature reading in the esp32/temperature topic:
1
// Convert the value to a char array
2
char tempString[8];
3
dtostrf(temperature, 1, 2, tempString);
4
Serial.print("Temperature: ");
5
Serial.println(tempString);
6
client.publish("esp32/temperature", tempString);
Copied!
The same process is repeated to publish the humidity reading in the esp32/humidity topic:
1
humidity = bme.readHumidity();
2
// Convert the value to a char array
3
char humString[8];
4
dtostrf(humidity, 1, 2, humString);
5
Serial.print("Humidity: ");
6
Serial.println(humString);
7
client.publish("esp32/humidity", humString);
Copied!
Copy link
Contents