I need to connect the DHT22 temperature and humidity sensor to BPi. Obviously, the kernel does not include the corresponding kernel module, but this module exists in sequent releases.
$ c -Wall dht22.c -o dht22 -lwiringPi
The main disadvantage of this implementation is:
- You need to modify this code for your task.
- It works unstable because uses inaccurate user mode timers and this code may miss some bits.
Here I’ve plunged into the Linux kernel :). I’ve found a source code for the DHT11 module for the kernel v3.14 and ported it to v3.10. A bit later I’ve added some important changes from the 4.x branch.
This is my first practice of programming for a Linux kernel. I can say now this is rather easy than programming for a Windows kernel. All my experiments didn’t crash Linux!
The main problem was related with interrupts. The kernel module uses theirs for precise detection of signal edges.
This is not obvious, but the Allwinner R40 chip allows to use interrupts for selected pins only (Logical numbers: PH0-PH21, PI10-PI15, CPU pin numbers: 224-245, 266-271). Only some of these pins present on the GPIO header.
Therefore I’ve selected and used PH3 (227) in my tests.
How to install compiled kernel modules
The customized kernel module allows to define the pin number in command line. Copy compiled *.ko files to the /home/pi directory and execute the following commands:
$ sudo cp industrialio.ko /lib/modules/3.10.107-BPI-M2U-Kernel/kernel/drivers/iio/
$ sudo cp dht11.ko /lib/modules/3.10.107-BPI-M2U-Kernel/kernel/drivers/iio/humidity/
$ sudo modprobe industrialio
$ sudo modprobe dht11 gpio=227
$ cat /sys/bus/iio/devices/iio:device0/in_humidity_input
dht11_3_10_107 compiled for kernel 3.10.107.
In my modified source code (dht11_internal.h) you may find useful functions:
gpio_set_isr – disable/enable interrupts for a pin.
gpio_set_pin_mode – set a pin mode (look at Allwinner R40 User Manual for possible modes for each pin).
gpio_set_pull – set the pull up resistor mode for a pin.