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
DHT22sensor 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
DHT22by pulling signal bus toLOW, at least800μs, typically1000μs, then release the bus toHIGHto wake up the sensor. DHT22responds to the host by pulling signal bus toLOW for about 80μs, then release the signal bus toHIGH to echo the host.DHT22sends out40-bitdata (2-bytehumidity, 2-bytetemperaturefollowed by 1-byteparity check).MSB first; LOW signal followed by HIGH signal; HIGH signal lasts26-28μsto representbit value 0, HIGH signal lasts68-75μsto representbit value 1.DHT22finally to pull signal busLOWagain (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-endianformat and10 timesof real humidity and temperature. - For example, raw data
0x03 0x2F 0x01 0x09means raw humidity is0x032Fand raw temperature is0x0109. HEX0x032Fis815(DEC),0x0109is265(DEC). Since raw data is10 timesof 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 0x00FFto 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 bitto represent positive temperature or temperature below 0°C;bit value 1 is negative. Please note this isnot the two's complementsystem. - When calculating real temperature, we must mask MSB of high-byte temperature to get real temperature. So
0x0109means26.5°Cand0x8109meansnegative 0x0109, that is-26.5°C.
-
After a success build, you'll get
dht22.kofile; 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 ofDHT22data pin,default is 4.autoupdate: Automatically triggerDHT22or 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 directorydht22under /sys/kernel. Read or write these sysfs attributes bycd /sys/kernel/dht22
ls -lsayou'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 > autoupdateto enable 'autoupdate'
echo 1 > autoupdateor 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_secto modify time interval:
echo 60 > autoupdate_secDHT22 can be automatically triggered only when 'autoupdate' flag is ON.
-
Trigger DHT22 manually:
echo 1 > triggerthis command will trigger sensor to fetch humidity/temperature, no matter
autoupdateflag is ON or OFF.