Real-Time Temperature and Humidity Sensing for $23

Aryan Jha
6 min readDec 12, 2022

Changes in temperature and humidity can be pretty bad for many things. For example, medicine can not be stored at temperatures above 30°C or 60% humidity before the medicine starts degrading or even becoming toxic. The ideal temperatures for plants are between 15 and 24°C, and the ideal humidity is 40–60%. Anything outside this can lead to plants getting diseases, not growing well, and even dying.

We don’t want this happening.

Obviously, we would like to avoid this, but there aren’t many easy ways to regulate the temperature and humidity of a place all the time without some costly and power-hungry implementations like running a fan 24/7. This also has the drawback of sometimes letting the humidity or temperature reach too low, which can have adverse effects as well.

What we need is a low power, low cost solution that adjusts based on the current temperature or humidity.

Luckily, this is possible due to the power of the Internet of Things.

If you want a quick overview of this project, check out my video.

Internet of Things

If you aren’t familiar with the Internet of Things, you might need a quick introduction.

The Internet of Things includes sensors, microcontrollers, and other devices. These talk to each other to do things like turn the light on when presence is detected, or turn off the AC when it gets too cold. This is very powerful, as you can run code only when a certain condition is met. This is exactly what I will be doing in this project.

The Idea

The setup I’m looking for is one where a temperature sensor/humidity sensor sends the data to a microcontroller, where, based on the current temperature and humidity, controls a fan. This fan would reduce the current temperature/humidity when spinning, and let it rise/stay the same when it isn’t spinning.

The current humidity and temperature should be able to be seen on a web interface, so it is easy to identify if there is a problem.

A diagram of the system.

Building It

After identifying what I need, I came up with a parts list.

  • Microcontroller: Raspberry Pi Pico
    This is a cheap microcontroller, and it came with pre soldered pins for easier use.
  • Sensor: DHT11 Humidity and Temperature sensor
    This sensor is cheap, and is good enough.
  • Fan: Noctua NFA4x20 fan 5V
    I had this fan lying around, and it took 5V power, which works for me. If you didn’t want to control the temperature, the first 2 products are all you need. If you do, you will need this and the breadboard as well.
  • Breadboard: Generic breadboard
    This made it easier for me to connect everything, and I was able to use the 5V power for two things at once.

After ordering and receiving these parts, I put it together.

The blue is the DHT11 sensor. The green is the Pi Pico, and the brown is the fan.

The Software

There are two parts to the software: The microcontroller side and the web interface side.

Microcontroller

The microcontroller side consists of reading the sensor data and controlling the fan speed based on that. Because of the limitations of the Raspberry Pi Pico, the code was all written in MicroPython. If you want to follow this tutorial, you will need the Thonny IDE (and suffer through the lack of dark mode option) to run this on your Pi Pico.

The code is very simple. First, we import the libraries needed and define our variables.

from machine import Pin, PWM
from time import sleep
import dht
import os
import sys
from machine import UART

# Fan settings
PWM_PIN = 14
pwm0 = PWM(Pin(PWM_PIN))
PWM_FAN_FREQUENCY = 25_000
maxfan = 65_535
sixtypercentfan = (maxfan * 3) // 5

# Defining Sensor
DHTsensor = dht.DHT11(Pin(22))

This next code is pretty simple as well. First, it measures the temperature and humidity. Then, based on that, it sets the fan speed to either 60%, 100%, or 0%. It prints the temperature and humidity data, so the computer can read it to update the web interface.

while True:
try:
# Sensor only reads every 1 second, so we have to wait 1 second
sleep(1)
# DHT11 measuring
DHTsensor.measure()
temp = DHTsensor.temperature()
hum = DHTsensor.humidity()

# Fan setting
if hum >= 50 or temp >= 23:
pwm0.duty_u16(sixtypercentfan)
elif hum > 60 or temp >= 24:
pwm0.duty_u16(65_535)
else:
pwm0.duty_u16(0)
# Print data, which will be read by computer
print(str(temp) + 'a' + str(hum))

except OSError as e:
pwm0.duty_u16(0)
print('Failed to read sensor.')
except KeyboardInterrupt:
pwm0.duty_u16(0)
# Run an error to stop the program
exit()

The reason I add the letter “a” in between is to add a character to separate the two values. This makes it easier to split the data into the temperature and humidity again for the web interface part.

Saving this as main.py on the Pi makes it run at startup/when power is plugged in. This is very important, as since the serial port will be used by the web interface, we can’t have the IDE open at the same time.

Web Interface

I had no prior experience with Django (the web framework I chose to use), so I had to learn that first. Because of this, the code is definitely not perfect, so if you have any corrections/suggestions, they would be greatly appreciated.

I followed this tutorial until the end. Once at polls/views.py, I wrote this code to import the required libraries.

from django.shortcuts import render
from django.http import HttpResponse
import serial

This code actually updates the webpage. First, it connects to the serial device (our Pi.) You may need to update the port (“COM5” in this case) to what your Pi is connected to on your computer. It reads the bytes, then decodes it to turn it into a string. It splits the string, using the “a” character we added earlier to separate the parts into the temperature data and the humidity data.

It adds strings to those to display it more clearly, then recombines them, converts them to bytes, and displays them at localhost:8000/polls.

def index(request):
s = serial.Serial("COM5", 115200)
t = s.read(7)
s.close()
t = t.decode('utf-8')
print(t)
t, h = t.split('a')

temperaturestring = ("Temperature: ")
currentresponse = temperaturestring + t
humiditystring = (" Humidity: ")
currentresponse = currentresponse + humiditystring + h
currentresponse = currentresponse.encode('utf-8')

return HttpResponse(currentresponse)

The end result looks a bit like this.

Very simple, but it could easily be made better by a good front-end developer.

Improvements

Obviously, this isn’t a perfect solution. Some things I’d work on to make this better are:

  • Connecting the Pi Pico to a wireless capable microcontroller to update the web interface locally
  • Making a prettier front-end design
  • Putting it all in a compact case for easier use

Possible Applications

  • Medicine Storage
    As mentioned before, medicine can be very temperature or humidity sensitive. Many people depend on medicine, and if it degrades or becomes ineffective, their life can become much worse. This simple project can make sure that this doesn’t ever happen.
  • Farming
    Another example I mentioned before, plants need optimal conditions to grow. If it is too hot or humid, you might not be able to grow enough fruit to sell. Obviously, it wouldn’t work great in a huge field, but indoor spaces or many fans would definitely make a large difference.
  • Other IoT Devices
    IoT devices can be very simple or very complex. Complex systems can run hot, so simple cooling solutions are great. Resistors create heat when reducing the current, which can heat up other parts of the system. A compact system could be sold for pretty cheap, and could help solve many problems with IoT device temperatures.

Conclusion

The Internet of Things is a very powerful tool, with projects like mine being able to make an impact in many different areas. Though it is quite simple, it shows the power and reach of this technology.

If you are interested in this technology, check out my other article on a project that was more software-based.

Where to Buy

DHT11 Temperature Sensor ($10) https://www.amazon.com/Ardest-DHT11-Temperature-Humidity-Raspberry/dp/B07QQKFQ47/ref=sr_1_8?crid=3AEBV35WNOD89

Raspberry Pi Pico Microcontroller ($13): https://www.amazon.com/Raspberry-Pre-Soldered-Microcontroller-Development-Dual-Core/dp/B08X7HN2VG/ref=sr_1_14?crid=GK4J63F0B44R

Breadboard (optional) ($7): https://www.amazon.com/EDGELEC-Breadboard-Optional-Assorted-Multicolored/dp/B07GD2BWPY/ref=sr_1_1_sspa?crid=3IKZMM03ZUQGF

Jumper Wires 120 pcs ($7) (optional): https://www.amazon.com/EDGELEC-Breadboard-Optional-Assorted-Multicolored/dp/B07GD2BWPY/ref=sr_1_1_sspa?crid=3IKZMM03ZUQGF

40mm NF-A4x20 fan ($15) (optional): https://www.amazon.com/Noctua-NF-A4x20-FLX-Premium-40x20mm/dp/B072JK9GX6/ref=sr_1_3?crid=2WUQ46JYFS3JQ

--

--