---
# System prepended metadata

title: '**Monitor the environment in the apartment**'

---

# **Monitor the environment in the apartment**
**Michal Ostrowski (mo223um)**

In this project I will show you how to connect DHT11 sensor to the microcontoller, setup the WiFi connection, send data through MQTT and visualize them.

Estimated time: 3 hours

**Objective**
---
Working from home has lot of benefits, but sometimes it is also very exhausting. You may feel better one day, and worse another. The weather conditions has a huge impact of that situation so it is good to know the environment you work in. 
To do that is good to measure temperature nad humidity in the room. Having those data we can easily find best air conditions for us.
This step by step guidline is a good way to deep into IoT solutions since it is easy to follow and shows how benefits and fun might be developing you own IoT project.

**Material**
---
In the following table you will find a list of materials I am using in this tutorial together with the links where I bought them and their estimated price.


| Item     | Link  | Price $ | Description |
| -------- | -------- | -------- | -------- | 
| NodeMCU ESP32 | [Link](https://botland.store/esp32-wifi-and-bt-modules/8893-esp32-wifi-bt-42-platform-with-module-5904422337438.html) | 9.70 | Microcontoller with built in WiFi. |
| Breadboard | [Link](https://botland.store/breadoards/19943-breadboard-justpi-830-holes-5904422328610.html) | 1.67 | Usefull for connecting sensors to the microcontroller. |
| Jumper wires | [Link](https://botland.store/withdrawn-products/1022-connecting-cables-male-male-65pcs-5904422304409.html) | 1.71 | Connect the sensors to the microcontroller. |
| DHT11 | [Link](https://botland.store/multifunctional-sensors/9301-temperature-and-humidity-sensor-dht11-50c-5904422372668.html) | 3.45 | Temperature and humidity sensor. |
| 4.7k Ω resistor | [Link](https://botland.store/withdrawn-products/1268-set-of-resistors-cf-tht-1-4w-200pcs-5903351241496.html) | 2.15 | The DATA-line on DHT11 needs a pulling resistor 5k Ω. |
|Micro USB cable | [Link](https://botland.store/usb-20-cables/2906-microusb-cable-b-a-1m-5901812014474.html) | 1.28 | To connect microcontroller to your computer and upload a code |
|    | Total: | 19.96 | 

**Computer setup**
---
**Flashing the firmware**
First we have to flash MicroPython firmware on our device. 
To do that follow the instructions below:
* Install the latest version of python. You can do it from pythons website [link](https://www.python.org/downloads/).
* Install the latest version of esptool.py: open a Terminal window and use pip manager.
```
python -m pip install esptool
```
![](https://i.imgur.com/uLPedh6.png)

* Go to the folder where esptool is installed:
```
cd C:\Users\username*\AppData\Local\Programs\Python39\Lib\site-packages
```
\* Remember to change username to your computer's name
* Run esptool.py to check if it is correctly installed:
```
esptool.py
```
![](https://i.imgur.com/MYBWHZj.png)
* Download the latest firmware of MicroPython for the ESP32 board from micropython webpage [link](https://micropython.org/download/esp32/).
* Add the bin file to the site-packages folder.
* Now we need to check the COM port of the device. We can do it by typing esptool.py flash_id in the Terminal:
![](https://i.imgur.com/W7BZ3z8.png)
We can also go to the Device Manager and check it there under Ports. If you cannot find it there you might be missing the drivers. If so, download the drivers from [there](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads) and istall it. Then you should be able to find the COM port.
* Now it's a timeto erase the flash memory of the device and flash it with the MicroPython firmawe. Do not forget to change the port number. Hold the **BOOT/FLASH** button while running the command. 
```
esptool.py --chip esp32 --port <YOUR_COM_PORT> erase_flash 
```

* Now we can flash the MicroPython firmware to the board. Again, hold the **BOOT/FLASH** button while running the command.
```
esptool.py --chip esp8266 --port <YOUR_COM_PORT> write_flash --flash_mode dio --flash_size detect 0x0 <YOUR_BIN_FILE>
``` 
![](https://i.imgur.com/Id4TpBf.png)

Now our board is ready :D

**Intalling IDE**
We will be using Visual Studio Code to program the board. It is easy to use and enable programming in several languages. We will need the Pymakr extension to build our project.
* First, we need to install Node.js. Download the file from the [link](https://nodejs.org/en/download/). Then run the .exe file and follow the instructions.
* We need to install Visual Studio Code. Download the programme [link](https://code.visualstudio.com/) and install on your computer.
* Once VS Code is installed, open it and click on the Extensions page. Search for the Pymakr extension and install it. You should now see the Pymakr Console on the bottom.

![](https://i.imgur.com/vb6HgLW.png)
* Press All Commands int the bottom of the screen and search for Pymakr > Global Settings. This opens the pymakr.json file

![](https://i.imgur.com/248bXe0.png)

Here we have to change the **address** field to out COM port number and set the **auto_connect** to false to connect directly to our board. We can now connect to the microcontroller searching for **Pymakr > Connect** under **All Commands**.
* To upload the code to the microcontroller we just need to create a folder where we will store our code, and then press the **Uppload** button (at the bottom).

**Putting everything together**
---
We are ready to connect the DHT11 sensor to the ESP32. You can see how it should looks like on the diagram below

![](https://i.imgur.com/pyFLf5Y.png)

* The orange wires are positive cables to power the sensors.
* The black wires are groung cables.
* The blue wire is a data cable. 

Here you can see how it looks:

![](https://i.imgur.com/0MYJoLH.jpg)
As you see, it looks really simple :D 
This is of course for a development setup, but is a nice way to start.

**Platform**
---
I have decided to choose the *Adafruit IO* platform. 

It is a cloud platform, which provides utilities to store data and create simple dashboards, perfect for our solution.

All you need to do is to create a free acount at Adafruit' website [here](https://accounts.adafruit.com/). 

Having an account we can easily create dashboard and create *feeds* for the data.

**The code**
---
Now it's time for some coding :D

To be able to send the data to the platform we need to setup WiFi connection.

We will use MQTT broker to publish the data.

We are establishing WiFi connection in the boot.py file:
```
import network
import machine
import config

# Connect the device to WiFi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.WIFI_SSID, config.WIFI_PASS)
while not wlan.isconnected():
    machine.idle() #save power while waiting
print('WLAN connection succeded!')
print(wlan.ifconfig())

import gc
#do a garbage collection before we start sensors
gc.collect()
```

In the main.py file we are creating sensor object and setting up MQTT broker.

```
#Importing libraries
import network
import dht
import machine
from machine import Pin
import time
from utilities import *

# Create sensor object
dht_sensor = dht.DHT11(Pin(4))

# Connect to MQTT broker
try:
    client = connect_MQTT()
except OSError as e:
    restart_and_reconnect()

# Try to connect to mqtt broker, read the sensors, and publish results
while True:
    try:
        # Need to wait for the DHT11 to initialize
        time.sleep(2)

        #Get Readings.
        results = read_dht(dht_sensor)

        # Publish data to the broker
        publish(client, results)

        # Wait 20 minutes (1200 seconds)
        time.sleep(1200) 
    except OSError as e:
        restart_and_reconnect()
```

It is good to store the credentials in the seperate file, for example config.py:
```
WIFI_SSID = "wifi_ssid"
WIFI_PASS = "wifi_password"

MQTT_BROKER = "io.adafruit.com"
SERIAL_NUMBER = 'serial_number_of_the_device'

USER = 'your_username_on_adafruit_io'
PASS = 'your_password'

TOPIC_TEMP = 'michalostrowski/feeds/sensor.temperature'
TOPIC_HUM = 'michalostrowski/feeds/sensor.humidity'
```

All neccessary functions are stored in the utilities.py file:
```
from lib.umqttsimple import MQTTClient
import config
import machine
import time

# The MQTT topics that we publish data to
topic_pub_temp = config.TOPIC_TEMP
topic_pub_hum = config.TOPIC_HUM

# Connect to MQTT Broker
def connect_MQTT():
    #Enter Adafruit username and key below
   
    client = MQTTClient(config.SERIAL_NUMBER, 
                        config.MQTT_BROKER, 
                        user=config.USER, 
                        password=config.PASS)
    client.connect()
    print('Connected to %s MQTT broker' % (config.MQTT_BROKER))
    return client

# Publish data to the broker, under specified topic
def publish(client, results):
    # Unpack the results
    temp, hum = results

    client.publish(topic_pub_temp, str(temp))
    client.publish(topic_pub_hum, str(hum))

# Reset the device if it can not publish the readings via MQTT
def restart_and_reconnect():
    print('Failed to connect to MQTT broker. Reconnecting...')
    time.sleep(10)
    machine.reset()

# Read the dht sensor 
def read_dht(dht_sensor):
    try:
        dht_sensor.measure()
        temp = dht_sensor.temperature()
        hum = dht_sensor.humidity()
        return temp, hum
    except OSError as e:
        return('Failed to read dht sensor.')

```
To make the above code work we need to download the umqttsimple library from [here](https://raw.githubusercontent.com/RuiSantosdotme/ESP-MicroPython/master/code/MQTT/umqttsimple.py).

**Transmitting the data / connectivity**
---
The DHT11 sensor reads the data every 20 minutes. The results are immidiately send via WiFi. ESP32 has build in WiFi transmitter, thus it was the matter of available technologies in case of choosing wireless protocol (t.ex Pycom devices have LoRa protocol).

We are using MQTT protocol to transfer the data to the Adafruit IO MQTT broker. We have to provide the credentials to the account and topics for our results.

**Presenting the data**
---
Creating dashboard to show the data in the more meanigfull way is relatively easy. After logging in to Adafruit IO we click **Dashboards** and then select *New Dashboard*. We need to provide the name for our dashboard and click create button. Next, we are going to the newly created dashboard and under the settings we select *Create New Block*. Now we can choose from several types of blocks. I have chosen **Line Chart** to show the historical data, and **Gauge** to present the current humidity and temperature.
![](https://i.imgur.com/xFlirx0.png)

In the next step we are choosing which topics (feeds) will be connected to the corresponding blocks.

![](https://i.imgur.com/VqJlUIk.png)

Now we can present our data :D

![](https://i.imgur.com/D33NEYU.png)

Data is send up do the Adafruit every 20 minutes. Results are stored for maximum 30 days.

**Finalizing the design**
---
Yay!!! Our project is ready :D

We went through the tutorial and we've build a simple project to measure temperature and humidity in our environment. 

Following all above steps gives a good understanding how to create IoT project from base. From this place we can easily add more sensors, such as *Air quality* sensor to build more complex solution.

![](https://i.imgur.com/alSUPRy.jpg)
