---
# System prepended metadata

title: Temperature and humidity measuring using DHT11 and Arudino Nano RP2040 Connect

---

# Temperature and humidity measuring using DHT11 and Arudino Nano RP2040 Connect
by Kristian Åkerblom
ka223hw
Applied IoT summer course 2022

[Github Code](https://github.com/alesbabnik/nano-dht11)

This project was done using the Arudino Nano RP2040 ESP32 board and the DHT11 temperature and humidity sensor. The platform used was Adafruit where I send the data via MQTT over Wifi. 

Completion time: ~2 - 8 hours 
## Table of contents
[TOC]
## Objective
### Why you chose the project
This is probably the most common project since it is so simple, but I mostly chose it because I wanted something easy but useful to work with.

It is also pretty nice to be able to open my phone and check how warm it is at home!

### What purpose does it serve
I will mostly just check how hot it is in my room, on hot summer days I can turn on the AC and leave the room until it is a good temperature again. I would like to do something bigger but I have little time and did not what to be over ambitious and fail my work.

### What insights you think it will give
IoT is something I hear about a lot but I never fully understood it and it seemed really hard and low-level for someone like myself to get into. But it is something I want to try out and learn more about.

## Material

```csvpreview {header="true"}

Material,Amount,Cost,Usage
Arduino Nano RP2040 Connect,1,28 €,Main device for the project.
DHT11 (or DHT22),1,0.75€,Our sensor to measure the temperature and humidity.
LED (optional),2,Cheap!,We could use the on-board LED but I think these are better since they are easier to see.
USB A-male to micro B-male, 1, ~3 €, Used to connect the board to a computer.
```
![](https://i.imgur.com/BEv2iNc.jpg =250x)
I was going for the **Heltec** as a cheap ESP32 alternative, but there were some trouble with the units and I ended up buying the **Nano RP2040** instead. It is a very good device for beginners I'd say and will suit most project perfectly.

I recommend getting a  breadboard if you are going to use LEDs but this project can be done without. I decided to go with a breadboard as base and jumper wires to connect since I will have this device indoors and its very handy to shuffle thing around the board to fit the design. I bought the [Sensor only bundle](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-sensors-only-bundle/) so it gives you all of the things needed. I bought a smaller breadboard and the DHT11 sensor from [Sizable](https://sizable.se/) but the rest were from [Electrokit](https://www.electrokit.com).

## Computer setup

The computer I used is running Windows 10 so this is focused on that. I mainly used Atom for reading the COM4 port and uploading code. I wrote everything using Atom and Vim but you can write it with whatever text editor you want.

Things to install:
- [Node.js](https://nodejs.org/en/)
- [Atom](https://atom.io/)
- [Python](https://www.python.org/downloads/)

And if you are using the Nano RP2040 then follow [this](https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-python-api) tutorial in order to get your micropython working. You have to be careful here if your device is plugged in since the 5v is right next to the pins.
Same for goes for [pymakr](https://docs.pycom.io/gettingstarted/software/atom/) for Atom.

We will use Atom to write and upload the code to our device. You will have to choose the COM port and what project folder you want to upload, in the image below I'm uploading the *src* project folder to my COM4 port which is my RP2040
![](https://i.imgur.com/io4Ierz.png)

There will be a button to upload code in the pymakr menu:
![](https://i.imgur.com/dToApDG.png)
And you should be having a working project, altough yours will not work with the default settings, you will have to change pins and wifi settings to get that working!
![](https://i.imgur.com/rFKsb8C.png)
Example of what it should look like after uploading your project.
## Putting everything together
![](https://i.imgur.com/QxFgmlB.jpg)
You can use any resistors you want, It will only change how bright the LEDs are. I am using 1 Kohm for my green and 330 Ohm red light. 

The red light is the error-light so that it is easy to see whenever an error occured since it will blink bright red while the green running-light is enough to have a visual reperesentation that the board is connected and ready to send data to the Adafruit broker.

**OBS!** Fritzing did not seem to have a DHT11 which was the sensor I used, so I used the LM35 temperature sensor as a replacement for this diagram. But they are very similar in terms of their pins.

```python
    # Pins
    DHT11 = dht.DHT11(Pin(26))
    LED_ON=Pin(27,Pin.OUT)
    LED_ERR=Pin(28,Pin.OUT)
```
I decided to use pin 26, 27 and 28 on my device. You can change these to whatever pins you want to use. Pin 26 is the DHT11 sensor and the two others are the LED
![](https://i.imgur.com/JcXMQiC.png)
Pinout of the RP2040, highlighted area are the pins I used.

## Platform
I first wanted to try making REST API calls from my device so I chose ubidots. However, there seemes to be a problem with the urequest library so I could not POST anything from my device. This was a common problem for ESP32 generic boards and the Heltec so I had to change my plan. 
I found **[this](https://help.ubidots.com/en/articles/1956221-connect-your-esp32-to-ubidots-over-http-using-micropython)** guide on the ubidots website, but it somehow have me an error which I could not find in the documentation for micropython nor on the web.

After some testing around I decided to use Adafruit instead since it uses MQTT and that works for the ESP32 generic boards. It seems very free, fast and reliable from my experience and I highly recommend it! Also lets you store up to 10k pages of data! At the time I'm writing this it is at about 900 pages of data which took about a week of measuring. 

I like that the site has webhooks and API that you can use to integrate it elsewhere. 
(Webhook implementation will be shown later)

```javascript
function updateMyroom() { 
// Fetch request to the adafruit API
  fetch("https://io.adafruit.com/api/v2/{NAME}/feeds/{FEED}/details", {
    headers: new Headers({
      'X-AIO-Key': '{KEY}'
    })
  })    
    .then(response => response.json())
    .then(data => {
      console.log(data)
      temp = data.last_value // The temperature value is stored as last_value in the JSON response
      if (temp < 18)
        emoji = '🥶'
      else if (temp > 24)
        emoji = '🥵'
      else
        emoji = '😊'
      
      let string = emoji + " " + temp + "°C";
      document.getElementById("myroom_text").innerHTML = string;
    });
}
updateMyroom()
```

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

I added a little indicator to my browser startpage so that everytime I open my browser, it will make a fetch call and display the temperature in my room. Its pretty neat and fun to tinker with!

## The code
[Project Code](https://github.com/alesbabnik/nano-dht11)

```python=62
    def send_data(feed, value):
        print("Publishing: {0} to {1} ... ".format(value, feed), end='')
        try:
            client.publish(topic=feed, msg=str(value))
            print("DONE")
            LED_ERR.value(0)
        except Exception as e:
            print("FAILED")
            LED_ERR.value(1)
```
This is the function for sending data via MQTT to the Adafruit broker. If there is any exceptions while sending, then the error light will turn on. This is different from the blinking that occurs when the script crashes.
```python=65
    def led_error():
        LED_ON.value(0)
        while 1:
            LED_ERR.value(1)
            time.sleep(0.5)
            LED_ERR.value(0)
            time.sleep(0.5)
```
Here is the blinking function for when the script crashes. It will blink once every second and the green light turn off. You can only stop it by restarting the device.


```python=79
    try:
        LED_ON.value(1)
        while 1:
            DHT11.measure()        # Update sensor values
            t = DHT11.temperature()
            h = DHT11.humidity()
            send_data(AIO_TEMP_FEED, t - 2)    # Send temperature
            send_data(AIO_HUM_FEED, h)         # Send humidity
            time.sleep(DELAY)
    except:
        led_error()
        client.disconnect()
        client = None
        sta_if.disconnect()
        sta_if = None
        print("Disconnected from Adafruit IO.")
```
This is the heart of the program and it will start the loop of sending data with a delay that you chose. The green light turns on and it will measure the sensot and give variable names for the humidity and temperature that were measures. 
I have a -2 on my temperature because my DHT11 seemed to be about 2 degrees more compared to other temperature sensors in my room.

The error handling will disconnect the device and the red LED will start to blink.
## Transmitting the data / connectivity
This variable determines how fast it should send the data to the broker. It is simply used in a sleep timer each cycle to delay each datapoint sent.
```python=26
    DELAY = 5
```
In this case, I left mine with a high refresh rate. Since it is plugged to the wall I do not need to think about power usage. If it was battery powered then a 60 second delay would be perfectly fine.
```python=38
    sta_if = network.WLAN(network.STA_IF)       # Put modem on Station mode
    if not sta_if.isconnected():                # Check if already connected
        print('Connecting to network...')
        sta_if.active(True)                     # Activate network interface
        sta_if.connect(cred.WIFI_SSID, cred.WIFI_PASS)     # Your WiFi Credential
        # Check if it is connected otherwise wait
        while not sta_if.isconnected():
            pass
    # Print the IP assigned by router
    print('Network config:', sta_if.ifconfig())
```
I decided to go for WiFi since I did not intend to have it outside of the house and didn't buy a LoRa module. The code starts with initializing station mode and if its not connected, then it will activate the network module and use the given credentials from our constants above. If this works then it will print whatever IP address it recieved from the network.

I decided to use adafruit so it uses MQTT to recive the data. Since we are only going to send small numbers, MQTT will suit us perfectly. Its packets only has one 2 byte header and the payload can be up to 260 MB. It is also secure since it uses a key and username for verifying the sender. It is commonly used in IoT so I thought it would be nice to learn it too.

We will have to use a library in order to use this protocol but it is very easy to set up. We have a library for MQTT and we will have to set up a client and give it the right credentials in order to send out data to Adafruit.
```python
    # Just an example of the configuration
    AIO_SERVER = "io.adafruit.com"
    AIO_PORT = 1883
    AIO_USER = "USERNAME"
    AIO_KEY = "aio_XXXXXXXXXXXXXXXXXXXXXX"
    AIO_CLIENT_ID = "ANYTHING GOES HERE ITS JUST AND ID"
    AIO_FEED = "USERNAME/feeds/FEEDNAME"
```
![](https://i.imgur.com/e24L7Aa.png)
```python
# MQTT Client to send data
client = MQTTClient(AIO_CLIENT_ID, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY)
```
You will have to get your keys from Adafruit, there should be a yellow key symbol and it will show you all of the stuff needed to be able to connect. You will have to get your feeds too and you can create as many as you want, you will have to call the send_data function for all your feeds.
```python
send_data(AIO_1_FEED, data_a)
send_data(AIO_2_FEED, data_b)
send_data(AIO_3_FEED, data_c)
```
Kinda like this. Just make sure *AIO_1_FEED*, *AIO_2_FEED* and *AIO_3_FEED* have their own feeds so that you do not send to the same feed.
## Presenting the data
![](https://i.imgur.com/FJhd8Ed.png)
This is the Adafruit dashboard. The first line chart is humidity and the one next to it is temperature, they show the last 2 days of data. At the bottom we have both of the line charts showing a whole week. The data is a little weird since the device shut itself for two days. 

The data policy will let you update your data 60 times a minute, this includes delete, create and update. The data will only be stored for 30 days but that is good enough for most use cases and if you really want to store the data longer then you can download everything and store it locally.

Since the rate limit is so high, my fast 5 second delay won't hit the limit and it is already more than enough for just measuring temperature.

Adafruit also has a built-in webhook so we can insert a discord webhook to your server and have it give warning if your feed hits a certain threshold.

On discord just go to: **Server settings** > **Integrations** > **Webhooks** and create the webhook bot that you want. You have to copy the link and paste it in your Adafruit **Action** tab. 
The tab is very self explanatory and all you have to do is to give it the URL from discord, the rules for when a message should be sent and limit how often it can send the message.
![](https://i.imgur.com/z5GvnV7.png)
In this example everytime my room is above or equal to 26 degrees it will give me a warning to cool down my room!
![](https://i.imgur.com/HuNVEr7.png)

![](https://i.imgur.com/LTlcJFA.png)
Final result after adding the webhook.

## Finalizing the design
I think this project was really fun and it felt great when everything was working. I did think my project was a little too easy since I did not run into that many problems except some libraries having some trouble and nearly frying my board the first day I got it. 
I was not that creative but I it is definatley something I want to continue working on outside of this course and the wiring part was fun to fiddle around with.
This project changed my view of how simple IoT can be and it was really rewarding to get things to work the way I wanted them to.
![](https://i.imgur.com/2p7LeVJ.png )
Its very compact and neat looking! The jumper wires are very long since they did not have any shorter.
![](https://i.imgur.com/yBVyt5Z.jpg )

If I got a chance to redo this project then I would have used my other temperature sensor that I got from the lnu sensor bundle and have it outside so that I could have both inside and outside temperature. Would be cool to have a seven segment display for the temperature but it looked way too hard to tackle for this project.
Would also love to try LoRa and a battery powered device!