3 easy steps to build a WiFi Temperature Sensor (ESP8266)

Spread the love

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

NodeMCU ESP8266
NodeMCU ESP8266

TMP36DZ Temperature Sensor

TMP36 Temperature Sensor
TMP36 Temperature Sensor

Jumper Wires

Jumper Wires
Jumper Wires

Breadboard

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

PlatformIO IDE Code
PlatformIO IDE

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.

ESP8266 WiFi Temperature Sensor Wiring Diagram
ESP8266 WiFi Temperature Sensor Wiring Diagram

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

PlatformIO IDE Code
PlatformIO IDE Code

You should see the serial terminal output below

Serial Terminal Output
Serial Terminal Output

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

Dinesh

Senior Software Engineer @ Apple | ex-Yahoo Finance Eng | Distributed Computing @ Georgia Tech | Python, Scala, C++ | Scalability, ML/AI, IoT | Opinions mine only

Also published on Medium.


Spread the love

2 Replies to “3 easy steps to build a WiFi Temperature Sensor (ESP8266)”

Leave a Reply