DHT-22 sensor on Banana Pi BPI-M2U

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.

I’ve found and tried this user-mode C code (dht22). It uses the WiringPi library and can be compiled on Banana Pi BPI-M2U.

$ c -Wall dht22.c -o dht22 -lwiringPi

The main disadvantage of this implementation is:

  1. You need to modify this code for your task.
  2. 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.

Source code

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.

There are no comments.

Leave a Reply