Arduino实现语音实时播报当前温湿度

    这几天气温极高,重庆竟然超过了44℃,我所在的杭州也达到了有气象记录以来的最高温41.8℃,于是心血来潮,做一个简单快速的语音播报当前实测到的温度,看看当前温度究竟是多少?

    手头正好有一个DHT11的测温湿度模块,该模块采用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上。关键是价格非常便宜,在某宝上不到3元就能买到,而且还包邮。

    好,闲话不说了,语音播报模块就用LU-ASR01,虽然说起来LU-ASR01是一块离线智能语音识别模块,不过拿来作为一个语音播报模块也很不错。

    硬件就是Arduino UNO一块,DHT11测温湿度模块一块,LU-ASR01离线智能语音识别模块一块,然后就是几根杜邦线。

    硬件连接方式:Arduino仍然采用硬件串口通信,使用TX和RX端口,LU-ASR01则使用IO6端口作为发送数据的软TX,IO7端口作为接收数据的软RX。由Arduino提供5V电源给LU-ASR01(下图中的红黑2线),Arduino的TX连接到LU-ASR01的IO7端口(软RX),Arduino的RX连接到LU-ASR01的IO6端口(软TX),DHT11的1脚(电源正极)连接到Arduino的3.3V(DHT11可以在3.3V或5V工作),4脚(地)连接到Arduino的地,2脚(DATA)连接到Arduino的D12。连接图如下:

     为简化程序的编写,Arduino端的程序调用了一个读取DHT11数据的简易库文件DHT.h,该库文件可以到网址:https://github.com/markruys/arduino-DHT下载,下载完全是免费的,也不需要进行注册登录等,打开网页后直接点击绿色的方块“Code”下拉,然后点击最后一项“Download ZIP”即可。网页界面见下图:

    我们仍然采用3字节报文进行通信(详细可参看本人之前写的《Arduino通过简单报文实现串口通信的尝试》),本次自定义了2条从Arduino端发送到LU-ASR01的报文命令,一条是发送温度数据的报文,格式定义如下:

        第1字节:0x23(十进制的35)发送温度数据

        第2字节:温度的整数部分

        第3字节:温度的2位小数

    第2条是发送湿度数据的报文,格式定义如下:

        第1字节:0x24(十进制的36)发送湿度数据

        第2字节:湿度的整数部分

        第3字节:湿度的2位小数

    另外定义了一条由LU-ASR01向Arduino发送的报文命令,请求Arduino发送当前的温度或湿度,报文格式定义如下:

        第1字节:0x25(十进制的37)请求发送当前的温度或湿度

        第2字节:未使用

        第3字节:=1则要求发送温度,=2则要求发送湿度

    当通电后,呼叫“当前温度”,则LU-ASR01发送请求温度数据报文,Arduino收到后,读取DHT11的温度数值,并将之发送给LU-ASR01,LU-ASR01收到该温度数据后则播报“目前的温度是XX度”。同样也可以通过呼叫“当前湿度”获得湿度的播报。

    Arduino端的完整程序如下:

/*

   本程序通过DHT11获得当前温湿度,并通过串口通信与ASR01连接,然后由ASR01播报

   当前温湿度。

   通信报文长度为3字节,报文格式:

   第1字节:命令编号   第2、3字节:数据

   本程序的报文用了三个命令:

   发送温度报文:编号:0x23(字节1),字节2温度整数部分,字节3温度2位小数部分

   发送湿度报文:编号:0x24(字节1),字节2湿度整数部分,字节3湿度2位小数部分

   接收请求发送温湿度报文:编号:0x25(字节1),字节2未使用,字节3  =1温度,=2湿度

*/

#include "DHT.h"

DHT dht;

#define MLEN 3   //定义报文长度为3

const int DHTPin =  12; // 定义DHTPin连接的引脚为D12

unsigned char Txbyte[MLEN];  //串口发送的字符数据,长度为MLEN

unsigned char Rxbyte[MLEN];  //串口读取的字符数据,长度为MLEN

float thtmp; //

//初始化

void setup() {

  Serial.begin(9600); //设置串口波特率9600

  pinMode(DHTPin, INPUT);  //设置DHTPin    

  dht.setup(DHTPin); // 设置DHT11数据传输的引脚

}

//发送报文子程序

//参数txb为准备发送的报文数据,n为报文长度

void txmss(unsigned char txb[],int n){

  int i;

  for(i=0;i<n;++i){

    Serial.write(txb[i]);

    delay(2);  

  }

}

//接收报文子程序,成功接收返回值为true,否则为false

//参数rxb为返回的报文数据,n为报文长度

bool rxmss(unsigned char rxb[],int n){

int i,dn;  //dn为超时计数器

  for (i=0; i<n; ++i) {

    dn=0;  //超时计数变量复位

    while(1){   //  

      if (dn<=50){  //设等待读取一字节的最大时间为50ms,若没有超时则

        if(Serial.available() > 0){ //当串口缓冲区有数据

          rxb[i]=Serial.read(); //读取一个字节

          break;  //跳出while(1)循环

        }

        else{  //若串口缓冲区没有数据,且没有超时,则超时计数器+1

          delay(1);

          dn+=1;    //超时计数器+1

        }

      }

      else return false;  //接收超时则函数rxmss退出,返回false

    }

  }

  return true;  //正常接收到n个字节,函数rxmss返回true

}

//主程序

void loop() {

  delay(dht.getMinimumSamplingPeriod()); //获取DHT11的最小采样周期

  if (Serial.available() > 0){     //当串口缓冲区有数据

    if (rxmss(Rxbyte,MLEN)){    //若成功接收到一个报文(即3字节数据已接收到数组Rxbyte)

      if(Rxbyte[0]==0x25) {    //若接收的Rxbyte[0]为0x25则为要求发送温湿度命令

        if(Rxbyte[2]==1){ //要求发送的是温度

          //填写报文

          Txbyte[0]=0x23;  //命令码0x23表示发送温度数据

          thtmp=(float) dht.getTemperature(); //从DHT11读取温度

          Txbyte[1]=(int) thtmp; //温度的整数部分放在Txbyte[1]

          Txbyte[2]=(int) (thtmp-Txbyte[1]*100);  //温度的2位小数放在Txbyte[2]

          txmss(Txbyte,MLEN);  //发送报文,将温度数据发送给LU-ASR01

        }

        if(Rxbyte[2]==2){ //要求发送的是湿度

          //填写报文

          Txbyte[0]=0x24;  //命令码0x24表示发送温度数据

          thtmp=(float) dht.getHumidity(); //从DHT11读取湿度

          Txbyte[1]=(int) thtmp; //湿度的整数部分放在Txbyte[1]

          Txbyte[2]=(int) (thtmp-Txbyte[1]*100);  //湿度的2位小数放在Txbyte[2]

          txmss(Txbyte,MLEN);  //发送报文,将湿度数据发送给LU-ASR01

        }

      }

    }

  }

}

    LU-ASR01端仍然采用“天问block”的图形化编程平台,下面是在“天问block”上的完整程序:

     做完后,我马上拿到室外去测试了下,一下子就到45度了,太热了,赶紧终止测试,逃回空调房间,哈哈……

本人网名为“不赦先生”,发表在CSDN上的文章均为本人原创,且仅在CSDN网站发布,其他网站的转载均未获得过本人的授权。

物联沃分享整理
物联沃-IOTWORD物联网 » Arduino实现语音实时播报当前温湿度

发表评论