Skip to content

3. Measuring Temperature & Humidity with the AM2302 (Arduino)

ControlBits edited this page Nov 8, 2020 · 4 revisions

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.

Adafruit has build a unified sensors ecosystem that supports AM2302/DHT22 that makes using the AM2320 easy.

3.1 Libraries Installation

We need to install two Arduino libraries from Adafruit. one is for the DHT22 sensor 'DHT library from Adafruit' and another base library 'Adafruit Unified Sensor library' that's needed for the DHT library to work.

There are several methods to install a library to the Arduino IDE, the easiest is using Arduino library manager. Select 'Sketch' -> 'Include Library' -> 'Manage libraries'

Manage Libraries

On the search bar type 'dht' to filter the available libraries, you should then find the Adafruit library 'DHT sensor by Adafruit'. Select the latest version and click 'install'.

dht library

Then type on the search bar 'Adafruit unified sensor' to filter the libraries to find the matched library and click install.

unified sensor

After installing the needed libraries from the libraries manager we are now ready to write some code reading the humidity and temperature from the sensor.

3.2 AM2302 Setup

The first thing we need to do is include the 'dht' library from Adafruit.

#include "#include "DHT.h"

Then to keep the readability of the code we will define the pin associated with the DHT sensor which in our case its pin 14

#define EMIT_DHT_PIN 14

Another needed macro definition is the sensor type as Adafruit library supports both DHT11 and DHT22 sensors.

#define DHTTYPE DHT22

Now we need to create the DHT sensor object that we would use its API's to interface the sensor. the object constructor takes two parameter. the sensor attached pin and the sensor type.

DHT dht(EMIT_DHT_PIN, DHTTYPE);

And that's the definitions done. The definition section before setup should look like this:

#define EMIT_RED_LED 16

#define EMIT_DHT_PIN 14     // Digital pin connected to the DHT sensor

#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// Initialize DHT sensor.
DHT dht(EMIT_DHT_PIN, DHTTYPE);

Now in setup we need to initialize the DHT22 communication by calling the 'begin()' function of the dht object:

dht.begin();

And that's the setup done, the setup() function would look like this:

void setup() {
  // Enable the serial terminal
  // Useful for debugging messages
  Serial.begin(115200);  
  // configure RED LED GPIO to be OUTPUT
  // so that we would control the LED (ON , OFF)
  pinMode(EMIT_RED_LED , OUTPUT);
  
  // on the beginning we will turn OFF the RED LED 
  digitalWrite(EMIT_RED_LED , LOW);

  // initialize the DHT communication
  dht.begin();
  
}

3.3 Reading the AM2302

Now onto our main application code in loop():

The first thing we need to do is change the timing of our main 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 loop to:

delay(5000);

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 Serial Monitor to "Reading AM2302 ...".

OK, so we're now finally ready to request the AM2302 to start its measurement. 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:

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 
  float humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float tempC = dht.readTemperature();

One 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:

  float tempF = (tempC * 9/5) + 32.0

However passing 'true' to the readTemperature function does the conversion for us which we would use instead:

  // Read temperature as Fahrenheit (isFahrenheit = true)
  float tempF = dht.readTemperature(true);

Finally, all we need to do is to print the results to the Serial Monitor.

  // Print the read values on the Serial Monitor.
  Serial.print("Temperature (C): ");
  Serial.println(tempC);
  Serial.print("Temperature (F): ");
  Serial.println(tempF);  
  Serial.print("Humidity (%RH): ");
  Serial.println(humidity);

One thing to notice is the difference between print() and println() of the Serial object, both are doing the same function while the second one append a new line to the printed string.

Our completed loop() should look something like this:

void loop() {
  //Wait for 5 seconds ( 5000 milliseconds )
  delay(5000);

  // turn the red LED ON
  digitalWrite(EMIT_RED_LED , HIGH);

  // Print a debugging message on the Serial Terminal indicating the start of the read attempt.
  Serial.println("Reading AM2302 ...");
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 
  float humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float tempC = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float tempF = dht.readTemperature(true);
  
  // turn the red LED OFF indicating the end of the read cycle
  digitalWrite(EMIT_RED_LED , LOW);

  // Print the read values on the Serial Monitor.
  Serial.print("Temperature (C): ");
  Serial.println(tempC);
  Serial.print("Temperature (F): ");
  Serial.println(tempF);  
  Serial.print("Humidity (%RH): ");
  Serial.println(humidity);

}

Now all that's left is to compile,upload and test our new Sketch (as detailed in part 2 of this guide: 2. Writing and uploading firmware to EMIT.

Open the serial monitor to see the current readings printed on the screen every 5 seconds.

dht reading

Great, once you're happy with this, it's time to Connect EMIT to the Internet

Clone this wiki locally