Skip to main content
Chemistry LibreTexts

2: DHT 22 - Streaming Temperature and Humidity Data

  • Page ID
    434335
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    In this lesson, we will connect the DHT22 temperature and humidity sensor and stream readings to a Google Sheet. DHT22 is one of the most common IOT temperature and humidity sensors, it can measure temperature between -40°C and 80°C (±1°C) and humidity from 0% to 100% (±1%).

    To start:

    1. You can use the same Google Sheet that you've created last time (Upload Data to Google Sheet)
    2. Add a new tab to your Google Sheet.
    3. Name columns "DateTime", "Temperature, C" and "Humidity, %"
    4. Rename the worksheet (the tab at the bottom) to "DHT22" by right-clicking on it and selecting "Rename". This way you can always find your data quickly.
    clipboard_e4a07fa8cd04eede61adeb91682cb3a3b.png
    Figure \(\PageIndex{1}\): Rename the worksheet (CC0; E. Lisitsyna)

    Fritzing Diagram

    Any time you need to connect a sensor to your Raspberry Pi, you should start with searching the web for the pinout of that sensor. If you search for "DHT22 pinout" you will find many images similar to the one below.

    clipboard_ee7b11a6b9d8bcb7470b1461f276df36e.png
    Figure \(\PageIndex{2}\): DHT22 Pinout (CC0; E.Lisitsyna)

    As you can see, DHT22 has 4 pins: VCC, Data Out, N/C and Ground. N/C stands for “Not connected” and is not used for wiring. You can connect the DHT22 sensor directly to your Raspberri Pi's GPIO pins using a male-to-female jumper wires, or you can use a T-cobbler and a breadboard. We will be using a breadboard for this lesson.

    • Pin#1 is connected to hot rail
    • Pin#2 is connected to GPIO4 and a "pull-up" resistor
    • Pin#4 is connected to ground rail

    Remember, that we are not using pin#3. If your T-cobbler doesn't have built-in connections to hot and ground rails, you will need to run wires from the cobbler's 3.3 V to hot (red) rail and GND to ground (blue) rail. We will also add a 10 kΩ resistor between the data out pin and hot. Remember the GPIO pin has two values, on (3.3 V) or off, and this pulls it to high as the default position. Note, GPIO pins 1 through 8 of the Broadcom BCM2711B0 are pulled up by default (see page 77, the alternative GPIO assignments table of the datasheet), but we will run a pull-up resistor to ensure this. Here is the Fritzing connection diagram:

    clipboard_e7ec65310505e971ec8a5d514da420d6c.png
    Figure \(\PageIndex{3}\): DHT22 connection diagram. You are using a 10 kΩ pull-up resistor (CC0; E.Lisitsyna)

     

    Python Code

    Let's test the sensor. We will need to install a few things first. Open the terminal and execute the following commands: Note, if you are using the Debian Bookworm or newer operating system you will need to install these packages in a virtual environment, and you should go to section 5.12.2 Thonny-Virtual Environments for instructions on how to set up the virtual environment on your Raspberry Pi.

    pip3 install adafruit-circuitpython-dht
    

    If the above code does not work you need to do this in a venv (virtual environment), where you define the path of pip3 in the virtual environment

    /home/pcomp/Desktop/2024_pcomp/ASN9_DHT22/bin/pip3 install adafruit-circuitpython-dht
    sudo apt-get install libgpiod2

    We install the gspread module during one of the previous lessons, but if you are starting with a new Raspberry Pi you will need to install it again with the following command:

    pip3 install gspread

    remember you may need to give the path to pip3 in your venv

    Now run the following program in Thonny:  

    #!/home/pcomp/Desktop/2024_pcomp/ASN9_DHT22/bin/python3
    #note the above shbang goes to python in venv
    
    #Import the modules
    import time
    import board
    import adafruit_dht
    
    #Declare the sensor and the GPIO pin it is connected to
    dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False)
    
    while True:
        try:
            # Print the values to the serial port
            tempC = dhtDevice.temperature
            humidity = dhtDevice.humidity
            print(f"Temp: {tempC} C    Humidity: {humidity}% ") 
            time.sleep(10.0)  #pause for 10 seconds
        except RuntimeError:
            pass
    
    Exercise \(\PageIndex{1}\)

    Examine the code. What do you think is the purpose of the “try – except” block?

    Answer

    DHT22 can fail unexpectedly and return a Runtime Error, that looks like this:

    clipboard_e0671bea6fbf50eba489a7ed6986cf79d.png

    This would stop your code, and you would have to restart it manually. To prevent this from happening, we add the “try-except” block that basically tells our program to try to run this code and if the specified error occurs to pass (or ignore) it. This way the loop continues.

    Be careful using the "try-except" block. Errors are usually signaling that something is wrong with your code or wiring, and you can miss that message if you are ignoring the errors you shouldn't be ignoring. Runtime Error is a known issue with the DHT22 sensors, so it is safe to use for this lesson.

    You can learn more about Runtime Errors and how they are different from Syntax Errors here

    If you want, you can add a print statement to alert you that an error had occurred, so you can see how often it happens. 

        except RuntimeError:
            print ("Runtime Error. Continue...")
            pass
    

     

    Stream DHT22 Data to Google Sheets

    #!/usr/bin/python3
    
    import datetime
    import time
    import board
    import adafruit_dht
    import gspread
    from google.auth.transport.requests import AuthorizedSession
    from google.oauth2 import service_account
    import requests
    
    dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False)
    
    #Access Google API
    googleAPI = '/home/pi/1_PythonScripts/mydata-key.json' #NOTE: replace this with the path to your JSON key
    scope = ['https://www.googleapis.com/auth/drive']
    credentials = service_account.Credentials.from_service_account_file(googleAPI)
    scopedCreds = credentials.with_scopes(scope)
    gc = gspread.Client(auth=scopedCreds)
    gc.session = AuthorizedSession(scopedCreds)
    sheet = gc.open("DHT22_Data")
    worksheet = sheet.worksheet("DHT22")
    
    def appendSheet(tempC, humidity):
        dateTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        values =[dateTime, tempC, humidity]
        worksheet.insert_row(values, 2, value_input_option='RAW')
        print("Google Sheet Updated")
    
    def getData():
        try:
            tempC = dhtDevice.temperature
            humidity = dhtDevice.humidity
            print(f"Temp: {tempC} C    Humidity: {humidity}% ")
            appendSheet(tempC, humidity)
        except RuntimeError:
            print ("Runtime Error. Continue...")
            pass
        
    while True:
        getData()
        time.sleep(5.0) 
    

    Notice that in this code, we used the full path to the JSON key file. This is useful if you want to keep your JSON keys separate from the code files or schedule your script in cron. 

    Check your Google Sheet. You should see the DHT22 readings. 

    Google Sheet Dashboard

    It is easy to set up a Dashboard in Google Sheets, which would be the landing page of the sheet (first tab) that has graphs of data that is being streamed to other tabs.

    clipboard_ee200b4120519f59190479c9f7d5579f0.pngFigure \(\PageIndex{1}\): Copy and Paste Caption here. (Copyright; author via source)

    Homework Assignment

    1. Edit the code to stream the temperature in degrees Fahrenheit instead of Celsius. You will need to add a new variable (tempF) and convert from degrees Celsius to degrees Fahrenheit. Make sure that you change the heading in your Google Sheet from "Temperature, C" to "Temperature, F". Run your script and make sure it works and your Google Sheet is updated with the temperature in Fahrenheit. 
    2. Add a red LED to your circuit. You can use the RGB PCB board by connecting it to your breadboard.
    3. Create an IF statement that will turn the LED on when the temperature is below x degrees Fahrenheit and turn it off if the temperature is equal or above x degrees Fahrenheit. Set x to about 1oF above the temperature read from step 1. For example, if in step 1 your temperature was 70.6, make x = 71.6.
    4. Add a new variable "ledStatus" that can be either "ON" or "OFF". Add a new column to your Google Sheet, call it "LED Status". Make your program stream all 4 variables (dateTime, tempF, humidity, ledStatus) to your Google Sheet.
    5. You can wait for the temperature to change naturally, or you can place a hot or a cold object next to the sensor. Use common sense and don't put anything that can damage your board! Your Google Sheet should look something like this (for x=71.6):
    6. Set up a Google Dashboard as the front page of your sheet (see Google Dashboard Tutorial).  You want to stream the data to the sheet called DHT22 and show two graphs on the front page (Dashboard).  The first graph will be Temp as a fct of time and the second humidity as a fct. of time.
    clipboard_e364606d730ef3e48a963c4fb848603f4.png
    Figure \(\PageIndex{4}\): Homework example. (CC0; E. Lisitsyna)

    This page titled 2: DHT 22 - Streaming Temperature and Humidity Data is shared under a not declared license and was authored, remixed, and/or curated by Robert Belford.

    • Was this article helpful?