# IOT-Temperature_Sensor
**By Peter Sergo, ps223kr**
A tutorial on how to build a temperature sensor using an ESP32 controller connected via WiFi in combination with a DHT11 temperature sensor that both displays the current temperature in a dashboard and allows for remote control of the blue onboard led.
Rough estimate of the time necessary is a couple of days work if you have no prior IOT knowledge otherwhise the flashing and the code is quite simple.
## Objective
---
I want to be able to monitor the temperature of my home when I'm away and control the heatpump remotely both in a manual way and an automatic that disables the heating at night and during the day to preserve energy. Due to time limitations and my ordered IR-sender not showing up I wasn't able to do any active control which I instead had to replace with the onboard LED as a proof of concept of sending signals over the internet to the controller.
The purpose of this project is to save energy which makes up most of our electric bill and also to be more environmentally friendly.
There were several insights gained but most importantly to do a project from finish to end and to order parts earlier next time.
## Material
---
| Part | Location | Price SEK |
| ---------------- | -------------------------------------------------------------------- | --------- |
| ESP32 Controller | https://sizable.se/P.CE9S1/ESP32 | 94 |
| DHT11 Sensor | https://sizable.se/P.WGXR4/DHT11-Temperatur-och-luftfuktighetssensor | 28 |
| Dupont cables | https://sizable.se/P.4LTWU/Dupont-kopplingskablar-Hona-Hona-40-pin | 24 |
| Micro USB cable | An old smartphone charging cable | - |
total 146 kr
The ESP32 controller is the main component responsible for handling all the data, supplying the sensor with electricity and sending the data over wifi.
The DHT11 sensor is responsible for measuring the temperature of the surrounding air.
A connection is required between the ESP32 controller and the DHT11 sensor. I opted for the cheaper alternative of using vires but you can also use a breadboard.
The micro USB-cable needs to be of the data carrying kind(not only for charging) as I found out when I wasn't able to connect to my controller from the computer the first time.
## Computer setup
---
I chose to write the code in VSCODE IDE as I had some previous experience using that and I find the extensions for PEP8 formatting handy. However any IDE such as Atom, Thonny or even VIM can be used.
To upload the code to the controller thonny was used as it worked and I found that most tutorials for this controller also used it.
The extra steps needed to get everything running can vary as I use Ubuntu with the apt packet manager but in essence you need to download python, pip and thonny using the following commands in the terminal
> sudo apt update; sudo apt upgrade
> sudo apt install python3
> sudo apt install python3-pip
> sudo pip3 install thonny
You then connect the ESP32 controller and open thonny by writing thonny in the terminal.
> thonny
To flash the firmware for the generic ESP32 controller visit
https://micropython.org/download/
and get the latest firmwareupdate and the extract it.
In thonny go to tools > options > Interpreter
* Choose "Micropython ESP32"
* Select "Install or update firmware" and select the file
If you encounter the following error
Unable to connect to /dev/ttyUSB0: [Errno 13] could not open port /dev/ttyUSB0: [Errno 13] Permission denied: '/dev/ttyUSB0'
Try using the following command in the terminal to change read/write permission allowing you to upload your files to the actual controller.
> sudo chmod a+rw /dev/ttyUSB0
## Putting everything together
---

*Figure 1, Connecting the DHT11 sensor to the ESP32 controller*
Everything is connected using three wires from the ESP32 controller
- 3V3 to VCC
- GND 1 to GND
- D15 to SDA
The DHT11 sensor only needs 3.3V meaning that no additional resistor is required to bring the voltage down from the controllers 3.3V pin.
In order for this to be viable in production I would probably consider soldering the sensor to the controller in a more permanent way with shorter wires and putting everything inside an enclosure to protect it from dust and ESD/short circuiting.
## Platform
---
I tried using the TIG-stack and node-red through docker which worked pretty good locally but I ended up using adafruit because our ISP doesn't provide a public IP so I can't access a local server online. I chose adafruit primarily because it's free, stores the data and can also send input to the controller with a nice UI/UX dashboard.
If I continue with this in the future however and want to process the data I would probably look into cloud hosting which also allows for scalability.
## The code
---
The DHT11 uses the dht library which is already included.
Two methods are used first measure() to activate the sensor and collect data and then temperature() to retrieve the measured temperature.
In addition the following library [umqtt](https://pypi.org/project/micropython-umqtt.simple/) was installed to use the mqtt protocol.
```python=
from machine import Pin
import wifi
import dht
from time import sleep
from umqtt.simple import MQTTClient as MQTT
import sys
# Wifi
wifi.connect()
# Blue led on the board
led = Pin(2, Pin.OUT)
led.off()
# Temperature sensor input
sensor = dht.DHT11(Pin(15))
# MQTT Adafruit Info
mqtt_client_id = bytes("client_"+"384283248235", "utf-8") # Random client id
ADAFRUIT_IO_URL = "io.adafruit.com"
ADAFRUIT_IO_USERNAME = "USERNAME"
ADAFRUIT_IO_KEY = "KEY"
TEMP_FEED_ID = "temp"
TOGGLE_FEED_ID = "led"
client = MQTT(client_id=mqtt_client_id,
server=ADAFRUIT_IO_URL,
user=ADAFRUIT_IO_USERNAME,
password=ADAFRUIT_IO_KEY,
ssl=False)
try:
client.connect()
except Exception as e_:
print("could not connect to mqtt server {}{}".format(type(e).__name__, e))
sys.exit()
def cb(topic, msg):
print("Received data: Topic = {}, Msg = {}".format(topic, msg))
received_data = str(msg, "utf-8")
if received_data == "0":
led.off()
if received_data == "1":
led.on()
temp_feed = bytes(
"{:s}/feeds/{:s}".format(ADAFRUIT_IO_USERNAME, TEMP_FEED_ID), "utf-8")
toggle_feed = bytes(
"{:s}/feeds/{:s}".format(ADAFRUIT_IO_USERNAME, TOGGLE_FEED_ID), "utf-8")
client.set_callback(cb)
client.subscribe(toggle_feed)
while True:
sleep(5)
try:
sensor.measure()
temp = sensor.temperature()
print(temp)
except OSError as e:
print('Failed to read sensor.')
client.publish(temp_feed,
bytes(str(temp), "utf-8"),
qos=0)
print("msg sent")
client.check_msg()
```
The wifi.py file is imported in the start of the main file and then called. This connects the controller to the wifi with your SSID and password.
```python=
def connect():
import network
ssid = "SSID_OF_YOUR_WIFI"
password = "PASSWORD"
station = network.WLAN(network.STA_IF)
if station.isconnected() == True:
print("Already connected")
return
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
pass
print("Connection successful")
print(station.ifconfig())
```
## Transmitting the data / connectivity
---
The data is sent every 5 seconds over WiFi as this was done at home and it's already readily available.
I then used MQTT as a my transport/application protocol over TCP. MQTT is more lightweight and used a lot throughout the IOT-world. To enable this in micropython I downloaded the umqtt library in Tools > Manage packages.
## Presenting the data
---

*Picture 2, The Adafruit dashboard with the current temperature and an on/off switch*

*Picture 3, The Adafruit feed for the Temperature*
The data is saved every 5 seconds which is often enough considering that the temperature doesn't change that much and that the sensor's accuracy isn't too great.
The data is then stored on adafruit for a period of 30 days. An alternative would be to host your own server for example a SQL Mariadb one.
In my dashboard you only have the control over the LED and the current temperature but if you go to the temperature feed you can see a graph over it instead. To build this you only need to create a dashboard on the adafruit website and choose Create new block > Choose a block type > Choose one of the MQTT connected feeds.
## Finalizing the design
---
Currently the controller sits on the floor and collects temperature data sent to adafruit with the possibility to turn the blue LED on/off over the internet. It was a nice start for IOT but I want to control the heatpump to change the temperature instead of just the onboard led. So the next step is to add the IR-sender once it arrives and perhaps collect data over the electricity price and adjust the usage after that to save even more money.

*Picture 4, current installation*