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

为了和Adafruit的例子保持一致,采用了同样的电路图接法。
引脚1接在3.3V电源上,引脚3悬空,引脚4接地。
引脚2接在面包板的P7 (也就是树莓派的PIN #7,BCM的GPIO #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
-
#include <stdio.h>
-
#include <string.h>
-
#include <stdlib.h>
-
#include <dirent.h>
-
#include <fcntl.h>
-
#include <assert.h>
-
#include <unistd.h>
-
#include <sys/mman.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <sys/time.h>
-
#include <unistd.h>
-
#include <bcm2835.h>
-
-
#define DHT11_DATA RPI_V2_GPIO_P1_07 // RPi Pin #7
-
-
int readDHT(int pin, unsigned int *data)
-
{
-
int i = 0, j = 0;
-
int counter = 0;
-
int laststate = HIGH;
-
-
// Set GPIO pin to output
-
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
-
-
bcm2835_gpio_write(pin, HIGH);
-
usleep(500000); // 500ms
-
bcm2835_gpio_write(pin, LOW);
-
usleep(20000); // 20ms
-
-
// Set GPIO pin to input
-
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
-
-
// wait for pin to drop?
-
while (bcm2835_gpio_lev(pin) == 1) {
-
usleep(1);
-
}
-
-
// reading data
-
for (i = 0; i < 100; i++) {
-
counter = 0;
-
while (bcm2835_gpio_lev(pin) == laststate) {
-
counter++;
-
if (counter == 1000)
-
break;
-
}
-
if (counter == 1000) break;
-
laststate = bcm2835_gpio_lev(pin);
-
-
// shove each bit into the storage bytes
-
if ((i > 3) && (i {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03} 2 == 0)) {
-
data[j / 8] <<= 1;
-
if (counter > 200)
-
data[j / 8] |= 1;
-
j++;
-
}
-
}
-
-
/*printf(“DHT11 Data ({d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d bits): 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x 0x{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}x\n”,
-
j, data[0], data[1], data[2], data[3], data[4]);*/
-
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
-
printf(“Temp = {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d *C, Hum = {d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}d \{d4daabd1ba368d9860c36387ddb72bbda14f8f9559d69d60a952800885260c03}\n”, data[2], data[0]);
-
return 1;
-
}
-
-
return 0;
-
}
-
-
int main(int argc, char **argv)
-
{
-
uint8_t counter = 0;
-
uint32_t data[100];
-
-
if (!bcm2835_init())
-
return 1;
-
-
while (counter < 10) {
-
memset(data, 0, 100 * sizeof(uint32_t));
-
if (readDHT(DHT11_DATA, data))
-
counter++;
-
}
-
-
bcm2835_close();
-
return 0;
-
}
最后,玩个增强版,用检测的温度来控制LED。我把电脑的出风口放在传感器旁边,明显看到温度上升,嘿嘿!
上图配修改后的程序,完美收官!
[cpp] view plain copy
-
int main(int argc, char **argv)
-
{
-
uint8_t counter = 0;
-
uint32_t data[100];
-
-
if (!bcm2835_init())
-
return 1;
-
-
// Set the pin to be an output
-
bcm2835_gpio_fsel(LED, BCM2835_GPIO_FSEL_OUTP);
-
-
while (counter < 10) {
-
memset(data, 0, 100 * sizeof(uint32_t));
-
if (readDHT(DHT11_DATA, data)) {
-
counter++;
-
-
if (data[2] != 18) {
-
bcm2835_gpio_write(LED, HIGH);
-
} else {
-
bcm2835_gpio_write(LED, LOW);
-
}
-
}
-
-
bcm2835_delay(1000);
-
}
-
-
bcm2835_close();
-
return 0;
-
}
参考资料
1. DHT Humidity Sensing on Raspberry Pi or Beaglebone Black with GDocs Logging





