Skip to content

Instantly share code, notes, and snippets.

@balloob
Created June 20, 2016 04:11
Show Gist options
  • Save balloob/1176b6d87c2816bd07919ce6e29a19e9 to your computer and use it in GitHub Desktop.
Save balloob/1176b6d87c2816bd07919ce6e29a19e9 to your computer and use it in GitHub Desktop.
Sketch for the ESP8266 to publish temperature and humidity values received from a DHT22 to MQTT
// Get ESP8266 going with Arduino IDE
// - https://github.com/esp8266/Arduino#installing-with-boards-manager
// Required libraries (sketch -> include library -> manage libraries)
// - PubSubClient by Nick ‘O Leary
// - DHT sensor library by Adafruit
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#define wifi_ssid "YOUR WIFI SSID"
#define wifi_password "WIFI PASSWORD"
#define mqtt_server "YOUR_MQTT_SERVER_HOST"
#define mqtt_user "your_username"
#define mqtt_password "your_password"
#define humidity_topic "sensor/humidity"
#define temperature_topic "sensor/temperature"
#define DHTTYPE DHT22
#define DHTPIN 14
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266
void setup() {
Serial.begin(115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_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 reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
// If you do not want to use a username and password, change next line to
// if (client.connect("ESP8266Client")) {
if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
bool checkBound(float newValue, float prevValue, float maxDiff) {
return !isnan(newValue) &&
(newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
float newTemp = dht.readTemperature();
float newHum = dht.readHumidity();
if (checkBound(newTemp, temp, diff)) {
temp = newTemp;
Serial.print("New temperature:");
Serial.println(String(temp).c_str());
client.publish(temperature_topic, String(temp).c_str(), true);
}
if (checkBound(newHum, hum, diff)) {
hum = newHum;
Serial.print("New humidity:");
Serial.println(String(hum).c_str());
client.publish(humidity_topic, String(hum).c_str(), true);
}
}
}
@delorean-dev
Copy link

@ballob i have this error:

C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino: In function 'void setup()':

dddddd:32: error: 'class PubSubClient' has no member named 'setServer'

client.setServer(mqtt_server, 1883);

      ^

C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino: In function 'void reconnect()':

dddddd:62: error: no matching function for call to 'PubSubClient::connect(const char [14], const char [14], const char [14])'

 if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {

                                                             ^

C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino:62:65: note: candidates are:

In file included from C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino:8:0:

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:111:9: note: bool PubSubClient::connect(String)

bool connect(String id);

     ^

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:111:9: note: candidate expects 1 argument, 3 provided

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:123:9: note: bool PubSubClient::connect(String, String, uint8_t, bool, String)

bool connect(String id, String willTopic, uint8_t willQos, bool willRetain, String willMessage);

     ^

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:123:9: note: candidate expects 5 arguments, 3 provided

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:185:9: note: bool PubSubClient::connect(MQTT::Connect&)

bool connect(MQTT::Connect &conn);

     ^

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:185:9: note: candidate expects 1 argument, 3 provided

dddddd:66: error: 'class PubSubClient' has no member named 'state'

   Serial.print(client.state());

                       ^

C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino: In function 'void loop()':

dddddd:101: error: invalid conversion from 'const char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]

   client.publish(temperature_topic, String(temp).c_str(), true);

                                                        ^

In file included from C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino:8:0:

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:144:9: error: initializing argument 2 of 'bool PubSubClient::publish(String, const uint8_t*, uint32_t, bool)' [-fpermissive]

bool publish(String topic, const uint8_t *payload, uint32_t plength, bool retained = false);

     ^

dddddd:108: error: invalid conversion from 'const char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]

   client.publish(humidity_topic, String(hum).c_str(), true);

                                                    ^

In file included from C:\Users\Paula Alves\Desktop\dddddd\dddddd.ino:8:0:

C:\Users\Paula Alves\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:144:9: error: initializing argument 2 of 'bool PubSubClient::publish(String, const uint8_t*, uint32_t, bool)' [-fpermissive]

bool publish(String topic, const uint8_t *payload, uint32_t plength, bool retained = false);

     ^

exit status 1
'class PubSubClient' has no member named 'setServer'

@errece
Copy link

errece commented Oct 12, 2017

Yes, that's perfect, but I don't know how to implement it with HomeAssistant Generic Thermostat, it requires a float, and don't know how change the code to do that...

@stoneobscurity
Copy link

@outrun0506

i think it's the MQTT_CALLBACK_SIGNATURE in pubsubclient. they are both being set to the same ID, so the MQTT server thinks you are already connected. when I unplug my 1st nodemcu the 2nd nodemcu stops getting the error. so it seems to be a first come, first serve(r)ed.

the script needs a way to pass in a DEVICE_ID of some kind to pubsubclient, so that it can used in the signature to differentiate them. not sure how to add that, python isn't my thing.

--stone

@stoneobscurity
Copy link

@outrun0506

well, it seems i spoke too soon, it does have a DEVICE_ID.

line 62: change "ESP8266Client" to "whateverYouLike2"
just so long as it's unique.

then both nodes should play well with each other.

@sh00t2kill
Copy link

I am successfully using this, but the temp and humidty values it reports are VERY jittery. Does anyone have a way to clean them up a little?

@jullle3
Copy link

jullle3 commented Nov 7, 2018

Depending on their values, taking an average could work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment