3 easy steps to build a WiFi Temperature Sensor (ESP8266)
In my last post a few weeks ago, I built a Temperature Sensor using an Arduino. This temperature sensor was limited to reading the current temperature using an LM35DZ sensor. I could’ve wired it up to a I2C display (Perhaps I’ll have a separate post for it). However, the real fun begins when sensors are able to communicate over the Internet. That way you can record and graph the data.
In this post, I’m going to take you through building a WiFi temperature sensor using the popular ESP8266 dev board.
What is ESP8266 and how is it different from an Arduino?
Not long ago, Arduino first came out with a dev board with an Atmel microcontroller and a easy to use IDE. They Open Sourced it and it began the whole Arduino and Arduino compatible Open Hardware, Software revolution. ESP8266 is an ultra cheap WiFi chip with a pretty capable Microcontroller (Tensilica LX6). This makes it perfect to build your IoT project without a separate microcontroller. This means your entire application can run on this single chip!
The ESP8266 board I’ll be using is the NodeMCU. Plenty boards available on Amazon and eBay between $3 and $10.
You’ll the following components to build the Temperature Sensor
NodeMCU ESP8266 Dev Board
TMP36DZ Temperature Sensor
Jumper Wires
Breadboard
PlatformIO IDE
PlatformIO IDE is a polyglot IDE. It supports many dev boards and frameworks. It’s based on Atom. You can find more info here.
MQTT Server
I run Ubuntu Linux on my NAS at home. So I chose to install mosquitto and mosquitto-client.
sudo apt-get install mosquitto mosquitto-client
Step 1: Wire up the ESP8266 (NodeMCU) board to TMP36
The wiring is similar to my last post. If you’re unsure see Adafruit’s tutorial on using this sensor as well. The main difference between the LM35 and TMP36 temperature sensor is the voltage required for operation. TMP36 can operate at low voltages like 3.3V. This is required as NodeMCU board doesn’t support 5V natively.
Step 2: Write code
Make sure to update the #defines at the beginning of the code block.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#define WIFI_SSID "XXXXXX"
#define WIFI_PASS "XXXXXX"
#define WIFI_CONN_BACKOFF_MS 1000
#define MQTT_SERVER_IP "XXX.XXX.XXX.XXX"
#define MQTT_SERVER_PORT XXXXX
#define STATUS_LED_PIN D0
float tempCelcius = 0.0f;
float tempFaren = 0.0f;
String deviceId;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// Forward decls
void connectWifi(const char* ssid, const char* password);
void adcValToTemperatures(float adcVal, float *celcius, float *farenheit);
void printTempToSerial(float adcVal, float tempCelcius, float tempFaren);
void sendTemperature(float tempCelcius);
String getDeviceId();
void setup() {
Serial.begin(115200);
// Turn off WiFi to resolve an issue with unstable readings
// See this: https://github.com/esp8266/Arduino/issues/2070
WiFi.disconnect(true);
mqttClient.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
pinMode(STATUS_LED_PIN, OUTPUT);
deviceId = getDeviceId();
}
void loop() {
float adcVal = analogRead(A0);
delay(1000);
adcValToTemperatures(adcVal, &tempCelcius, &tempFaren);
printTempToSerial(adcVal, tempCelcius, tempFaren);
sendTemperature(tempCelcius);
delay(1000);
}
void connectWifi(const char* ssid, const char* password) {
WiFi.begin(ssid, password);
Serial.print("Connecting WiFi");
while (WiFi.isConnected() != true) {
Serial.print(".");
delay(WIFI_CONN_BACKOFF_MS);
}
Serial.print("IP=");
Serial.println(WiFi.localIP());
}
void adcValToTemperatures(float adcVal, float *celcius, float *farenheit) {
*celcius = ((adcVal * (3300.0/1024)) - 500) / 10;
*farenheit = (*celcius * 1.8) + 32;
}
void printTempToSerial(float adcVal, float tempCelcius, float tempFaren) {
Serial.print("adc=");
Serial.print(adcVal);
Serial.print(" celcius=");
Serial.print(tempCelcius);
Serial.print(" farenheit=");
Serial.println(tempFaren);
}
void sendTemperature(float tempCelcius) {
digitalWrite(STATUS_LED_PIN, LOW);
connectWifi(WIFI_SSID, WIFI_PASS);
if (mqttClient.connect(deviceId.c_str(), "", "")) {
mqttClient.publish((deviceId + "/temp_celcius").c_str(), String(tempCelcius).c_str(), true);
} else {
Serial.print("MQTT Send failed\n");
}
WiFi.disconnect(true);
digitalWrite(STATUS_LED_PIN, HIGH);
}
String getDeviceId() {
return ("iot_" + WiFi.macAddress());
}
Step 3: Build & Flash
You should see the serial terminal output below
You can subscribe to the temperature topic to see the output
mosquitto_sub -h localhost -p MQTT_PORT -t 'SENSOR_ID/temp_celcius'
Make sure to replace the MQTT_PORT and SENSOR_ID with appropriate values.
Here’s a video of it in action
Originally published at Dinesh A Joshi.