Skip to main content

DHT11

This article aims to provide a detailed guide on how to use Luckfox Pico Plus to drive the DHT11 temperature and humidity sensor module. We are using Waveshare's DHT11 Temperature and Humidity Sensor module, and you can find the specific parameters for the screen on the DHT11 Product Wiki. You can download the image file and sample program for direct use or configure it yourself following the steps.

1. Quick Start

1.1 Burn Image

Burn the image provided at the beginning of the article.

1.2 Hardware Connection

Luckfox Pico

Luckfox Pico Plus

Luckfox Pico Pro/Max

Pin Connection

DHT11Luckfox Pico / Luckfox Pico PlusFunction
VCC3V3Power Input
GNDGDNPower Ground
DOUTGPIO1_C7_d(55)Communication Port

1.3 Import Module

After connecting the module and powering on, copy the dht11_drv.ko and dht11 files from the sample program to the development board and import the module:

insmod dht11_drv.ko

1.4 Run the Program

chmod +x dht11
./dht11

2. Compatible Device Configuration

  • The Luckfox Pico / Plus / Pro / Max series mainly refers to the pin layout of the Raspberry Pi Pico, and through pin configuration, it can be compatible with some Raspberry Pi Pico peripherals.

  • For the list of compatible devices supported by different models of Luckfox Pico, refer to Luckfox-Pico_support-List.

  • The compatible device option is essentially a combination of multiple pin configurations, which can simplify the configuration process.

  • Due to the lack of io commands to directly configure registers under Ubuntu, the Luckfox Pico cannot configure the pins as default pull-up when configuring the compatible device Pico-LCD, so it cannot properly control the buttons.

  • When starting the compatible device configuration, it will overwrite the original configuration. To cancel the compatible device, go to the Advanced Options screen to disable the started device function.

3. Sample Program

3.1 dht11_drv.c

The code is a Linux kernel module for interacting with the DHT11 sensor. It provides an interface for reading temperature and humidity through a character device file.Here is the code breakdown:

Data Structure Definition

typedef struct DHT11_SENSOR_DATA
{
u16 temp; // Temperature
u16 hum; // Humidity
} dht11_data;
  • Purpose: Defines a structure DHT11_SENSOR_DATA to store temperature and humidity data read from the DHT11 sensor.

DHT11_Read_DQ

static u8 DHT11_Read_DQ(void)
{
DHT11_IO_IN;
return gpio_get_value(dht11_gpio);
}
  • Purpose: Reads the state of the data line of the DHT11 sensor.
  • Steps: Sets the data line to input mode (DHT11_IO_IN) and uses gpio_get_value to get the value of the data line.

DHT11_Rst

static void DHT11_Rst(void)
{
DHT11_DQ_Low;
delay_ms(20);
DHT11_DQ_High;
delay_us(30);
}
  • Purpose: Resets the DHT11 sensor by pulling down the data line, waiting for a period, and then pulling it high.
  • Steps: Pulls the data line low (DHT11_DQ_Low), delays for 20 milliseconds, pulls the data line high (DHT11_DQ_High), and delays for 30 microseconds.

DHT11_Check

static u8 DHT11_Check(void)
{
u8 retry = 0;
DHT11_IO_IN;
while ((DHT11_Read_DQ() == 1) && retry < 100)
{
retry++;
delay_us(1);
}
if (retry >= 100)
return 1;
else
retry = 0;
while ((DHT11_Read_DQ() == 0) && retry < 100)
{
retry++;
delay_us(1);
}
if (retry >= 100)
return 1;
return 0;
}
  • Purpose: Checks if the DHT11 sensor is present by monitoring the state of the data line.
  • Steps: Waits for the data line to transition from high to low and then from low to high.

DHT11_Read_Bit

static u8 DHT11_Read_Bit(void)
{
u8 retry = 0;
while ((DHT11_Read_DQ() == 1) && retry < 100)
{
retry++;
delay_us(1);
}
retry = 0;
while ((DHT11_Read_DQ() == 0) && retry < 100)
{
retry++;
delay_us(1);
}
delay_us(40);
if (DHT11_Read_DQ() == 1)
return 1;
else
return 0;
}
  • Purpose: Reads one bit from the DHT11 sensor.
  • Steps: Waits for the data line to transition from high to low and then from low to high, delays for 40 microseconds, and finally reads the state of the data line.

DHT11_Read_Byte

static u8 DHT11_Read_Byte(void)
{
u8 i, dat;
dat = 0;
for (i = 0; i < 8; i++)
{
dat <<= 1;
dat |= DHT11_Read_Bit();
}
return dat;
}
  • Purpose: Reads one byte (8 bits) from the DHT11 sensor.
  • Steps: Calls the DHT11_Read_Bit function 8 times, left-shifts each bit, and performs bitwise OR operation with the read bit.

DHT11_Read_Data

static u8 DHT11_Read_Data(u16 *temp, u16 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if (DHT11_Check() == 0)
{
for (i = 0; i < 5; i++)
{
buf[i] = DHT11_Read_Byte();
}
if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
{
*humi = buf[0] << 8 | buf[1];
*temp = buf[2] << 8 | buf[3];
printk("buf=%d,%d,%d,%d,%d\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
return 0;
}
else
return 1;
}
else
return 1;
}
  • Purpose: Reads temperature and humidity data from the DHT11 sensor.
  • Steps: Calls DHT11_Rst for reset and initialization, then uses DHT11_Check to check if the sensor is present. If present, continues by calling DHT11_Read_Byte to read 40 bits of data and verifies the checksum.

DHT11_Init

static void DHT11_Init(void)
{
DHT11_DQ_High;
DHT11_Rst();
DHT11_Check();
}
  • Purpose: Initializes the GPIO of the DHT11 sensor and checks for sensor presence.
  • Steps: Pulls the data line high, then calls DHT11_Rst for reset, and finally calls DHT11_Check to wait for the sensor's response.

DHT11_open

int DHT11_open(struct inode *inode, struct file *flips)
{
printk("--------------%s--------------\n", __FUNCTION__);
return 0;
}
  • Purpose: Open operation of the character device file.

DHT11_read

static ssize_t DHT11_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
dht11_data Last_dht11_data;
printk("--------------%s--------------\n", __FUNCTION__);

if (DHT11_Read_Data(&Last_dht11_data.temp, &Last_dht11_data.hum) == 0)
{
if (copy_to_user(buf, &Last_dht11_data, sizeof(Last_dht11_data)))
{
return -EFAULT;
}
}
return 0;
}
  • Purpose: Read operation of the character device file, reads temperature and humidity data from the DHT11 sensor.
  • Steps: Calls the DHT11_Read_Data function to read data and then copies the data to the user space.

DHT11_close

static int DHT11_close(struct inode *inode, struct file *flip)
{
printk("--------------%s--------------\n", __FUNCTION__);
return 0;
}
  • Purpose: Close operation of the character device file.

dht11_probe

static int dht11_probe(struct platform_device *pdev)
{
...
}
  • Purpose: Handles detection and initialization of the platform device.
  • Steps: Includes getting GPIO information, registering a character device, creating a device class and device node, and initializing the DHT11 sensor.

dht11_remove

static int dht11_remove(struct platform_device *pdev)
{
...
}
  • Purpose: Handles the uninstallation of the platform device.
  • Steps: Includes destroying the device node and device class, and unregistering the character device.

dht11_shutdown

static void dht11_shutdown(struct platform_device *pdev)
{
printk("-------%s-------------\n", __FUNCTION__);
}
  • Purpose: Handles the device shutdown operation.
  • Steps: Prints a debug message.

3.2 dht11_test.c

This is an example code that calls the device file to read temperature and humidity.Here is the breakdown of the code:

Open Device File

fd = open("/dev/dht11", O_RDONLY);
if (fd == -1)
{
perror("open dht11 error\n");
exit(-1);
}

Uses the open function to open the character device file "/dev/dht11" in read-only mode. If the open fails, it outputs an error message and exits the program.

Loop to Read Sensor Data

while (1)
{
sleep(1);
retval = read(fd, &Curdht11_data, sizeof(Curdht11_data));
if (retval == -1)
{
perror("read dht11 error");
printf("read dht11 error");
exit(-1);
}
if (Curdht11_data.temp != 0xffff)
printf("Temperature:%d.%d C,Humidity:%d.%d %%RH\n", Curdht11_data.temp >> 8, Curdht11_data.temp & 0xff, \
Curdht11_data.hum >> 8, Curdht11_data.hum & 0xff);
}

Reads sensor data every 1 second. If the reading fails, it outputs an error message and exits the program. If the temperature value is not 0xffff, it prints the temperature and humidity information.

Close Device File

close(fd);

Uses the close function to close the character device file.

3.3 Compile the Program

  1. Modify the Makefile

    Replace <SDK Directory> with your own SDK path in the Makefile, for example, /home/luckfox/luckfox-pico/.

    ARCH=arm
    CROSS_COMPILE=<SDK Directory>/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-
    export ARCH CROSS_COMPILE

    KERN_DIR = <SDK Directory>/sysdrv/source/kernel
    OBJS_KERN_DIR = <SDK Directory>/sysdrv/source/objs_kernel

    name = dht11
    PWD ?= $(shell pwd)
    BUILD_DIR = $(PWD)/build

    all:
    make -C $(KERN_DIR) M=$(PWD) O=$(OBJS_KERN_DIR) modules
    $(CROSS_COMPILE)gcc $(name)_test.c -o $(name)
    echo $(PWD)

    clean:
    rm -f *.ko *.o *.mod *.mod.o *.mod.c *.symvers *.order *.cmd
    # make -C $(KERN_DIR) M=$(PWD) modules clean
    # rm -rf modules.order
    # rm -f $(name)_test
    obj-m += $(name)_drv.o
  2. Compile

    Execute make to compile the two files, and copy the resulting dht11_drv.ko and dht11 to the development board.

4. Implementation Results

4.1 Import Module

insmod dht11_drv.ko

The effect is as follows:

# insmod dht11_drv.ko
[ 57.655150] -------dht11_probe-------------
[ 57.655337] dht11-gpio: 55 is valid!
[ 57.655365] gpio 55 request success!
[ 57.655381] dht11_major =239
[ 57.681960] dht11 Initing...

4.2 Read Temperature and Humidity

chmod +x dht11
./dht11

The effect is as follows:

# chmod +x dht11
# ./dht11
Press CTRL+C to exit.
[ 91.447436] --------------DHT11_open--------------
open /dev/dht11 successfully
[ 93.447934] --------------DHT11_read--------------
[ 93.475741] buf=37,0,25,7,69
Temperature:25.7 C, Humidity:37.0 %RH
[ 94.476565] --------------DHT11_read--------------
Temperature:25.7 C, Humidity:37.0 %RH
[ 95.502423] --------------DHT11_read--------------
[ 95.532409] buf=37,0,25,7,69
Temperature:25.7 C, Humidity:37.0 %RH
[ 96.533221] --------------DHT11_read--------------
Temperature:25.7 C, Humidity:37.0 %RH
[ 97.559087] --------------DHT11_read--------------
[ 97.589061] buf=37,0,25,9,71
Temperature:25.9 C, Humidity:37.0 %RH
[ 98.589883] --------------DHT11_read--------------
Temperature:25.9 C, Humidity:37.0 %RH