zoukankan      html  css  js  c++  java
  • 树莓派使用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程序:

    如下程序借鉴了网上一老外的程序,忘了原帖地址在哪。

    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 ",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 }
    上述程序保存为.c文件后编译成可执行文件,运行后会在屏幕打印温度和湿度。 

    程序中的数据接收处理部分细节如下:

    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

  • 相关阅读:
    超参数调优
    集成学习(一)
    L1范数与L2范数
    HMM与CRF
    主题模型LDA
    性能评估指标
    java-jdk8下载及安装
    pandas相关性分析
    pandas小技巧
    Window—mysql下载及安装
  • 原文地址:https://www.cnblogs.com/Pond-ZZC/p/6680446.html
Copyright © 2011-2022 走看看