Вы находитесь на странице: 1из 2

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.
Compilation

The Arduino IDE compiles the application when you click the verify or upload button. However
Im 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

Вам также может понравиться