使用Seeeduino v4.2和Groove Temperature&Humidity Sensor v1.2传感器套件。
代码如下:
#define DHT11_PIN (5) //SCL引脚内部和ANALOG5相连,实际是PC5端口
byte dht11_dat[5]; //存储dht11的5字节数据
/*
从DHT11中读取一个byte的数据
*/
byte read_dht11_dat()
{
byte i = 0;
byte result = 0;
for (i = 0; i < 8; i++) {
while (!(PINC & _BV(DHT11_PIN))); // wait for 50us
delayMicroseconds(30);
if (PINC & _BV(DHT11_PIN))
result |= (1 << (7 - i));
while ((PINC & _BV(DHT11_PIN))); // wait '1' finish
}
return result;
}
/*
从DHT11中读取一次数据
*/
byte read_dht11()
{
byte dht11_in; //存储当前端口读取的值
byte i;
// start condition
// 1. pull-down i/o pin from 18ms
PORTC &= ~_BV(DHT11_PIN); //拉低
delay(18);
PORTC |= _BV(DHT11_PIN); //拉高
delayMicroseconds(40);
DDRC &= ~_BV(DHT11_PIN);
delayMicroseconds(40);
dht11_in = PINC & _BV(DHT11_PIN);
if (dht11_in) {
//Serial.println("dht11 start condition 1 not met");
return 1;
}
delayMicroseconds(80);
dht11_in = PINC & _BV(DHT11_PIN);
if (!dht11_in) {
//Serial.println("dht11 start condition 2 not met");
return 2;
}
delayMicroseconds(80);
// now ready for data reception
for (i = 0; i < 5; i++)
dht11_dat[i] = read_dht11_dat();
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
byte dht11_check_sum = dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3];
// check check_sum
if (dht11_dat[4] != dht11_check_sum)
{
//Serial.println("DHT11 checksum error");
return 3;
}
return 0;
}
void setup()
{
DDRC |= _BV(DHT11_PIN); //Data Direction Register(数据方向寄存器)
PORTC |= _BV(DHT11_PIN); //数据寄存器
Serial.begin(9600);
Serial.println("Ready");
}
void loop()
{
byte ret=read_dht11();
if(ret!=0)
{
Serial.println("dht11 error!");
return ;
}
Serial.print("Current humdity = ");
Serial.print(dht11_dat[0], DEC);
Serial.print(".");
Serial.print(dht11_dat[1], DEC);
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(dht11_dat[2], DEC);
Serial.print(".");
Serial.print(dht11_dat[3], DEC);
Serial.println("C ");
delay(2000);
}
其中#define _BV(bit) (1 << (bit))
,用于方便读写位的值。
注意两次数据读取间隔要高于1s,详情见DHT11使用笔记。
实际效果如下: