概述
在本课中,我们将学习如何驱动DHT11温湿度传感器模块。
所用器件
1 * Raspberry Pi
1 * Breadboard
1 * DHT11
Jumper wires
1 * T-Extension Board
1 * 40-Pin Cable
工作原理
DHT11是一款复合型数字温湿度传感器,包含校准过的温度和湿度输出信号。模块只有三个引脚:VCC、GND和DATA,这个模块采用单总线协议(OneWire protocol)进行通信,通信过程开始于DATA线向DHT11发送开始信号,DHT11接收信号并返回应答信号,然后主机接收应答信号并开始接收40位温湿度数据(8位湿度整数部分+ 8位湿度小数部分+ 8位温度整数部分+ 8位温度小数部分+ 8位校验和)。
模块原理图如下

我们需要将DHT11接到Raspberry Pi的GPIO口上,具体连接如下图所示

实物接线
没画
软件
For C language users ,please take following steps:
1) 在/home/pi下新建一个.c源文件(文件名随意)
cd ~
sudo nano dht11.c
2) 往新建的文件中写入一下代码
#include < wiringPi.h >
#include < stdio.h >
#include < stdlib.h >
#include < stdint.h >
#include < string.h >
#include < errno.h >
#define MAXTIMINGS 85
#define DHTPIN 15 //DHT connect to TxD
int dht11_dat[5] ={0,0,0,0,0};//store DHT11 data
void read_dht11_dat()
{
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0,i;
float f;//fahrenheit
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
//pull pin down to send start signal
pinMode( DHTPIN, OUTPUT );
digitalWrite( DHTPIN, LOW );
delay( 18 );
//pull pin up and wait for sensor response
digitalWrite( DHTPIN, HIGH );
delayMicroseconds( 40 );
//prepare to read the pin
pinMode( DHTPIN, INPUT );
//detect change and read data
for ( i = 0; i < MAXTIMINGS; i++ ) { counter = 0; while ( digitalRead( DHTPIN ) == laststate ) { counter++; delayMicroseconds( 1 ); if ( counter == 255 ) { break; } } laststate = digitalRead( DHTPIN ); if ( counter == 255 ) break; //ignore first 3 transitions if ( (i >= 4) && (i % 2 == 0) )
{
//shove each bit into the storage bytes
dht11_dat[j / 8] <<= 1; if ( counter > 16 )
dht11_dat[j / 8] |= 1;
j++;
}
}
//check we read 40 bits(8bit x 5) +verify checksum in the last byte
//print it out if data is good
if ( (j >= 40) &&
(dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
{
f = dht11_dat[2] * 9. / 5. + 32;
printf( "Humidity = %d.%d %% Temperature = %d.%d C (%.1f F)\n",
dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
}
else
{
printf( "Data not good, skip\n" );
}
}
void print_info()
{
printf("\n");
printf("|***************************|\n");
printf("| DHT11 test |\n");
printf("| --------------------------|\n");
printf("| DHT11 connect to GPIO14 |\n");
printf("| --------------------------|\n");
printf("| OSOYOO|\n");
printf("|***************************|\n");
printf("Program is running...\n");
printf("Press Ctrl+C to end the program\n");
}
int main( void )
{
if ( wiringPiSetup() == -1 )
{
fprintf(stderr,"Can't init wiringPi: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
print_info();
while ( 1 )
{
read_dht11_dat();
delay(1000);//wait ls to refresh
}
return(0);
}
键盘输入Ctrl+X再按Y保存退出,完整的代码可以通过下面的命令获取
wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_17/dht11.c
3) 编译
gcc -Wall -o dht11 dht11.c -lwiringPi
4) 运行程序
sudo ./dht11
5) 最终结果
运行上面的程序,屏幕上首先会输出DHT11如何与Pi连接等信息,然后不停打印温湿度值。
For Python Language users
1) 在/home/pi下新建一个.py脚本文件(文件名随意)
cd ~
sudo nano dht11.py
2) 往新建的文件中写入一下代码
import RPi.GPIO as GPIO
import time
#DHT11 connect to BCM_GPIO14
DHTPIN = 14
GPIO.setmode(GPIO.BCM)
MAX_UNCHANGE_COUNT = 100
STATE_INIT_PULL_DOWN = 1
STATE_INIT_PULL_UP = 2
STATE_DATA_FIRST_PULL_DOWN = 3
STATE_DATA_PULL_UP = 4
STATE_DATA_PULL_DOWN = 5
def read_dht11_dat():
GPIO.setup(DHTPIN, GPIO.OUT)
GPIO.output(DHTPIN, GPIO.HIGH)
time.sleep(0.05)
GPIO.output(DHTPIN, GPIO.LOW)
time.sleep(0.02)
GPIO.setup(DHTPIN, GPIO.IN, GPIO.PUD_UP)
unchanged_count = 0
last = -1
data = []
while True:
current = GPIO.input(DHTPIN)
data.append(current)
if last != current:
unchanged_count = 0
last = current
else:
unchanged_count += 1
if unchanged_count > MAX_UNCHANGE_COUNT:
break
state = STATE_INIT_PULL_DOWN
lengths = []
current_length = 0
for current in data:
current_length += 1
if state == STATE_INIT_PULL_DOWN:
if current == GPIO.LOW:
state = STATE_INIT_PULL_UP
else:
continue
if state == STATE_INIT_PULL_UP:
if current == GPIO.HIGH:
state = STATE_DATA_FIRST_PULL_DOWN
else:
continue
if state == STATE_DATA_FIRST_PULL_DOWN:
if current == GPIO.LOW:
state = STATE_DATA_PULL_UP
else:
continue
if state == STATE_DATA_PULL_UP:
if current == GPIO.HIGH:
current_length = 0
state = STATE_DATA_PULL_DOWN
else:
continue
if state == STATE_DATA_PULL_DOWN:
if current == GPIO.LOW:
lengths.append(current_length)
state = STATE_DATA_PULL_UP
else:
continue
if len(lengths) != 40:
print "Data not good, skip"
return False
shortest_pull_up = min(lengths)
longest_pull_up = max(lengths)
halfway = (longest_pull_up + shortest_pull_up) / 2
bits = []
the_bytes = []
byte = 0
for length in lengths:
bit = 0
if length > halfway:
bit = 1
bits.append(bit)
print "bits: %s, length: %d" % (bits, len(bits))
for i in range(0, len(bits)):
byte = byte << 1
if (bits[i]):
byte = byte | 1
else:
byte = byte | 0
if ((i + 1) % 8 == 0):
the_bytes.append(byte)
byte = 0
print the_bytes
checksum = (the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3]) & 0xFF
if the_bytes[4] != checksum:
print "Data not good, skip"
return False
return the_bytes[0], the_bytes[2]
def main():
print "Raspberry Pi wiringPi DHT11 Temperature test program\n"
while True:
result = read_dht11_dat()
if result:
humidity, temperature = result
print "humidity: %s %%, Temperature: %s C" % (humidity, temperature)
time.sleep(1)
def destroy():
GPIO.cleanup()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
destroy()
键盘输入Ctrl+X再按Y保存退出,完整的代码可以通过下面的命令获取
wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_17/dht11.py
3) 运行程序
sudo python ./dht11.py
4) 最终结果
运行上面的脚本程序,屏幕会不停打印温湿度值。
DownLoad Url osoyoo.com
You must be logged in to post a comment.
Any suggestions on how to make this sensor on Scratch on Raspberry Pi? Scratch documentation only covers the DS18B20 sensor.
https://www.raspberrypi.org/documentation/usage/scratch/gpio/
Do you mean you want know how to connect the DHT11 sensor to Raspberry pi? or how to connect DS18B20 sensor to raspberry Pi?
Do you use raspberry Pi 2 or Pi 3?
If you want to learn more about GPIO port with raspberry Pi 3 and T type adapter, Please review our lessone 2: https://osoyoo.com/2017/06/26/introduction-of-raspberry-pi-gpio/.
Use DHT11 sensor with Raspberry pi.
I would like to code in Scratch, not Python or C, since I am using it to teach kids coding. The link I sent before https://www.raspberrypi.org/documentation/usage/scratch/gpio/ is general documentation for using Scratch to code on Pi, but it doesn’t cover your sensor DHT11. I am wondering if you have/could create some sample codes for Scratch.
It is Pi 3.
Thanks.