`Mathias Damgaard md223im` ![](https://i.imgur.com/ofDUaoE.jpg) # Tutorial on how to build a temperature & humidity sensor with an LCD. I have built an IoT device with an ESP32 microcontroller, a sensor for measuring temperature and humidity of my kitchen. I’ve also connected an LCD so I can read those values. The device also connects to the internet through Wi-Fi and sends the sensor data via MQTT protocol to Datacake. Datacake stores those values and lets you visualize them in different ways. Estimate project time would be probably be a day for a beginner and less than an hour for someone with experience. ## Objective As a complete beginner to the subject of IoT my objective was to learn the basics and explore different aspects of IoT, hardware and programming along the way. I knew I wanted to make something that I could have use for in my everyday life. Living in an old apartment building with less than stellar climate control where I regulate the airflow and temperature by opening and closing windows or the balcony door. Because of this temperature and humidity varies a lot. Therefore, I opted to make a weather station placed in my kitchen where the most dramatic shifts occur. That’s where my balcony door is and where my oven is sometimes running for hours a day since I like to cook and bake, preferably sourdough bread. Knowing the temperature where my dough ferments lets me easier predict when to proceed to the next stage of the bread baking, hopefully turning it into a great looking and tasting bread. ## Material Due to unexpected late cancellations of the materials I wanted, I ended up using the ESP32-WROVER which was included in a starter kit containing several things (172 items) including sensors, cables, a bread board, LEDs, LCD & resistors to name a few. It has comprehensive documentation on how to get started with their starter kit that can be found [here](https://github.com/Freenove/Freenove_Super_Starter_Kit_for_ESP32). [Amazon.se](https://www.amazon.se/Freenove-ESP32-WROVER-Contained-Compatible-Bluetooth/dp/B09BC5B4H6) 359 SEK ![](https://i.imgur.com/x1Kfspy.jpg) From the starter kit I used: **ESP32-WROVER** ![](https://i.imgur.com/W9PlGPC.png) **GPIO Extension Board** ![](https://i.imgur.com/tN7Qs60.png) **LCD 1602 Module** ![](https://i.imgur.com/RjXGgmA.png) **Breadboad** ![](https://i.imgur.com/SKCFlqb.png) **Jumper F/M x4 Jumper M/M x4** ![](https://i.imgur.com/q1KBvGz.png) **USB A - Micro USB cable** ![](https://i.imgur.com/zPnGvpi.jpg) **DHT11** ![](https://i.imgur.com/dvwGz7t.png) [Amazon.se](https://www.amazon.se/-/en/gp/product/B01M30ZWQR/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1) 282 SEK The humidity and temperature sensor came in another kit that I found containing 37 different sensors. It can be bought by itself from most stores selling items related to IoT since it's very common. One benefit is that it's inexpensive but it might not be as accurate as other alternatives on the market. **Generic USB A charger** ![](https://i.imgur.com/0WtC26Q.jpg) I'm also using an old Sony USB A phone charger with an output of 5V, 850mA. ## Computer setup As I am a beginner to programming, I tried both [Atom](https://atom.io/) and [Thonny](https://thonny.org/) as IDE to communicate with the ESP32 microcontroller. I have since enjoyed using Thonny more because it lets you view and interact with the files that's currently stored on your ESP32, which as far as I know, Atom doesn’t. Therefore Let's look at [this](https://randomnerdtutorials.com/getting-started-thonny-micropython-python-ide-esp32-esp8266/) guide from Random nerd tutorials on how to get going with Thonny. **This is the system that using to do this project** ![](https://i.imgur.com/yFp2eYL.png) I used the aur installer yay to install Thonny from the aur with the package called [thonny](https://aur.archlinux.org/packages/thonny) on my system. It's flagged as out-of-date which doesn't seem to be correct. Open up a terminal and cope and paste this command: ```yay -S thonny``` Next we'll update the firmware of our ESP32 and test so everything is up and running. We'll follow [this guide](https://hackmd.io/@lnu-iot/SyZ2diUOq) provided by LNU but have to make some alternations since it's aimed at Ubuntu and not Arch. * Step 1: Ignore this step * Step 5: It seems like you'll only have to do this step once with our setup instead of repeating it every time you reconnect the board to your computer as the guide suggests. We'll also have change the second command `sudo usermod -a -G dialout [Your username] >> usermod -a -G uucp $USER` These are the commands you'll run one by one in the Terminal: ``` ls -l /dev/ttyUSB0 usermod -a -G uucp $USER sudo chmod a+rw /dev/ttyUSB0 ls -l /dev/ttyUSB0 ``` * Step 6: 3. It's important to remeber to enter the Offset to 1000 as described or the device won't function properly. If you've followed the mentioned guides, Thonny IDE should now be connected to your board and you should be able to use the Shell to communicate with the ESP32. We can upload files to the ESP32 by selecing the files we want to upload and right clicking one of them and selecting "Upload to /". ![](https://i.imgur.com/cl7Fp11.jpg) ## Putting everything together This will all be fairly straight forward, I've connected the ESP32, extension board, sensor and LCD to the breadboard using the jumper cables. You can look at the documentation that Freenove provides for the board and their kits for more information [here](https://github.com/Freenove/Freenove_Ultimate_Starter_Kit_for_ESP32) (I've linked purposly to the Ultimate Starter Kit since they include a guide in the Python_Tutorial pdf on page 272, project 24.2 that I've followed and adapted my hardware to). Here you can see a circuit diagram and a schematic diagram to help you see how I connected my hardware. ![](https://i.imgur.com/17fTHK4.png) ![](https://i.imgur.com/h4CwtMa.png) The DHT11 that we have has a built-in 10k ohm pull up resistor so we don't need to add any extra. ![](https://i.imgur.com/eJEwL5F.png) ## Platform I choose to use [Datacake](https://datacake.co/) as a platform to recive and store data. It's a low-code IoT platform which is fairly straight forward and lets you connect up to two devices for free with up to 500 data points per day, which is way more than we need. We'll connect to it via Wi-Fi and their MQTT broker. ## The code ``` from mqtt import MQTTClient import time import ujson import machine import config from time import sleep_ms from machine import I2C, Pin from I2C_LCD import I2cLcd import dht DHT = dht.DHT11(Pin(18)) DEFAULT_I2C_ADDR = 0x27 i2c = I2C(0, scl=Pin(14), sda=Pin(13), freq=400000) lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) def sub_cb(topic, msg): print(msg) # MQTT Setup client = MQTTClient(config.SERIAL_NUMBER, config.MQTT_BROKER, user=config.TOKEN, password=config.TOKEN, port=config.PORT) client.set_callback(sub_cb) client.connect() print('connected to MQTT broker') # The MQTT topic that we publish data to temperature_topic = config.Temperature_TOPIC humidity_topic = config.Humidity_TOPIC while True: try: DHT.measure() lcd.move_to(0, 0) lcd.putstr("Temperature: ") lcd.putstr(str(DHT.temperature())) lcd.putstr("C") lcd.move_to(0, 1) lcd.putstr("Humidity: ") lcd.putstr(str(DHT.humidity())) lcd.putstr("%") sleep_ms(1000) temperature = DHT.temperature() humidity = DHT.humidity() except: pass # Here, we publish the data to the broker, under topic client.publish(topic=temperature_topic, msg=str(temperature)) client.publish(topic=humidity_topic, msg=str(humidity)) client.check_msg() print("Send data to MQTT broker, sleeping for 5 minutes...") time.sleep(300) # Wait 5 minutes (300 seconds) ``` **Connecting to Wi-Fi** We create a file called boot where we establish the Wi-fi connection. ``` import network import config sta_if = network.WLAN(network.STA_IF) if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(config.WIFI_SSID, config.WIFI_PASS) while not sta_if.isconnected(): pass print('network config:', sta_if.ifconfig()) ``` In above mentioned boot file we import a file called config where we save our Wi-Fi and Datacake credentials. How to do this and the code can be found in the LNU guide [here](https://hackmd.io/@lnu-iot/r1aui0B59). **Import DHT11 and I2C LCD1602 modules.** The code for the DHT and LCD can be found [here](https://github.com/Freenove/Freenove_Ultimate_Starter_Kit_for_ESP32/tree/master/Python/Python_Codes/24.2_Hygrothermograph). ``` from time import sleep_ms from machine import I2C, Pin from I2C_LCD import I2cLcd import dht ``` **Assign Pin(18) to DHT11, Pin(13) and Pin(14) to LCD160.** ``` DHT = dht.DHT11(Pin(18)) DEFAULT_I2C_ADDR = 0x27 i2c = I2C(scl=Pin(14), sda=Pin(13), freq=400000) lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) ``` **Measure and display data.** Here we create a while loop that runs indefinitely obtaining the data of the DHT11, displays it on the LCD and then sleeps 1 second. The first line displays temperature + "C" and the second line displays humidity + "%"". ``` while True: try: DHT.measure() lcd.move_to(0, 0) lcd.putstr("Temperature: ") lcd.putstr(str(DHT.temperature())) lcd.putstr("C") lcd.move_to(0, 1) lcd.putstr("Humidity: ") lcd.putstr(str(DHT.humidity())) lcd.putstr("%") sleep_ms(1000) temperature = DHT.temperature() humidity = DHT.humidity() except: pass ``` **Publish data to Datacake** We publish the data to Datacake every 5 minutes under the topic subject. This is more frequent than necessary for most people. Since I’m not running the device on battery currently and that we’ve got a balcony door and windows that are frequently opened for ventilation the temperature and humidity normally differs. ``` client.publish(topic=temperature_topic, msg=str(temperature)) client.publish(topic=humidity_topic, msg=str(humidity)) client.check_msg() print("Send data to MQTT broker, sleeping for 5 minutes...") time.sleep(300) # Wait 5 minutes (300 seconds) ``` ## Transmitting the data / connectivity I'm transmitting the data over Wi-Fi since my ESP32 only supports that and Bluetooth. It also seems to be appropriate since I'll have it stationary inside of the apartment always in rage of my router. The data is sent every 300 seconds (five minutes) to Datacake’s MQTT broker, which is the transport protocoll I decided to use. They're packaged as two different topics: Temperature and humidity. That should add up to 288 transmissions per day which is well within the 500 datapoints that Datacake gives us for free. The device is also always connected to the outlet using the phone charger, so I'm not concerned regarding power consumption. I would change the frequency of my messages and how often the devices measures and displays the data on the LCD if I ran it on battery. ## Presenting the data The dashboard is built with widgets that displays the current temperature and humidity and charts showing of the last 24 hours and the last weeks trends. You can do much more with the visualization. You can also set up notifications e.g., if you want to get notified when the temperature or humidity goes above or belove a certain value. I've not experimented much with this myself but that's something I hope to explore further on. ![](https://i.imgur.com/cN9OCnn.png) ![](https://i.imgur.com/14MkxUX.png) ![](https://i.imgur.com/B796AM0.png) ![](https://i.imgur.com/wfkkpv2.png) ## Finalizing the design There are many things that could have gone differently. For example, it took until the last minute to realize that I didn't need a couple of jumper wires that I had connected to the bread board that wasn't necessary. One way to evolve this project further could have been to add a pH sensor to understand how the surrounding climate and time effect the sourness of a dough. Utilizing this data in order to bake the perfect bread. I feel like I've learned a lot and I feel like I've been bitten by the bug and am sure I'll explore much more of what IoT has to offer. Cheers to many more projects and loafs of bread in the future. ![](https://i.imgur.com/iEyC6uH.jpg) ![](https://i.imgur.com/ZEQnZZY.jpg)