Raspberry Pi Pico Send DHT22/DHT11 Sensor Readings to ThingSpeak

In this user guide, we will learn how to publish DHT22/DHT11 sensor readings to ThingSpeak using Micropython, Raspberry Pi Pico, and ESP-01 module. We will use Thonny IDE to program our Raspberry Pi Pico board which will be connected to a DHT22 temperature and humidity sensor. Our main aim is to transmit these sensor readings to ThingSpeak easily and interactively demonstrate them. Any appropriate sensor can be used such as DS18B20, BME680, LM35, and MPU6050 but for this article, we will use a DHT22 sensor which is used to measure temperature and humidity.

Raspberry Pi Pico Send DHT22 DHT11 Sensor Readings to ThingSpeak

Raspberry Pi Pico does not support Wi-Fi capabilities hence we have to use a separate Wi-Fi module to enable Wi-Fi connectivity. Therefore, we will interface and program ESP-01 Wi-Fi module with Raspberry Pi Pico to enable Wi-Fi features. We will use Thonny IDE to program Raspberry Pi Pico with ESP-01 and DHT22 in MircoPython. We will use AT commands through the serial port that is UART to configure the ESP-01 Wi-Fi module.

The following content will be covered in this article:

  1. Introduction to DHT11/DHT22 sensor
  2. Connecting Raspberry Pi Pico with DHT22 and ESP-01 Wi-Fi module
  3. Getting ThingSpeak API Ready
  4. Publish to multiple fields of sensor readings to ThingSpeak (Temperature and humidity)

We have similar guides with BME280 and DS18B20:

Prerequisites

Before we start this lesson make sure you are familiar with and have the latest version Python 3 in your system, have set up MicoPython in Raspberry Pi Pico, and have a running Integrated Development Environment(IDE) in which we will be doing the programming. We will be using the same Thonny IDE as we have done previously when we learned how to blink and chase LEDs in micro-python. If you have not followed our previous tutorial, you check here:

If you are using uPyCraft IDE, you can check this getting started guide:

Recommended Readings:

DHT11/DHT22 Introduction 

The DHT11/DHT22 is a sensor which measures relative humidity and temperature sensor. It provides a calibrated digital output with a 1-wire protocol. Both sensors are inexpensive. They are quite similar to each other with some differences in specifications. 

DHT22 is almost similar to the DHT11 but the former measures temperature and humidity with higher accuracy and supports a wider range.

DHT11 vs DHT22

The following table lists the comparison of both DHT sensors. 

DHT22DHT11
Temperature-40 to 80 ºC +/- 0.5ºC0 to 50 ºC +/-2 ºC
Humidity0 to 100% +/-2%20 to 90% +/-5%
ResolutionHumidity: 0.1%Temperature: 0.1ºCHumidity: 1%Temperature: 1ºC
Operating Voltage3- 6 V DC( directly power able from Raspberry Pi Pico)3-5.5 V DC( directly power able from Raspberry Pi Pico)
Sampling time2 seconds1 second
Current rating$4 to $10$1 to $5
Output data typefloatint
Pinout4-pin (same as DHT11)4-pin (same as DHT22)
Price52

As you can see from the above comparison table that DHT22 offers wider temperature range and resolution for temperature and humidity. But it is more expensive than DHT11. However, DHT11 has a better sampling period. Furthermore, the operating voltage range for both sensors is almost and we can directly power these sensors from power pins of Raspberry Pi Pico. 

Regardless of above differences, both DHT sensors have the same working principle and same pinout. We can use the same MicroPython script to read temperature and humidity readings by selecting DHT type inside the code. 

DHT sensors are pre-calibrated. We can directly connect them with Raspberry Pi Pico to obtain sensor output reading. They are internally composed of a humidity sensing sensor and a thermistor. These two components measure humidity and temperature. 

DHT11/DHT22 Pinout 

The following figure shows the pinout diagram of DHT sensors. DHT sensor consists of four pins. But on DHT modules only three pins are exposed to the pinout of the module and10k ohm pull-up resistor is internally connected to pin 2. 

pinout DHT11 and DHT22

Pin Description

The following lists the pinout of the DHT sensor and their brief description. Pin number starts from left to right when you hold the sensor from the front end. 

DHT11/DHT22 PinConnection with Raspberry Pi Pico
1 ( VCC)3.3V
2 (Data Out)Any GPIO pins of Raspberry Pi Pico along with 10k ohm pull-up resistor
3 (NC)Not used
4 (GND)Ground
  • Vcc is the power supply pin. Apply voltage in a range of 3.3 V to 5.0 V to this pin
  • Data Out is the digital output pin. It sends out the value of measured temperature and humidity in the form of serial data
  • N/C is not connected
  • GND: Connect the GND pin 

Interfacing Raspberry Pi Pico with DHT22 and ESP-01

Raspberry Pi Pico with DHT22 and ESP-01

This section shows how to connect Raspberry Pi Pico with DHT22 sensor and ESP-01.

Parts Required 

We will require the following components:

  • Raspberry Pi Pico
  • DHT22 Sensor
  • 10K ohm resistor (not required if using the module version of the sensor)
  • ESP-01 Module
  • Connecting Wires
  • Breadboard

Raspberry Pi Pico with DHT22

Connect the DHT22 to Raspberry Pi Pico along with a 10K ohm pull-up resistor.

  • The first pin for both sensors is a power supply(Vcc) pin. Connect it with the 3.3 volt pin of Raspberry Pi Pico.
  • Data out is the pin through which we get temperature and humidity samples from the DHT sensor. Connect this pin with GP16 of Raspberry Pi Pico and also connect the data pin with a 10k pull-up resistor. But you can also use any digital pin of Raspberry Pi Pico as well.

A Pull-up resistor is used to keep the data pin high for proper communication between the microcontroller and sensor. You can check the datasheet of DHT11 and DHT22 to get more information about it. DHT22 is also known by the name of AM2302.

  • Third pin is not used
  • Connect the fourth pin (GND) to the ground pin of the board

The connections between the two devices which we are using can be seen below.

DHT22Raspberry Pi Pico
VCC3.3V
Data Out GP16 along with 10k ohm resistor
NC
GNDGND

We have used the same connections as specified in the table above.

Raspberry Pi Pico with ESP-01

The ESP-01 module consists of 8 pins. However we will use 5 pins to connect with the Pi Pico board. These include the VCC, EN, GND, RX and TX pins. RX and TX pins of the module will be connected with the UART pins of the Pi Pico board. Let us first have a look at the Raspberry Pi Pi UART Pins.

Raspberry Pi Pico UART Pins

Raspberry Pi Pico contains two identical UART peripherals with separate 32×8 Tx and 32×12 Rx FIFOs.

Raspberry Pi Pico pinout diagram

The following table lists the GPIO pins for both UART peripherals which are exposed on Raspberry Pi Pico development board pinouts. 

UART PinsGPIO Pins
UART0-TXGP0/GP12/GP16
UART0-RXGP1/GP13/GP17
UART1-TXGP4/GP8
UART1-RXGP5/GP9

For this guide, we will use UART0-TX and RX pins.

Follow the connection diagram below to connect the two devices.

Raspberry Pi PicoESP-01
3.3VVCC
3.3VEN
GNDGND
GP1 (UART0 RX)TX
GP0 (UART0 TX)RX

Connection Diagram Raspberry Pi Pico with DHT22 and ESP-01

We have used the same connections as given in the two tables above. All three devices will be commonly grounded and will be powered with the same 3.3V pin of Raspberry Pi Pico.

The diagram below shows the connection diagram of Raspberry Pi Pico with DHT22 and ESP-01.

Raspberry Pi Pico with DHT22 and ESP-01 connection diagram
Raspberry Pi Pico with DHT22 and ESP-01 connection diagram

Getting ThingSpeak API Ready

ThingSpeak is an open-source API that is used to store or retrieve data using HTTP or MQTT protocol. This takes place over the Internet or through the LAN. We will use this API to publish sensor readings from DHT22 integrated with our Raspberry Pi Pico board. In ThingSpeak you can access your data from anywhere in the world. You can display your data in plots and graphs.

For more information about ThingSpeak API, you can have a look at our previous ESP32/ESP8266 tutorials given below:

Creating Account

ThingSpeak API is free to use but we will have to create a MathWorks Account.
First go to the following website: https://thingspeak.com/
The following window will appear. Click on the ‘Get Started for Free’ button.

ESP32 HTTP ThingSpeak get started

Now you will be redirected to the account window. If you already have an existing MathWorks account you can use that to log in. Otherwise, you will have to create a new one. Click ‘Create One!’ to make a new MathWorks account.

ESP32 HTTP ThingSpeak account

When you have successfully signed in you will receive the following notification:
Click ‘OK’.

ESP32 HTTP ThingSpeak account successful

Publish to multiple fields of sensor readings to ThingSpeak (Temperature and humidity)

We will start by creating a new channel for our project. Go to Channels > My Channels. Then click ‘New Channel’.

ESP32 HTTP ThingSpeak new channel

You will be prompted to give a name to your channel. We will give a name, and some description and mark the first field. In this section, we will show you how to publish multiple data. You can use any name, description, and field according to your preference. There are a total of eight fields that we can add to our channel at the same time. We will tick the first two fields and add the names. Click ‘Save Channel’ to proceed.

DHT22 Sensor Readings to ThingSpeak with Raspberry Pi Pico (1)

Your channel will now be created.

DHT22 Sensor Readings to ThingSpeak with Raspberry Pi Pico (2)

Go to private view and click the pencil icon on top of each Field Chart. This will let us customize the graphs according to our preference. You can add details accordingly. After you press the Save button, the chart will get updated to the settings you just set.

DHT22 Sensor Readings to ThingSpeak with Raspberry Pi Pico (3)

After that go to the API key tab and click it. You will now be able to access your unique API key. Save it and keep it secure as you will need it later in the program code.

DHT22 Sensor Readings to ThingSpeak with Raspberry Pi Pico (4)

Raspberry Pi Pico & ESP-01 ThingSpeak MicroPython Sketch (DHT22)

Open your Thonny IDE and go to File > New to open a new file. Copy the code given below in that file. You just have to replace the network credentials and your ThingSpeak API key.

import uos
import machine
import utime
from machine import Pin
import dht

myHOST = 'api.thingspeak.com'
myPORT = '80'
myAPI = '****************'

print()
print("Machine: \t" + uos.uname()[4])
print("MicroPython: \t" + uos.uname()[3])

sensor = dht.DHT22(Pin(16))

uart0 = machine.UART(0, baudrate=115200)
print(uart0)

def Rx_ESP_Data():
    recv=bytes()
    while uart0.any()>0:
        recv+=uart0.read(1)
    res=recv.decode('utf-8')
    return res
def Connect_WiFi(cmd, uart=uart0, timeout=3000):
    print("CMD: " + cmd)
    uart.write(cmd)
    utime.sleep(7.0)
    Wait_ESP_Rsp(uart, timeout)
    print()

def Send_AT_Cmd(cmd, uart=uart0, timeout=3000):
    print("CMD: " + cmd)
    uart.write(cmd)
    Wait_ESP_Rsp(uart, timeout)
    print()
    
def Wait_ESP_Rsp(uart=uart0, timeout=3000):
    prvMills = utime.ticks_ms()
    resp = b""
    while (utime.ticks_ms()-prvMills)<timeout:
        if uart.any():
            resp = b"".join([resp, uart.read(1)])
    print("resp:")
    try:
        print(resp.decode())
    except UnicodeError:
        print(resp)
    
Send_AT_Cmd('AT\r\n')          #Test AT startup
Send_AT_Cmd('AT+GMR\r\n')      #Check version information
Send_AT_Cmd('AT+CIPSERVER=0\r\n')      #Check version information
Send_AT_Cmd('AT+RST\r\n')      #Check version information
Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings
Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode
Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the Wi-Fi mode = Station mode
Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode again
Connect_WiFi('AT+CWJAP="YOUR_SSID","YOUR_PASSWORD"\r\n', timeout=5000) #Connect to AP
Send_AT_Cmd('AT+CIFSR\r\n',timeout=5000)    #Obtain the Local IP Address
Send_AT_Cmd('AT+CIPMUX=1\r\n')    #Obtain the Local IP Address
utime.sleep(1.0)
print ('Starting connection to ESP8266...')
while True:
    sensor.measure()
    temp = str(sensor.temperature())
    hum = str(sensor.humidity())
    print('Temperature: ', temp)   
    print('Humidity: ', hum)
    
    print ('!About to send data to thingspeak')
    sendData = 'GET /update?api_key='+ myAPI +'&field1='+temp +'&field2='+hum
    Send_AT_Cmd('AT+CIPSTART=0,\"TCP\",\"'+ myHOST +'\",'+ myPORT+'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd('AT+CIPSEND=0,' +str(len(sendData)+4) +'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd(sendData +'\r\n')
    utime.sleep(4.0)
    Send_AT_Cmd('AT+CIPCLOSE=0'+'\r\n') # once file sent, close connection
    utime.sleep(4.0)
    print ('Data send to thing speak')

How the Code Works?

We will start by importing the machine module and the uos module. We will also import the Pin class from the machine module. This is because we have to specify the GPIO pin connected with the data pin of DHT22 sensor. We also import the utime module so that we will be able to add a delay in between our readings. Also, import the dht library.

import uos
import machine
import utime
from machine import Pin
import dht

Then, we will print the information about our current operating system in the Thonny shell terminal. We will uos.uname() and print the operating system version and release.

print()
print("Machine: \t" + uos.uname()[4])
print("MicroPython: \t" + uos.uname()[3])

Next, we will define a dht object named ‘sensor’ and assign the data pin to it. Here we are using DHT22 sensor with data pin connected at GP16. If using DHT11 replace ‘DHT22’ with ‘DHT11’ and change the pin number appropriately.

sensor = dht.DHT22(Pin(16))

Initialize UART Communication

Then we will create an uart object by using UART() and specify the UART channel as the first parameter and the baud rate as the second parameter. We are using UART0 in this case with baud rate 115200 for the uart communication. ESP8266 has a default baud rate of 115200 hence we will use the same baud rate here for Raspberry Pi Pico UART communication in order to create synchronization. Moreover we will also print the UART details in the shell terminal.

uart0 = machine.UART(0, baudrate=115200)
print(uart0)

Also, include the ThingSpeak host, port and write API key to successfully publish readings to the API. Make sure to replace your API key in the place specified by ‘****************’

myHOST = 'api.thingspeak.com'
myPORT = '80'
myAPI = '****************'

This Connect_WiFi() function is used to connect ESP8266 with WiFi.

def Connect_WiFi(cmd, uart=uart0, timeout=3000):
    print("CMD: " + cmd)
    uart.write(cmd)
    utime.sleep(7.0)
    Wait_ESP_Rsp(uart, timeout)
    print()

Next, we will define three functions. The first one is Rx_ESP_Data(). This reads the serial data being received. This data is decoded from UTF-8 format and returned.

def Rx_ESP_Data():
    recv=bytes()
    while uart0.any()>0:
        recv+=uart0.read(1)
    res=recv.decode('utf-8')
    return res

The second function is Send_AT_Cmd(cmd, uart=uart0, timeout=3000). It takes in three parameters, the AT command, the UART channel and the response time. This function will be used to it send an AT command to ESP8266 via uart0. The response time is set to 3 seconds.


def Send_AT_Cmd(cmd, uart=uart0, timeout=3000):
    print("CMD: " + cmd)
    uart.write(cmd)
    Wait_ESP_Rsp(uart, timeout)
    print()
    

The Wait_ESP_Rsp(uart=uart0, timeout=3000) function waits for 3 seconds to get the response from ESP8266. After receiving the data from ESP8266 it concatenates the received bytes and prints them on the shell terminal.

def Wait_ESP_Rsp(uart=uart0, timeout=3000):
    prvMills = utime.ticks_ms()
    resp = b""
    while (utime.ticks_ms()-prvMills)<timeout:
        if uart.any():
            resp = b"".join([resp, uart.read(1)])
    print("resp:")
    try:
        print(resp.decode())
    except UnicodeError:
        print(resp)

AT Commands

Now let us look at the series of AT commands that we will send through UART0 to ESP8266.

Send_AT_Cmd('AT\r\n')          #Test AT startup
Send_AT_Cmd('AT+GMR\r\n')      #Check version information
Send_AT_Cmd('AT+CIPSERVER=0\r\n')      #Check version information
Send_AT_Cmd('AT+RST\r\n')      #Check version information
Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings
Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode
Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the Wi-Fi mode = Station mode
Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode again
Connect_WiFi('AT+CWJAP="YOUR_SSID","YOUR_PASSWORD"\r\n', timeout=5000) #Connect to AP
Send_AT_Cmd('AT+CIFSR\r\n',timeout=5000)    #Obtain the Local IP Address
Send_AT_Cmd('AT+CIPMUX=1\r\n')    #Obtain the Local IP Address
utime.sleep(1.0)
Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')    #Obtain the Local IP Address
utime.sleep(1.0)

AT: This type of command is used to test the startup function of WiFi module. The response would be ok, against this command if everything is ok.

Send_AT_Cmd('AT\r\n')          #Test AT startup

AT+GMR : This type of AT command is used to check the version of AT command and we used SDK version of AT command in this type of WIFI module.

Send_AT_Cmd('AT+GMR\r\n')      #Check version information

AT+CIPSERVER=0: This configures the ESP8266 as server and sets the mode as 0 which means delete server (need to follow by restart)

Send_AT_Cmd('AT+CIPSERVER=0\r\n')     

AT+RST: This type of command is used for reset the WiFi module when it is in working condition. The response would be ok, when reset the module.

Send_AT_Cmd('AT+RST\r\n')   

AT+RESTORE: This type of command is used to restore factory settings means, when this command is entered then all the parameters are reset automatically to default one’s.

Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings

AT+CWMODE? : This type of command is used to query the WiFi mode of ESP8266.

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the WiFi mode

AT+CWMODE=1 : This sets the WiFi mode of ESP8266 in this case in station mode.

Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the WiFi mode = Station mode

AT+CWJAP=”SSID”,”PASSWORD”\r\n’, timeout=TIME_ms : This connects the ESP8266 with an AP whose SSID and password are given, The timeout here is the reconnection time.

Connect_WiFi('AT+CWJAP="YOUR_SSID","YOUR_PASSWORD"\r\n', timeout=5000) #Connect to AP

AT+CIFSR: This command obtains the local IP address.

Send_AT_Cmd('AT+CIFSR\r\n')

AT+CIPMUX=1:This command is used to enable multiple connections (maximum 4)

Send_AT_Cmd('AT+CIPMUX=1\r\n')

AT+CIPSERVER=1: This command configures ESP8266 as server.

Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')

Get DHT22 Sensor Readings and Publish to ThingSpeak

Inside the while loop, we will first we will obtain the temperature and humidity reading and save it in ‘temp’ and ‘hum’ respectively. We use the sensor object on the appropriate method e.g. temperature() to get the temperature reading in Celsius and humidity to get the humidity value in percentage. Additionally, we also convert them to string values.

while True:
    sensor.measure()
    temp = str(sensor.temperature())
    hum = str(sensor.humidity())
    print('Temperature: ', temp)   
    print('Humidity: ', hum)

We will print these sensor readings in the Thonny shell terminal.

    print('Temperature: ', temp)   
    print('Humidity: ', hum)

Finally, we will send these sensor readings to ThingSpeak dashboard.

    print ('!About to send data to thingspeak')
    sendData = 'GET /update?api_key='+ myAPI +'&field1='+temp +'&field2='+hum
    Send_AT_Cmd('AT+CIPSTART=0,\"TCP\",\"'+ myHOST +'\",'+ myPORT+'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd('AT+CIPSEND=0,' +str(len(sendData)+4) +'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd(sendData +'\r\n')
    utime.sleep(4.0)
    Send_AT_Cmd('AT+CIPCLOSE=0'+'\r\n') # once file sent, close connection
    utime.sleep(4.0)
    print ('Data send to thing speak')

We will create a variable ‘sendData’ that contains a GET request that we will make to ThingSpeak to udate the respective fields with the values held in the variables.

sendData = 'GET /update?api_key='+ myAPI +'&field1='+temp +'&field2='+hum

First, we are writing the AT command: AT+CIPSTART=0,\”TCP\”,\”‘+ myHOST +’\”,’+ myPORT+’\r\n’ This command is used to set the port connection and address of port.

Next after a delay of 1 second, we send the AT command: AT+CIPSEND=’ID’, ‘LENGTH’ This will set the length of the data that will be sent. It tells the WI-FI module how many bytes we want to send to the server.

Then we send the data to ThingSpeak via to be pusblished to their respective fields.

After that, we will close the multiple connections as we are sending the AT command: AT+CIPCLOSE=’ID’.

    Send_AT_Cmd('AT+CIPSTART=0,\"TCP\",\"'+ myHOST +'\",'+ myPORT+'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd('AT+CIPSEND=0,' +str(len(sendData)+4) +'\r\n')
    utime.sleep(1.0)
    Send_AT_Cmd(sendData +'\r\n')
    utime.sleep(4.0)
    Send_AT_Cmd('AT+CIPCLOSE=0'+'\r\n') # once file sent, close connection
    utime.sleep(4.0)
    print ('Data send to thing speak')

Demonstration

After you have uploaded your code to Raspberry Pi Pico board head over to the shell terminal. In the Thonny shell terminal you will be able to view the board getting connected. After every few seconds, new sensor readings will keep appearing as they get published to their respective fields.

Raspberry Pi Pico send DHT22 data to ThingSpeak shell terminal

Next, open the ThingSpeak API and you will be able to see temperature and humidity readings updating in your charts.

DHT22 Sensor Readings to ThingSpeak with Raspberry Pi Pico (5)
ThingSpeak Dashboard

Watch the demonstration below to have a better insight:

Conclusion

In conclusion, we were able to learn how to publish DHT22 sensor readings to ThingSpeak using MicroPython and Raspberry Pi Pico using ESP-01 Wi-Fi module in a fairly easy way. Likewise, you can publish single or multiple data to ThingSpeak API which you will be able to access from anywhere around the world.

You may like to read our articles on web servers with Raspberry Pi Pico:

You may also like to read other DHT11 and DHT22 tutorials:

Leave a Comment