器件准备
硬件:HC-06蓝牙模块、DHT11温湿度传感器,arduino开发板、杜邦线若干
开发环境:arduino uno
硬件连接
注意:下载程序的时候不能连接arduino板上的RXD和TXD,如果连接了,程序下载不进去。
蓝牙模块的使用:
DHT11传感器说明:
一次通信时间4毫秒左右,主控板发送一次开始信号后,DHT11从低功耗模式转换到高速模式,触发一次温湿度采集;等待开始信号结束后,DHT11发送响应信号,送出40bit的数据。如果没有接收到主控板发送的开始信号,DHT11不会主动进行温湿度采集。采集数据后DHT11转换到低速模式。
由于有上拉电阻,总线空闲状态为高电平。当Arduino主控板把总线拉低时,释放开始信号等待DHT11响应。注意:主控板把总线拉低必须大于18毫秒,以保证DHT11能检测到起始信号。主控板发送开始信号结束后,释放总线或者输出高电平,延时等待20~40微秒后,切换到输入模式,读取DHT11的响应信号。
DHT11接收到主控板的开始信号,等待开始信号结束后,发送80微秒低电平响应信号。
DHT11发送响应信号后,再把总线拉高80微秒,准备发送数据。每一位数据都以50微秒低电平时隙开始,高电平的长短决定了数据位是0还是1。当最后一位数据传送完毕后,DHT11拉低总线50微秒,随后总线由上拉电阻拉高进入空闲状态。
数字0信号表示方法
数字1信号表示方法
DHT11()函数
(完整代码附后面)
app inventor(上位机制作)
蓝牙和界面初始化
手机端接收数据
计时器更新当前时间
按钮功能设置
手机端界面:
完整代码
#define DHT11_PIN 0 // DHT11输入输出引脚连接在Arduino UNO 模拟端口0
byte dht11_dat[5]; //存储从DHT11传感器采样的温湿度值的数组
int ReceiveByte = 0;
/********************初始化********************/
void setup()
{
DDRC |= _BV(DHT11_PIN); // 配置DHT11_PIN配置为输出
PORTC |= _BV(DHT11_PIN); // 第DHT11_PIN位置1,其他位不变
Serial.begin(9600);
}
/********************循环语句********************/
void loop()
{
while(1)
{
if (Serial.available()> 0)
{ //串口是否有输入
ReceiveByte = Serial.read();
switch(ReceiveByte)
{
case 0x30: //十进制数值48转换为十六进制数值30
DHT11();
Serial.print(99,DEC); //发送温度识别码
Serial.print(dht11_dat[2],DEC); //发送温度值
Serial.print(98,DEC); //发送湿度识别码
Serial.print(dht11_dat[0],DEC); //发送湿度值
break;
default:
break;
}
}
}
}
/********************DHT11温湿度模块子函数********************/
void DHT11()
{
byte dht11_in;
int i;
PORTC &= ~_BV(DHT11_PIN); //拉低总线,给DHT11送开始信号
delay(18); //延时18毫秒
PORTC |= _BV(DHT11_PIN); //释放总线,开始信号结束
delayMicroseconds(40); //延时40微秒
DDRC &= ~_BV(DHT11_PIN); //端口转为输入
delayMicroseconds(40);
dht11_in = PINC & _BV(DHT11_PIN); //读输入电平
if(dht11_in)
{
Serial.println("dht11 response signal 1 not received");
//未收到响应信号低电平
return;
}
delayMicroseconds(80); //延时80微秒
dht11_in = PINC & _BV(DHT11_PIN);
if(!dht11_in)
{
Serial.println("dht11 response signal 2 not received");
//未收到响应信号高电平
return;
}
delayMicroseconds(80); //延时80微秒
// 读取来自DHT11传感器的5个字节温湿度值
//第一个字节是湿度值整数部分,dht11_dat[0]
//第二个字节是湿度值小数部分,dht11_dat[1]
//第三个字节是温度值整数部分,dht11_dat[2]
//第四个字节是温度值小数部分,dht11_dat[3]
//第五个字节是校验值,可以判断数据传送是否正确,dht11_dat[4]
for (i=0; i<5; i++)
dht11_dat[i] = read_dht11_dat();
byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
if(dht11_dat[4]!= dht11_check_sum) //验证校验码
{
Serial.println("DHT11 checksum error"); //校验错误告警
}
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
}
/********************DHT11温湿度模块数据读取子函数********************/
byte read_dht11_dat()
{
int i = 0;
byte result=0;
for(i=0; i< 8; i++){
while(!(PINC & _BV(DHT11_PIN))); //自循环,等待低电平结束
delayMicroseconds(30); //延时30微秒
if(PINC & _BV(DHT11_PIN)) //如果是高电平,表示信号1
result |=(1<<(7-i));
while((PINC & _BV(DHT11_PIN))); //自循环,等待高电平结束
}
return result;
}