(转)用c写的DHT11温湿度传感器

 

本来想找个I2C接口的温度传感器(比如MAX1668)玩玩,结果要么发现价格有点小贵,要么是蜘蛛脚,不好做实验。最后,采用了Arduiro DHT11电子积木,十分简单方便。电路原理图如下所示,

     

为了和Adafruit的例子保持一致,采用了同样的电路图接法。

引脚1接在3.3V电源上,引脚3悬空,引脚4接地。

引脚2接在面包板的P7 (也就是树莓派的PIN #7BCMGPIO #4)。注意,这里需要一个大小5.1K的上拉电阻。



    


 

好了,下面是我的面包板实验图,第一次居然忘了插数据线,所以没有读出数据,第二次插上数据线就一切正常了。

但是,我发现读到的数据错误率很高,不知道是电阻的问题还是程序的延时不精确导致的。

如果用定时器来实现延时,应该会比较好,以后再整吧!

$ sudo ./dht11
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 41 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}
Temp = 18 *C, Hum = 40 {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}


[cpp] view plain copy

 

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <dirent.h>  
  5. #include <fcntl.h>  
  6. #include <assert.h>  
  7. #include <unistd.h>  
  8. #include <sys/mman.h>  
  9. #include <sys/types.h>  
  10. #include <sys/stat.h>  
  11. #include <sys/time.h>  
  12. #include <unistd.h>  
  13. #include <bcm2835.h>  
  14.   
     
  15. #define DHT11_DATA RPI_V2_GPIO_P1_07   // RPi Pin #7  
  16.   
     
  17. int readDHT(int pin, unsigned int *data)  
  18. {  
  19.     int i = 0, j = 0;  
  20.     int counter = 0;  
  21.     int laststate = HIGH;  
  22.   
     
  23.     // Set GPIO pin to output  
  24.     bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);  
  25.   
     
  26.     bcm2835_gpio_write(pin, HIGH);  
  27.     usleep(500000); // 500ms  
  28.     bcm2835_gpio_write(pin, LOW);  
  29.     usleep(20000);  // 20ms  
  30.   
     
  31.     // Set GPIO pin to input  
  32.     bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);  
  33.   
     
  34.     // wait for pin to drop?  
  35.     while (bcm2835_gpio_lev(pin) == 1) {  
  36.         usleep(1);  
  37.     }  
  38.   
     
  39.     // reading data  
  40.     for (i = 0; i < 100; i++) {  
  41.         counter = 0;  
  42.         while (bcm2835_gpio_lev(pin) == laststate) {  
  43.             counter++;  
  44.             if (counter == 1000)  
  45.                 break;  
  46.         }  
  47.         if (counter == 1000) break;  
  48.         laststate = bcm2835_gpio_lev(pin);  
  49.   
     
  50.         // shove each bit into the storage bytes  
  51.         if ((i > 3) && (i {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03} 2 == 0)) {  
  52.             data[j / 8] <<= 1;  
  53.             if (counter > 200)  
  54.                 data[j / 8] |= 1;  
  55.             j++;  
  56.         }  
  57.     }  
  58.   
     
  59.     /*printf(“DHT11 Data ({d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d bits): 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x\n”, 
  60.             j, data[0], data[1], data[2], data[3], data[4]);*/  
  61.     if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {  
  62.         printf(“Temp = {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d *C, Hum = {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d \{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}\n”, data[2], data[0]);  
  63.         return 1;  
  64.     }  
  65.   
     
  66.     return 0;  
  67. }  
  68.   
     
  69. int main(int argc, char **argv)  
  70. {  
  71.     uint8_t counter = 0;  
  72.     uint32_t data[100];  
  73.   
     
  74.     if (!bcm2835_init())    
  75.         return 1;    
  76.   
     
  77.     while (counter < 10) {  
  78.         memset(data, 0, 100 * sizeof(uint32_t));  
  79.         if (readDHT(DHT11_DATA, data))  
  80.             counter++;  
  81.     }  
  82.   
     
  83.     bcm2835_close();    
  84.     return 0;    
  85. }  


最后,玩个增强版,用检测的温度来控制LED。我把电脑的出风口放在传感器旁边,明显看到温度上升,嘿嘿!

上图配修改后的程序,完美收官!

[cpp] view plain copy

 

  1. int main(int argc, char **argv)  
  2. {  
  3.     uint8_t counter = 0;  
  4.     uint32_t data[100];  
  5.   
     
  6.     if (!bcm2835_init())    
  7.         return 1;    
  8.   
     
  9.     // Set the pin to be an output  
  10.     bcm2835_gpio_fsel(LED, BCM2835_GPIO_FSEL_OUTP);    
  11.   
     
  12.     while (counter < 10) {  
  13.         memset(data, 0, 100 * sizeof(uint32_t));  
  14.         if (readDHT(DHT11_DATA, data)) {  
  15.             counter++;  
  16.   
     
  17.             if (data[2] != 18) {  
  18.                 bcm2835_gpio_write(LED, HIGH);  
  19.             } else {  
  20.                 bcm2835_gpio_write(LED, LOW);  
  21.             }  
  22.         }  
  23.   
     
  24.         bcm2835_delay(1000);  
  25.     }  
  26.   
     
  27.     bcm2835_close();    
  28.     return 0;    
  29. }  


 

参考资料

1. DHT Humidity Sensing on Raspberry Pi or Beaglebone Black with GDocs Logging

2. 树莓派动手实验-2.温湿度传感器DHT11实验

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注