本帖最后由 huihui1 于 2023-7-16 22:54 编辑
一、项目简介 本项目是基于启明6M5开发板完成了空气质量检测系统,传感器M702采集甲醛、二氧化碳、PM2.5、PM10、TVOC的浓度和温湿度;甲醛、二氧化碳、PM2.5、PM10、TVOC的浓度和温湿度通过wifi模块周期性上传到阿里云物联网平台,能够实时更新数据;1.77寸TFT彩屏提供显示功能,能够显示甲醛、二氧化碳等浓度和温湿度。
二、项目说明 调试环境:
开发环境:windows10;
IDE:MDK5.38a;
RASC:V4.0.0;
调试器:PWLINK2;
空气质量检测系统的核心功能如下:
1.实时监控室内环境信息,如甲醛、二氧化碳、PM2.5、PM10、TVOC浓度和温湿度;
2.实时检测环境信息并将其信息显示在TFT屏上,也可通过WIFI传至云端;
3.环境信息可通过WIFI上传至阿里云物联网平台显示。
三、方案设计 1.系统硬件方案
空气质量检测系统以R7FA6M5主控芯片组为核心,由M702七合一空气质量检测模块、TFT显示模块、ESP8266WIFI构成。
硬件架构图实现如下:
2.模块介绍
M702七合一传感器模块是一款高性价比的数字串口输出传感器模块,采用UART串口电平输出模式,集CO2,甲醛,TVOC,激光粉尘PM2.5,PM10颗粒物,温度,湿度于一体。它可对所处环境进行实时全面的检测,具有良好的稳定性非常方便客户使用。
应用领域:
● 酒店房间空气质量监控
● 农业大棚,户外养殖场所环境监控
● 新风换气系统
● 空气净化器,空调
● 空气质量监测设备
● 厨卫换气控制系统
● 智能家居设备
特点:
● 同时输出二氧化碳.甲醛.TVOC.PM2.5. PM10.温度.湿度共七组数据
● 灵敏度高,数据稳定
● UART 输出模式
● 温度精确到0.1℃,湿度精确到0.1%
● 每2秒自动通过UART信号输出七组传感器监测数据
规格参数:
类 别 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 2分钟(只有CO2,CH2O和TVOC需要预热,其它参数上电即显示) | | | | | | | | | 注意:模块输出的CO2值和CH2O值均为TVOC的等效值,客户购买和使用时请注意。
UART 接口定义: 串口数据流格式:
通信协议: 说明:校验和B17等于:B1+B2+······B16的值,取低8位。 当温度的数据 B13 的bit7=1 时, 代表是负温度,B13 的bit7=0 时,是正温度。例如,当 B13=9Bh 时,此时 bit7=1, 表示是负温度,此时实际温度就是-27℃;如果 B13=1Bh,此时bit7=0,代表是正温度,此时实际温度就是 27℃。
3.1.77寸TFT彩屏
SPI通讯,采用中景园电子代码。
4.WIFI
采用板载ESP8266烧录MQTT透传AT固件。
四、具体功能介绍
1.M702模块的数据读取
M702连接示意图
串口通道采用:UART4 P511 P512
代码实现:
读取M702发送的数据保存到数组中,在读取出来。
/* 串口中断回调 */
void debug_uart4_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
if(p_args->event == UART_EVENT_RX_CHAR)
{
RxBuff[0] =p_args->data;
RxLine++; //每接收到一个数据,进入回调数据长度加1
DataBuff[RxLine-1]=RxBuff[0]; //把每次接收到的数据保存到缓存数组
Rx_flag=1;
//接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
// if(RxBuff[0]==)
// {
// Rx_flag_finish=1;
// }
Rx_flag_finish=1;
RxBuff[0]=0;
// err = R_GPT_Reset(&g_timer0_ctrl);
// assert(FSP_SUCCESS == err);
}
}
//接受数据
void printf_usart(void)
{
// printf("length=%d\r\n",RxLine);//接收到的长度
for(int i=0;i<RxLine;i++)
{};
//printf("data:[%d] = 0x%x\r\n",i,DataBuff);//接收到的数据
//处理数据
co2= (DataBuff[2]*256 + DataBuff[3]);//co2浓度
ch2o=(DataBuff[4]*256 + DataBuff[5]);//甲醛
tvoc=(DataBuff[6]*256 + DataBuff[7]);
pm2_5=(DataBuff[8]*256 + DataBuff[9]);
pm10=(DataBuff[10]*256 + DataBuff[11]);
temp1=DataBuff[12];
temp2=(DataBuff[12]+DataBuff[13]*0.1);
hud1=DataBuff[14];
hud2=(DataBuff[14]+DataBuff[15]*0.1);
// printf("CO2浓度= %d ppm\r\n",co2);
// printf("甲醛浓度= %d μg/m3\r\n",ch2o);
// printf("tvoc= %dμg/m3\r\n",tvoc);
// printf("pm2.5= %dμg/m3\r\n",pm2_5);
// printf("pm10= %dμg/m3\r\n",pm10);
// printf("温度= %f ℃\r\n",temp2);
// printf("湿度= %f %RH \r\n",hud2);
memset(DataBuff,0,sizeof(DataBuff)); //清空缓存数组
//memset()作用:可以方便的清空一个结构类型的变量或数组。
//例句:memset(aTxbuffer,0,sizeof(aTxbuffer)) 用memset清空aTxbuffer。
RxLine=0; //清空接收长度
Rx_flag_finish=0;
Rx_flag = 0;
}
2.MQTT
1. MQTT协议简介
MQTT协议全称是Message Queuing Telemetry Transport,翻译过来就是消息队列遥测传输协议,它是物联网常用的应用层协议,运行在TCP/IP中的应用层中,依赖TCP协议,因此它具有非常高的可靠性,同时它是基于TCP协议的<客户端-服务器>模型发布/订阅主题消息的轻量级协议,也是我们常说的发送与接收数据,下面我们来初步了解一下mqtt相关的名称与功能。
MQTT通信模型
MQTT 协议提供一对多的消息发布,可以降低应用程序的耦合性,用户只需要编写极少量的应用代码就能完成一对多的消息发布与订阅,该协议是基于<客户端-服务器>模型,在协议中主要有三种身份:发布者(Publisher)、服务器(Broker)以及订阅者(Subscriber)。其中,MQTT消息的发布者和订阅者都是客户端,服务器只是作为一个中转的存在,将发布者发布的消息进行转发给所有订阅该主题的订阅者;发布者可以发布在其权限之内的所有主题,并且消息发布者可以同时是订阅者,实现了生产者与消费者的脱耦,发布的消息可以同时被多个订阅者订阅。
MQTT客户端的功能:
1.发布消息给其它相关的客户端。
2.订阅主题请求接收相关的应用消息。
3.取消订阅主题请求移除接收应用消息。
4.从服务端终止连接。
MQTT 服务器常被称为 Broker(消息代理),以是一个应用程序或一台设备,它一般为云服务器,比如BTA三巨头的一些物联网平台就是常使用MQTT协议,它是位于消息发布者和订阅者之间,以便用于接收消息并发送到订阅者之中,它的功能有:
1.接受来自客户端的网络连接请求。
2.接受客户端发布的应用消息。
3.处理客户端的订阅和取消订阅请求。
4.转发应用消息给符合条件的已订阅客户端(包括发布者自身)。
阿里云配置
具体阿里云的注册设置参照:
http://t.csdn.cn/L8SWn
AT指令让 ESP8266 连接阿里云
第一步 AT+RST
第二步 AT+CWMODE=1
第三步 AT+CIPSNTPCFG=1.8"ntp1.alivun.com"
第四步 AT+CWJAP="WiFi 名字""WiFi 密码"
第五步 AT+MQTTUSERCFG=0,1,"NULL","用户名","密码",0,0,"
第六步 AT+MQTTCLIENTID=0,"Clienld" //clientld 第二个参数注意每个逗号前加分隔符
第七步 AT+MQTTCONN=0,"连接域名",1883,1
AT+MQTTSUB=0,"topic",1 //订阅指令
AT+MQTTPUB=0,"topic","Json格式内容",1,0 //发布指令
AT+MQTTCLEAN=O //断开连接
具体代码实现:
static char* ssid = "MI";//wifi名
static char* pswd = "147258369";//密码
static char* aliyun = "ntp1.aliyun.com";
//连接WiFi和阿里云
void AT_Init(void)
{
// printf("AT\r\n");
// R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+RST\r\n");
R_BSP_SoftwareDelay(4500, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CWMODE=1\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pswd);
LED1_ON;//点亮LED1
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CIPSNTPCFG=1,8,\"%s\"\r\n",aliyun);
LED2_ON;//点亮LED2
LED1_OFF;//熄灭LED1
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTUSERCFG=0,1,\"NULL\",\"Air-quality-detection-system&ivs8zZPrvfk\",\"33e40cee05fce2fbbca52cf939a2e12843c860d02ec5b2175ba80d73a3b25507\",0,0,\"\"\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
LED3_ON;//点亮LED3
LED2_OFF;//熄灭LED2
printf("AT+MQTTCLIENTID=0,\"ivs8zZPrvfk.Air-quality-detection-system|securemode=2\\,signmethod=hmacsha256\\,timestamp=1686987060303|\"\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTCONN=0,\"iot-06z009xfy86rf3c.mqtt.iothub.aliyuncs.com\",%d,%d\r\n",1883,1);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
LED1_ON;//点亮LED1
LED3_OFF;//熄灭LED3
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
LED1_OFF;//熄灭LED1
}
结果显示:
3.TFT显示
使用中景园电子SPI例程移植。
引脚连接如下:
#define LCD_SCLK_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_10, BSP_IO_LEVEL_LOW);//SCL=SCLK
#define LCD_SCLK_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_10, BSP_IO_LEVEL_HIGH);
#define LCD_MOSI_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_03, BSP_IO_LEVEL_LOW);//SDA=MOSI
#define LCD_MOSI_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_03, BSP_IO_LEVEL_HIGH);
#define LCD_RES_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_02, BSP_IO_LEVEL_LOW);//RES
#define LCD_RES_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_02, BSP_IO_LEVEL_HIGH);
#define LCD_DC_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_01, BSP_IO_LEVEL_LOW);//DC
#define LCD_DC_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_01, BSP_IO_LEVEL_HIGH);
#define LCD_CS_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_04, BSP_IO_LEVEL_LOW);//CS
#define LCD_CS_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_04, BSP_IO_LEVEL_HIGH);
#define LCD_BLK_Clr() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_08_PIN_01, BSP_IO_LEVEL_LOW);//BLK
#define LCD_BLK_Set() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_08_PIN_01, BSP_IO_LEVEL_HIGH);
具体函数功能如下:
void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color);//指定区域填充颜色
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color);//在指定位置画一个点
void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color);//在指定位置画一条线
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color);//在指定位置画一个矩形
void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color);//在指定位置画一个圆
void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示一个字符
void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示字符串
uint32_t mypow(uint8_t m,uint8_t n);//求幂
void LCD_ShowIntNum(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey);//显示整数变量
void LCD_ShowFloatNum1(uint16_t x,uint16_t y,float num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey);//显示两位小数变量
void LCD_ShowChinese(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示汉字串
void LCD_ShowChinese12x12(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示单个12x12汉字
void LCD_ShowChinese16x16(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示单个16x16汉字
void LCD_ShowChinese24x24(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示单个24x24汉字
void LCD_ShowChinese32x32(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode);//显示单个32x32汉字
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[]);//显示图片
显示结果:
具体代码参考附件
m702.zip
(3.43 MB, 下载次数: 61)
五、实物展示和总结
实物展示:
视频演示:https://www.bilibili.com/video/BV1tW4y1Z7Tz/
总结:
首先非常感谢野火举办的瑞萨RA MCU创意氛围赛,能让我入围获得这次参赛的机会。本次创意氛围赛学习到了很多东西,对云平台的连接有了更深入的了解,同时对RA6M5单片机的内核以及控制有了充足的认知,RA6M5上手快速,对新手很友好,可以用来开发强大功能的设计作品。野火官方提供的手册例程使用起来也很方便,能够快速上手,便于开发使用。在开发过程,遇到了很多问题,大多在网上搜索答案,从而提高自己的解决问题的能力。
|