树莓派论坛

 找回密码
 立即注册

树莓派2B实现温湿度监控(DHT22温湿度传感器)两种方式

无名族 发表于 2015-3-15 20:50:15 | 显示全部楼层 |阅读模式
前言:一时兴起,买了个树莓派2b,信心满满的准备好好研究一番,结果光安装系统就折腾了两天,本人虽然懂些PHP,但是都是在windows下操作,Linux接触很少,C更是一塌糊涂,最终一番折腾,也算是圆满实现,写个教程让大家少走弯路,网上基于树莓派2B的教程较少,很多操作按照教程来做根本无法实现,中间走了很多弯路,本教程适合新手,高手请略过。。。
硬件:树莓派2B DHT22温湿度传感器(买的集成好的模块,已有上拉电阻)
系统:Raspbian Debian Wheezy 2014-02-16
读取操作:基于wiringPi或BCM2835 C Library
接线:/DHT22共有三根引脚(有的是四根):
1–>3.3v 接左边第1个GPIO针脚
2–>GPIO 数据接口,可随意连接1个GPIO针脚(第7个针脚对应的是GPIO Pin #4)
3–>NC 不接(我的没这个引脚
3–>GND 接地(第6个针脚)
声明:以下操作均在root权限下进行
一、首先说说基于wiringPi读取:
wiringPi操作相对简单,只要系统安装wiringPi:
  1. git clone git://git.drogon.net/wiringPi
  2. cd wiringPi
  3. git pull origin
  4. cd wiringPi
  5. ./build
复制代码
到这里wiringPi安装完毕,你可以输入gpio readall看下引脚的定义。
获取操作更简单,直接把代码编译执行就行了,我找了个dht11的读取代码,然后修改了下:
  1. #include <wiringPi.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #define MAX_TIME 100
  6. #define DHT11PIN 7 //读取数据引脚
  7. #define ATTEMPTS 5                 //retry 5 times when no response
  8. int dht11_val[5]={0,0,0,0,0};
  9.   
  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.     //host send start signal   
  17.     pinMode(DHT11PIN,OUTPUT);      //set pin to output
  18.     digitalWrite(DHT11PIN,LOW);    //set to low at least 18ms
  19.     delay(18);
  20.     digitalWrite(DHT11PIN,HIGH);   //set to high 20-40us
  21.     delayMicroseconds(30);
  22.      
  23.     //start recieve dht response
  24.     pinMode(DHT11PIN,INPUT);       //set pin to input
  25.     for(i=0;i<MAX_TIME;i++)         
  26.     {
  27.         counter=0;
  28.         while(digitalRead(DHT11PIN)==lststate){     //read pin state to see if dht responsed. if dht always high for 255 + 1 times, break this while circle
  29.             counter++;
  30.             delayMicroseconds(1);
  31.             if(counter==255)
  32.                 break;
  33.         }
  34.         lststate=digitalRead(DHT11PIN);             //read current state and store as last state.
  35.         if(counter==255)                            //if dht always high for 255 + 1 times, break this for circle
  36.             break;
  37.         // top 3 transistions are ignored, maybe aim to wait for dht finish response signal
  38.         if((i>=4)&&(i%2==0)){
  39.             dht11_val[j/8]<<=1;                     //write 1 bit to 0 by moving left (auto add 0)
  40.             if(counter>16)                          //long mean 1
  41.                 dht11_val[j/8]|=1;                  //write 1 bit to 1
  42.             j++;
  43.         }
  44.     }
  45.     // verify checksum and print the verified data
  46.     if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))){
  47.         float f, h;
  48.           h = dht11_val[0] * 256 + dht11_val[1];
  49.           h /= 10;
  50.           f = (dht11_val[2] & 0x7F)* 256 + dht11_val[3];
  51.         f /= 10.0;
  52.         if (dht11_val[2] & 0x80)  f *= -1;
  53.           printf("Temp =  %.1f *C, Hum = %.1f \%\n", f, h);
  54.         return 1;
  55.     }
  56.     else
  57.         return 0;
  58. }
  59.   
  60. int main(void){
  61.     int attempts=ATTEMPTS;
  62.     if(wiringPiSetup()==-1)
  63.         exit(1);
  64.     while(attempts){                        //you have 5 times to retry
  65.         int success = dht11_read_val();     //get result including printing out
  66.         if (success) {                      //if get result, quit program; if not, retry 5 times then quit
  67.             break;
  68.         }
  69.         attempts--;
  70.         delay(2500);
  71.     }
  72.     return 0;
  73. }
复制代码
保存为test.c编译执行即可看到温度和湿度,很多教程也是到此结束,给个结果的截图,但对于新手来说,怎么编译是个问题,当然包括我在内,百度后知道是gcc -o 可怎么也编译不成功,后来细致的看了下gcc的命令,发现需要加-l参数来指定库名,这个对于老手来说肯定要笑了。
执行编译运行:
  1. gcc -Wall -o test test.c -lwiringPi
  2. ./test
复制代码
如果不出意外,你就看到了执行结果:
二、再说说基于BCM2835 C Library读取:
这部分是折腾我的地方,本来先是尝试的这种方法,按照网上教程,一路下来,发现只要读取就没反应,什么结果都不出卡在那里,后来觉得是版本问题,改了下代码只执行gpio端口设置为OUT,执行后发现,根本就没变,因为2B是bcm2836的芯片,然后就是各种搜,QQ群求助也是让找2836的,可怎么也找不到,无奈去http://www.airspayce.com/mikem/bcm2835一看,最新版本为1.42,我下载的是1.36,会不会最新版本支持呢,重新下载编译,尝试读取,成功,下面是操作过程:
首先安装BCM2835 C Library
  1. wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.42.tar.gz
  2. tar xvzf bcm2835-1.42.tar.gz
  3. cd bcm2835-1.42
  4. ./configure
  5. make
  6. make check
  7. make install
复制代码
下载dht22读取程序编译读取:
  1. cd /home/pi
  2. git clone https://github.com/dohkoos/Raspberry-Pi-Code.git
  3. cd Raspberry-Pi-Code/DHT22
  4. make
  5. ./dht 22 4 #数据接口接在第7针脚,所以这里是4
复制代码
来个图:
dht22.jpg




评分

参与人数 1 +2 收起 理由
piczero + 2 很给力!

查看全部评分

wtchennewmyy 发表于 2015-3-20 00:38:18 | 显示全部楼层
mark 以后应该能用到
树老大 发表于 2015-3-15 22:05:15 | 显示全部楼层
这必须赞美啊。
kidsuntown 发表于 2015-3-18 10:14:34 | 显示全部楼层
不错啊,一直没搞定
ZWeiandLen 发表于 2015-3-18 11:11:00 | 显示全部楼层
哦哦哦,好帖要顶,最喜欢这种头一回的帖子了
PiHackCode 发表于 2015-3-21 10:20:03 | 显示全部楼层
洒洒水水水水水水
princezhou 发表于 2015-3-23 13:26:57 | 显示全部楼层
这是我需要的,感谢啊,搞起!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版 | Archiver | 树莓派论坛 ( 粤ICP备15075382号-1 )