首页 > 代码库 > 树莓派使用DHT11温湿度传感器(C语言程序)
树莓派使用DHT11温湿度传感器(C语言程序)
pi4j是基于wiringpi开发的通过java来控制树莓派GPIO口的库文件。在java程序中引入相关类就可以使用已经封装好的方法控制树莓派GPIO口。
pi4j官网:http://pi4j.com/
pi4j下载:http://pi4j.com/download.html
pi4j安装:http://pi4j.com/install.html
pi4j文档:http://pi4j.com/apidocs/index.html
编译和运行:
使用了pi4j后,编译.java文件和运行.class文件时,需要使用root权限。例如:
编译:
1
sudo
javac -classpath .:classes:/opt/pi4j/lib/
‘*‘
YourJavaFile.java
运行:
1
sudo
java -classpath .:classes:/opt/pi4j/lib/
‘*‘
YourClassFile.class
如果使用sudo编译和运行时提示找不到javac和java,这是由于root用户没有加载环境变量,所以找不到java的执行命令。可以使用如下命令切换到带有环境变量的root用户后,再执行编译和运行:
1
sudo
su
- root
二、硬件连接
由于本人较懒,而且目前是新手状态使用ubuntu,不知道用什么软件来做图,所以用文字简单描述一下硬件的连接。
DHT11引脚有格子空的为正面,引脚朝下,从左数4个引脚分别为
DHT11引脚名称 DHT11引脚功能 连接到树莓派的GPIO 1.VCC 正极,连接3.3V或5V 物理接口1,即3.3V 2.DATA 数据输入输出 物理接口7,即GPIO 7 3.NC 悬空(就是不连任何地方) 不连 4.GND 负极 物理接口 6,即GND 此外按照DHT11数据手册要求,我在DATA和VCC之间连接了一个4.7K欧姆的电阻,起到上拉作用。
三、软件编写
使用wiringpi编写C程序:
如下程序借鉴了网上一老外的程序,忘了原帖地址在哪。
上述程序保存为.c文件后编译成可执行文件,运行后会在屏幕打印温度和湿度。
01
#include <wiringPi.h>
02
#include <stdio.h>
03
#include <stdlib.h>
04
#include <stdint.h>
05
#define MAX_TIME 85
06
#define DHT11PIN 7
07
#define ATTEMPTS 5 //retry 5 times when no response
08
int
dht11_val[5]={0,0,0,0,0};
09
10
int
dht11_read_val(){
11
uint8_t lststate=HIGH;
//last state
12
uint8_t counter=0;
13
uint8_t j=0,i;
14
for
(i=0;i<5;i++)
15
dht11_val[i]=0;
16
17
//host send start signal
18
pinMode(DHT11PIN,OUTPUT);
//set pin to output
19
digitalWrite(DHT11PIN,LOW);
//set to low at least 18ms
20
delay(18);
21
digitalWrite(DHT11PIN,HIGH);
//set to high 20-40us
22
delayMicroseconds(40);
23
24
//start recieve dht response
25
pinMode(DHT11PIN,INPUT);
//set pin to input
26
for
(i=0;i<MAX_TIME;i++)
27
{
28
counter=0;
29
while
(digitalRead(DHT11PIN)==lststate){
//read pin state to see if dht responsed. if dht always high for 255 + 1 times, break this while circle
30
counter++;
31
delayMicroseconds(1);
32
if
(counter==255)
33
break
;
34
}
35
lststate=digitalRead(DHT11PIN);
//read current state and store as last state.
36
if
(counter==255)
//if dht always high for 255 + 1 times, break this for circle
37
break
;
38
// top 3 transistions are ignored, maybe aim to wait for dht finish response signal
39
if
((i>=4)&&(i%2==0)){
40
dht11_val[j/8]<<=1;
//write 1 bit to 0 by moving left (auto add 0)
41
if
(counter>16)
//long mean 1
42
dht11_val[j/8]|=1;
//write 1 bit to 1
43
j++;
44
}
45
}
46
// verify checksum and print the verified data
47
if
((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))){
48
printf
(
"RH:%d,TEMP:%d\n"
,dht11_val[0],dht11_val[2]);
49
return
1;
50
}
51
else
52
return
0;
53
}
54
55
int
main(
void
){
56
int
attempts=ATTEMPTS;
57
if
(wiringPiSetup()==-1)
58
exit
(1);
59
while
(attempts){
//you have 5 times to retry
60
int
success = dht11_read_val();
//get result including printing out
61
if
(success) {
//if get result, quit program; if not, retry 5 times then quit
62
break
;
63
}
64
attempts--;
65
delay(2500);
66
}
67
return
0;
68
}
程序中的数据接收处理部分细节如下:
1
if
((i>=4)&&(i%2==0)){
//前3次分别是:1低电平,2高电平(即响应信号),3低电平(即数据第一个低电平)
2
//i%2==0 是因为每次都是循环读取低电平和高电平,每次要循环2次才读出一个bit处理
3
dht11_val[j/8]<<=1;
//读到后,j/8可以限制一个数的8个位,左移1位自动补0,相当于读出0
4
if
(counter>16)
//counter计数如果超过16,则高电平长,应读1.
5
dht11_val[j/8]|=1;
//故再将上面数与1位或,使最后一位变成1
6
j++;
//j++8个换成下一个数据
7
}
1
if
((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))){
2
3
//这其中(dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF)是将5个数相加,和1与。
4
//目的是防止读出数据都为0,和为0,0和1与后得0,所以if判断条件不成立,返回读取失败码。
5
//如果读出数据是不为0的正常数据,和1与后还得原数。
使用pi4j编写java程序:
在使用pi4j编写DHT11要求的时序时,始终收不到DHT11回应信号,个人感觉是java达不到DHT11要求的微秒级时序,所以java程序没有成功。如果有哪位大神成功用java写出DHT11程序,希望能赐教一下。
转自:http://my.oschina.net/fantasymaker/blog/275381
树莓派使用DHT11温湿度传感器(C语言程序)