3. Measuring temperature & humidity with the AM2302 - ControlBits/EMIT GitHub Wiki
To measure the temperature and humidity of the surrounding environment, EMIT includes an AM2302 temperature & humidity sensor. The sensor can measure temperatures from -40 to +80 degrees Celcius and humidity from 0 to 99.9 %RH (Relative Humidity).
The AM2302 (also know as DHT22) uses a single-pin, serial protocol and is connected to the ESP32s GPIO14 pin. The sensor can be read by the ESP32 at a maximum frequency of once every 2 seconds.
The AM2302/DHT22 is so widely used that the standard MicroPython distribution for the ESP32 includes a dedicated ‘dht’ module that makes using the AM2302 easy.
3.1 AM2302 Setup
The first thing we need to do is import the dedicated 'dht' module. To do this, we simply add 'dht' to our list of imported modules in boot.py:
import machine, time, dht
Then we can configure GPIO Pin 14 in a similar way to the Red LED pin; we use the dht.DHT22() function to configure the pin as a single-wire serial DH22(AM2302) device. To make our code easier to read, we'll assign the variable name 'AM2302' to the pin as follows:
AM2302 = dht.DHT22(machine.Pin(14))
And that's the setup done. Our complete boot.py should now look something like this:
# general board setup
import machine, time, dht
# configure GPIO pins
RedLED = machine.Pin(16, machine.Pin.OUT)
RedLED.value(0)
AM2302 = dht.DHT22(machine.Pin(14))
3.2 Reading the AM2302
Now onto our main application code in main.py:
The first thing we need to do is change the timing of our main 'while' loop. The maximum frequency that we can ready the AM2302 is once every 2 seconds. For our application however, we're only going to read the AM2302 every 5 seconds. To do this, change the first timer event in the main.py to:
time.sleep(5) # wait 5 seconds
The AM2302 will automatically return its result once it has completed its measurement cycle, so we don't require the second timer event - this can be deleted.
We're still going to use the Red LED, this time as a 'read status' LED. We'll turn it ON immediately before we read the AM2302 and OFF again immediately it has finished its measurement. This will result in a brief flash that indicates the duration of the read event.
To help with debugging, we'll also change the "LED ON" message that gets printed to the shell window to "Reading AM2302 ...".
OK, so we're now finally ready to request the AM2302 to start its measurement. This is very simple, just a single command:
AM2302.measure()
Once the measurement cycle has been completed, we'll turn the Red LED off (already in our code) and print the results to the Shell window.
We get the measurements from the AM2302 using the temperature() and humidity() functions. So in our code, we'll get the results and assign them to new local variables as follows:
tempC = AM2302.temperature() # get temperature (Celsius) from AM2302
humidity = AM2302.humidity() # get humidity from AM2302
Finally, all we need to do is print the results to the Shell window, BUT there is one important thing to point out ... the AM2302 returns it's result as floating point number, we can not directly print a floating point number so we must convert the number to a string first using the str() function.
To help keep our code compact, MicroPython let's us do the string conversion within the print statement itself as follows:
print("Temperature (C): " + str(tempC))
print("Humidity (%RH): " + str(humidity))
Our completed main.py should look something like this:
# this is the main program loop
while True:
time.sleep(5) # wait 5 seconds
RedLED.value(1) # turn RedLED ON
print("Reading AM2302 ...")
AM2302.measure() # start AM2302 measurement
RedLED.value(0) # turn RedLED OFF
tempC = AM2302.temperature() # get temperature (Celsius) from AM2302
humidity = AM2302.humidity() # get humidity from AM2302
print("Temperature (C): " + str(tempC))
print("Humidity (%RH): " + str(humidity))
Now all that's left is to upload and test our new boot.py and main.py (as detailed in part 2 of this guide: 2. Writing and uploading firmware to EMIT. Remembering to reboot the ESP32 after upload so that it reads our new files in the right order.
3.3 Converting temperature to Fahrenheit
One final point to discuss, the AM2302 always produces its temperature results in degrees Celsius. If you would prefer to display your results in Fahrenheit, you can do a simple conversion from Celsius to Fahrenheit as follows:
tempF = (tempC * 9/5) + 32.0
Our final main.py, that now includes temperature in Celsius & Fahrenheit, should look something like this:
# this is the main program loop
while True:
time.sleep(5) # wait 5 seconds
RedLED.value(1) # turn RedLED ON
print("Reading AM2302 ...")
AM2302.measure() # start AM2302 measurement
RedLED.value(0) # turn RedLED OFF
tempC = AM2302.temperature() # get temperature (Celsius) from AM2302
humidity = AM2302.humidity() # get humidity from AM2302
tempF = (tempC * 9/5) + 32.0 # convert Celcius result into Fahrenheit
print("Temperature (C): " + str(tempC))
print("Temperature (F): " + str(tempF))
print("Humidity (%RH): " + str(humidity))
Great, once you're happy with this, it's time to Connect EMIT to the Internet