The purpose of this project is to develop a Linux Kernel Driver for DHT22
humidity and temperature sensor. For more information of DHT22
, read the followings link:
- Datasheet for DHT22
I cross compiled to RPi3 Model B
running Linux Kernel 4.8.16-v7+
. The host environment is Ubuntu 16.04 LTS
(running Linux Kernel 4.4.0-98-generic). I've tested and run the driver on RPi3/B only and never tested compability issues between DHT22
and DHT11
(the other cheaper one), other Pi models or other Kernel versions.
Modify Makefile
first to fit in your development environment before you can build this driver; for either native(on RPi) or cross compilation.
If you prefer cross compilation, the first step is to build your own RPi Linux Kernel (whatever versions) on host environment.
I'm new to Linux Kernel/Driver programming; whatever wrong you find, please don't hesitate to contact me.
p.s. This is my first Linux Kernel Driver, I've learned and studied this, then developed this simplified one (with simple algorithm, more comments and without compicated mechanism, like FSM).
- About DHT22 Seosor
1.1. DHT22 Spec And Communication
1.2. Triggering DHT22
1.3. Reading And Interpreting Humidity/Temperature/Parity Raw Data
1.4. Temperature Below 0°C - Using This Driver
2.1. Loading/Unloading The Driver
2.2. sysfs Attributes
2.3. Some Useful Examples
The DHT22
must be manually triggered with a specific signal as the followings:
- After power on, the
DHT22
sensor must warm up first; in general, it takes about2 seconds
. During first 2 seconds, the sensor can't respond to host's request. - The host triggers request to
DHT22
by pulling signal bus toLOW
, at least800μs
, typically1000μs
, then release the bus toHIGH
to wake up the sensor. DHT22
responds to the host by pulling signal bus toLOW for about 80μs
, then release the signal bus toHIGH to echo the host
.DHT22
sends out40-bit
data (2-bytehumidity
, 2-bytetemperature
followed by 1-byteparity check
).MSB first
; LOW signal followed by HIGH signal; HIGH signal lasts26-28μs
to representbit value 0
, HIGH signal lasts68-75μs
to representbit value 1
.DHT22
finally to pull signal busLOW
again (50μs, following 40-bit data) to notify the host about end of communication, then release the signal bus toHIGH
.
- 40-bit raw data is composed of 2-byte humidity, 2-byte temperature and 1-byte parity check. Raw humidity and temperature are both
big-endian
format and10 times
of real humidity and temperature. - For example, raw data
0x03 0x2F 0x01 0x09
means raw humidity is0x032F
and raw temperature is0x0109
. HEX0x032F
is815(DEC)
,0x0109
is265(DEC)
. Since raw data is10 times
of real data, so the humidity is81.5%
and temperature is26.5°C
. - Parity check: The parity check is 1-byte and summation of byte 0 to 3 may overflow, we must
bitwise AND 0x00FF
to mask high byte before checking against to parity byte. Take the above as an example:(0x003F + 0x002F + 0x001C + 0x0009) & 0x00FF == 0x003C
, the parity check byte must be 0x3C, or the host must ignore this error and re-trigger later.
- Bit 0 (MSB) of raw data byte 2 (3rd byte) is a
sign bit
to represent positive temperature or temperature below 0°C;bit value 1 is negative
. Please note this isnot the two's complement
system. - When calculating real temperature, we must mask MSB of high-byte temperature to get real temperature. So
0x0109
means26.5°C
and0x8109
meansnegative 0x0109
, that is-26.5°C
.
-
After a success build, you'll get
dht22.ko
file; copy this to wherever that your RPi can read. Load the module by the command (with root permission)insmod dht22.ko
-
dht22.ko default parameters:
gpio
: Assigned GPIO number ofDHT22
data pin,default is 4
.autoupdate
: Automatically triggerDHT22
or not,default is 1
(turn ON autoupdate); 0 to to turn it OFF. Others are interpreted as ON.autoupdate_sec
: Seconds between two trigger events, default is 10 seconds (int)
The DHT22
driver will be loaded by default parameters; if you want to assign other values, try this form:
> insmod dht22.ko [gpio=<gpio_number>] [autoupdate=<flag>] [autoupdate_sec=<second>]
`autoupdate=0` to turn OFF the flag; others rather than 0 turns it ON.
`autoupdate_sec` must be any positive number between 3 (sec) and 60000 (10 min). The driver ignores any number out of this range.
-
To unload the driver, simply do this (with root permission).
rmmod dht22
-
To check whether the driver was loaded or not by kernel:
lsmod | grep dht22
-
After you
insmod dht22.ko
, the driver will create a directorydht22
under /sys/kernel. Read or write these sysfs attributes bycd /sys/kernel/dht22
ls -lsa
you'll see the followings:
0 -rw-r--r-- 1 root root 4096 Nov 14 12:05 autoupdate
0 -rw-r--r-- 1 root root 4096 Nov 14 12:05 autoupdate_sec
0 --w------- 1 root root 4096 Nov 14 12:05 debug
0 -r--r--r-- 1 root root 4096 Nov 14 12:05 gpio
0 -r--r--r-- 1 root root 4096 Nov 14 12:05 humidity
0 -r--r--r-- 1 root root 4096 Nov 14 12:05 temperature
0 --w------- 1 root root 4096 Nov 14 12:05 trigger -
The attributes 'debug' and 'trigger' is write only; 'humidity' and 'temperature' are read only; others are both read and write.
-
Only users with root permission can write value to attributes. This is forbidden by Linux Operating System, not by the driver. To change permission of individual attribute, do chmod with root permission; for example:
chmod 222 trigger
Thus, any user can 'trigger' DHT22 with permission 222
.
-
Some useful tips are helpful, especially you are new to Linux Kernel Driver.
-
To read temperature and humidity (both are read only):
cd /sys/kernel/dht22
cat humidity
cat temperature
-
To get GPIO number used by DHT22; it's also read only, no one can change GPIO number after the driver is loaded. To change GPIO number, please read Loading/Unloading The Driver. .
cat gpio
-
To get 'autoupdate' flag and update the flag (with root permission) to dispable 'autoupdate':
echo 0 > autoupdate
to enable 'autoupdate'
echo 1 > autoupdate
or you can read Loading/Unloading The Driver to load driver with 'autoupdate' OFF.
-
To get 'autoupdate_sec' value and modify time interval between two trigger events; time unit is second, the range must be any positive number between 3 (sec) and 60000 (10 minutes). Any unrecognized input will be ignored by the driver and takes no effect. To read time interval:
cat autoupdate_sec
to modify time interval:
echo 60 > autoupdate_sec
DHT22 can be automatically triggered only when 'autoupdate' flag is ON.
-
Trigger DHT22 manually:
echo 1 > trigger
this command will trigger sensor to fetch humidity/temperature, no matter
autoupdate
flag is ON or OFF.