Arduino library for the AM2302 humidity and temperature sensor

The AM2303 sensor  from Aosong integrates a humidity and temperature sensor. A micro controller can fetch the sample values from the device via a single serial signal line. The measurement resolutions (not accuracy) are 0.1% RH and 0.1 °C.  AM2301, DHT21, DHT22,  SHT15, SHT11 and SHT10 are probably equivalent products. I have tested the library using an Arduino Pro Micro module. You can download the library here .

Data collection

Data transfers are initiated by pulling down the open collector data line. After this start pulse the sensor acknowledges the start puls and the outputs the data: Five bytes which represent the 16 bits humidity, 16 bits temperature  and 8 bits check sum values. These 40 bits are shifted out as pulses, the width of the pulses indicates if they represent 0 (22-30 µs) or 1 ((66-75 µs). To decode this signal we must therefore measure the time taken from each pulse rising edge till its falling edge with a few micro seconds precision.

The pulse widths can be measured by observing the signal level and store the Counter0 values at the edges.However, during the signal reception (a few milliseconds) the program is mostly idling. Therefore, this library takes an interrupt driven approach. You start the  collection of the measured values, do any other tasks and then after some time may collect the measured values.

The interrupt service routine is triggered by every edge of the signal. The value of Counter0 is stored at rising edges and subtracted from the counter value read at the falling edge. This yields the pulse width with a resolution of 4 µs.

The priorities of the pin change interrupts are fairly high, but the sensor reading may become unreliable if you have other interrupt handlers which disable interrupt for, say ten µs or more. So enable interrupts as early as possible in interrupt service routines to allow higher priority interrupts to be served without much delay (nested interrupts).

An even better approach would be to allocate one of the 16 bit counters for this purpose and feed the signal to its capture input. The ISR would then be triggered on every signal edges of the capture pin signal. At the signal edges the present counter value is stored in the capture register. You must fetch the captured value before the next edge, but the precision of the capture is not deteriorated if interrupts are disabled. But still, the ISR must read the capture register before the following edge.

Library functions

My library has two functions related to the data capture, one to start the reading of the sensor (startMeasurement) and one to read the results (getResult). Everything between the call to these functions are taken care of by the interrupt handler. There are two versions of getResult, one which returns integers and one that returns formatted strings. The integers represent 10*humidity and 10*temperature, the strings are formatted with a one digit fraction.  The library also have one public function to format an integer.

If your input pin differs from the one I used you must rewrite the library to some extent. I think I would inherit the Am2302Sensor class and include rewritten startReadBitstring and irqHandler methods, and of course add an ISR interrupt handler for the actual pin.

The sensor

When using the Am2302 sensor, one must be aware of the fact that the sensor samples the present humidity and temperature states while the previous result is shifted out. What you read is therefore the previous values. So if you read the sensor once an hour you will read one hour old values. The solution to this is to read twice and disregard the first value.


The Arduino IDE compiles the application when you click the verify or upload button. However I’m not sure if the IDE always also will compile the libraries in use. If unsure, you can delete the library object to force recompilation. In Linux, use this command:

rm -rf /tmp/build*/Am2302sensor/*.o


0 Responses to “Arduino library for the AM2302 humidity and temperature sensor”

Comments are currently closed.