|
图片及说明在新浪博客,就不搬过来了。
ps:两边都是我的博客,csdn更好用一些,所以就搬到这边,不存在抄袭。
int out=2; //2号IO口作为通信接口
void setup() {
Serial.begin(115200); //波特率115200
pinMode(out,INPUT); //IO口设为输入模式
}
void loop() {
begin(); //起始函数,向DHT11发送起始信号
int* b=read1();//读取传感器数据
display_1(b);//串口显示数据
}
void begin()
{
pinMode(out,OUTPUT);//io 设为输出模式,是因为测量发现DHT11的上拉电流有5mA,
//远大于输入模式下ATmega328的 io 的下拉电流,便无法得到 起始的至少28ms的低电平。
digitalWrite(out,HIGH);//io置高
delay(1400); //等待1.4s,因为DHT11的采样周期为1s,这里取的稍长一些。
digitalWrite(out,LOW);//io拉低,发送起始信号
delay(30); //延时至少28ms,这里取30ms
digitalWrite(out,HIGH);//拉高
pinMode(out,INPUT);//切换到输入模式,准备读数据
}
int* read1()
{
int a[6]={0,0,0,0,0,0};//定义数组,存放数据
int i,j;//变量,下面用到
int* b=new int[5];//用b将数据返回给loop()**此处将传感器数据传递出去用全局变量也行,但想试试其他方法***
delayMicroseconds(40);//延时40us,等待DHT11将io拉低
if(digitalRead(out)==0)//io读取值为0,说明DHT11已响应,io已经被拉低
{
while(digitalRead(out)==0);//等待80us的低电平结束
delayMicroseconds(90);//等待80us的高电平结束
for(i=0;i<5;i++)//5个元素,依次存放温度、溼度、校验值数据
{
for(j=0;j<8;j++)//依次读取各二进制位
{
while(digitalRead(out)==0);//等待50us的低电平结束
delayMicroseconds(40);//延时40us, 大于表示数据"0"的26-28us高电平,并小于表示数据“1”70us高电平
if(digitalRead(out)==0)//若io读取值为0,说明高电平时间小于40us,即为数据“0”
{
a[i]=a[i]|0x00;//数据最低位取0
}
else//若io读取值为1,说明高电平时间大于40us,即为数据“1”
{
a[i]=a[i]|0x01;//数据最高位取1
delayMicroseconds(35);//因数据“1”高电平时间为70us,70-40=30,这里取的比30稍大,确保io已经拉低
}
if(j<7)//最后一位不用移
{
a[i]=a[i]<<1;//得到二进制数的第一位之后,将数据左移一位
}
}
b[i]=a[i]; //依次将a[]传给b[];
}
}
else //如果io读取不为0,说明io没有被拉低
{
Serial.print(" DHT11未响应 , ");//则认为是DHT11未响应
for(i=0;i<1;i++) //溼度赋值为-1.溼度为负说明读取出错
{
b[i]=-1;
}
}
return b;//返回b ******此处将传感器数据传递出去用全局变量也行,但想试试其他方法****
}
void display_1(int b[])//显示函数
{
float WenDu,ShiDu,JiaoYanZhi;//定义浮点数据类型
ShiDu=b[0]+float(b[1])/10;//计算溼度,后面的float(b[1])是将int类型的b[1]转换为浮点数据,
//因为小于10的int类型数据除以10之后将总为0.
WenDu=b[2]+float(b[3])/10;//计算温度。
JiaoYanZhi=b[4];//校验值赋值
if(JiaoYanZhi==ShiDu+WenDu&&ShiDu>=0)//校验数据是否正确且溼度不小于0(溼度小于0说明
//上面的DHT11未向应),正确且溼度大于0则串口输出数据
{
digitalWrite(out,HIGH);//串口显示数据
Serial.print(" 温度:");
Serial.print(WenDu);
Serial.print("度 溼度:");
Serial.print(ShiDu);
Serial.println("% ");
}
else//校验数据是否正确,错误则串口错误提示
{
Serial.println("读取数据出错");
}
}