#define vcc 9 //2号IO口作为通信接口
#define out 10
#define nc 11
#define gnd 12
#define contral 13
void setup() {
Serial.begin(9600); //波特率9600,太高linux端乱码
pinMode(vcc, OUTPUT);
pinMode(out, INPUT);
pinMode(contral, INPUT);
digitalWrite(contral, HIGH);
pinMode(nc, INPUT);
pinMode(gnd, OUTPUT); //IO口设为输入模式
digitalWrite(vcc, HIGH);
digitalWrite(gnd, LOW);
}
void loop() {
delay(500);
beginDHT(); //起始函数,向DHT11发送起始信号
unsigned char* b = read1();//读取传感器数据
display_1(b);//串口显示数据
}
void beginDHT()
{
pinMode(out, OUTPUT);//io 设为输出模式,是因为测量发现DHT11的上拉电流有5mA,
//远大于输入模式下ATmega328的 io 的下拉电流,便无法得到 起始的至少28ms的低电平。
digitalWrite(out, HIGH);//io置高
delay(1100); //等待1.4s,因为DHT11的采样周期为1s,这里取的稍长一些。
digitalWrite(out, LOW);//io拉低,发送起始信号
delay(30); //延时至少28ms,这里取30ms
digitalWrite(out, HIGH);//拉高
pinMode(out, INPUT);//切换到输入模式,准备读数据
}
unsigned char*read1()
{
//int a[6]={0,0,0,0,0,0};//定义数组,存放数据
int i, j;//变量,下面用到
unsigned char* b = new unsigned char[5];//用b将数据返回给loop()***此处将传感器数据传递出去用全局变量也行,但想试试其他方法****
for (i = 0; i < 5;i++)
b = 0;
delayMicroseconds(40);//延时40us,等待DHT11将io拉低
if (digitalRead(out) == 0)//io读取值为0,说明DHT11已响应,io已经被拉低
{
while (digitalRead(out) == 0);//等待80us的低电平结束
delayMicroseconds(82);//等待80us的高电平结束
for (i = 0; i < 5; i++)//5个元素,依次存放温度、湿度、校验值数据
{
for (j = 0; j < 8; j++)//依次读取各二进制位
{
b= b << 1;//得到二进制数的第一位之后,将数据左移一位
while (digitalRead(out) == 0);//等待50us的低电平结束
delayMicroseconds(32);//延时40us,大于表示数据“0”的26-28us高电平,并小于表示数据“1”70us高电平
if (digitalRead(out) == 0)//若io读取值为0,说明高电平时间小于40us,即为数据“0”
{
b = b | 0x00;//数据最低位取0
}
else//若io读取值为1,说明高电平时间大于40us,即为数据“1”
{
b = b | 0x01;//数据最高位取1
delayMicroseconds(40);//因数据“1”高电平时间为70us,70-40=30,这里取的比30稍大,确保io已经拉低
}
}
}
//b=a; //依次将a[]传给b[];
}
else //如果io读取不为0,说明io没有被拉低
{
// Serial.print(" DHT11未响应 , ");//则认为是DHT11未响应
for (i = 0; i < 5; i++) //湿度赋值为-1.湿度为负说明读取出错
{
b = 0;
}
}
returnb;//返回b ******此处将传感器数据传递出去用全局变量也行,但想试试其他方法****
}
void display_1(unsigned char b[])//显示函数
{
int c = (b[0] + b[1] + b[2] + b[3]) & 0xff;
unsigned char JiaoYanZhi;
int avaliable = -1;
charnumber[5];
floatWenDu, ShiDu;//定义浮点数据类型
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 == c&& ShiDu > 0)//校验数据是否正确且湿度不小于0(湿度小于0说明
//上面的DHT11未向应),正确且湿度大于0则串口输出数据
{
//digitalWrite(out,HIGH);//串口显示数据
//Serial.println(avaliable);
Serial.print("温度:");
//itoa(20,number,10);
Serial.print(WenDu);
Serial.print("_度
");
//Serial.println(int(WenDu));
Serial.print("湿度:");
Serial.print(ShiDu);
Serial.print("_%");
/*
Serial.print(" 校验值");
Serial.print(JiaoYanZhi);
Serial.print(" 计算值:");
Serial.print(c);
if(JiaoYanZhi!=c)
Serial.print("*************");
Serial.println("");
*/
}
else//校验数据是否正确,错误则串口错误提示
{
Serial.println("读取数据出错~");
}
//接收到S(ascii码83)T(ascii码84) 之后继续运行
while(avaliable != 83 && digitalRead(contral) == 0)
{
avaliable =Serial.read();
delay(200);
}
while(avaliable != 84 && digitalRead(contral) == 0) {
avaliable =Serial.read();
delay(200);
}
while(avaliable != -1 && digitalRead(contral) == 0) {
avaliable =Serial.read();
delay(200);
}
}