一、项目概述
现代社会,由于长期在室内活动,人们越来越关注室内空气质量。衡量室内空气质量的主要指标有:二氧化碳浓度、TVOC(总挥发性有机物)浓度、温度、湿度。研究表明:当室内CO2浓度超过1000 ppm时,人体就会出现困倦、呼吸急促、注意力缺乏等症状,当浓度逐渐升高未及时处理,还会造成脑损伤、昏倒甚至丧生。当TVOC浓度为3.0-25 mg/m3时,会产生刺激和不适,与其他因素联合作用时,可能出现头痛;当TVOC浓度大于25 mg/m3时,除头痛外,可能出现其他的神经毒性作用。温度和湿度则是最基本的环境指标,过高或过低的温湿度都会造成然提感到不适。
通风换气是改善空气质量的最简单有效的办法之一,TVOC、CO2、温读和湿度等环境监测数据可用于配置空气净化系统或智能管理通风系统运行模式,从而节省能耗,达到节能减排的目的,助力双碳目标实现。本文基于CH32V307开发板采集TVOC、CO2、温读和湿度四项环境数据,通过WIFI无线网络接入腾讯云物联网平台IoT Explorer,实现了在腾讯连连小程序上能够实时监测室内空气质量的应用。
二、系统结构
系统采用CH32V307作为控制核心,esp8266无线wifi模块用于和腾讯云物联网平台通信,SGP30模块用于采集TVOC、CO2浓度数据、SHT40模块用于采集温湿度数据,led和按键用于人机交互,用户可通过微信小程序实时查看监测数据。系统结构如图所示:

三、硬件介绍
3.1  CH32V307开发板
CH32V307是沁恒微电子基于32位RISC-V设计的高性能、低功耗互联型微控制器,产品特点:
青稞V4F处理器,最高144MHz系统主频
支持单周期乘法和硬件除法,支持硬件浮点运算(FPU)
64KB SRAM,256KB Flash
供电电压:2.5/3.3V,GPIO单元独立供电
多种低功耗模式:睡眠、停止、待机
上/下电复位、可编程电压检测器
2组18路通用DMA
4组运放比较器
1个随机数发生器TRNG
2组12位DAC转换
2单元16通道12位ADC转换,16路触摸按键TouchKey
10组定时器
USB2.0全速OTG接口
USB2.0高速主机/设备接口(480Mbps 内置PHY)
3个USART接口和5个UART接口
2个CAN接口(2.0B主动)
SDIO接口、FSMC接口、DVP数字图像接口
2组IIC接口、3组SPI接口、2组IIS接口
千兆以太网控制器ETH(内置10M PHY)
80个I/O口,可以映射到16外部中断
CRC计算单元,96位芯片唯一ID
串行2线调试接口
本次项目采用沁恒微电子官方推出的开发板,如下图所示:

3.2 SGP30传感器
SGP30是Sensirion推出的一款I2C接口低功耗、高精度多气体传感器(VOC和CO₂eq),主要参数规格如下:

本次项目采用模组如下图所示,集成了电源管理和电平转换电路:

3.3 SHT40传感器
SHT40是Sensirion推出的一款I2C接口低功耗、高精度数字温湿度传感器,主要参数规格如下:

本次项目采用模组,集成电源和电平转换:

3.4 ESP8266 WIFI
esp8266是乐鑫推出的面向物联网应用的高性价比、高度集成的 Wi-Fi MCU,本次使用模组,引出了通信串口,如图所示:

3.5 系统硬件连接
ESP8266模块连接到开发板串口2(管脚PA2、PA3),SGP30连接到开发板PA4、PA5,SHT40连接到开发板PB10、PB11,如下图所示:

四、项目亮点
支持腾讯连连小程序查看监测数据(CO2浓度、TVOC浓度、温度和湿度);
支持腾讯云IoT Explorer平台实时查看上报数据信息(CO2浓度、TVOC浓度、温度和湿度);
支持腾讯连连微信公众号信息推送(CO2浓度、TVOC浓度、温度和湿度超标告警);
采用腾讯云可视化编辑器自定义腾讯连连小程序界面;

小程序界面展示如下图所示:

五、系统实现
系统实现分为3个部分,一是腾讯云平台配置,二是ESP8266腾讯云固件烧录,三是MCU端程序设计。
5.1 腾讯云平台配置
首先需要在腾讯物联网开发平台创建项目:

这里建立一个名为环境监测的项目:

然后在该项目下面点击新建产品按钮,新建一个产品:

一个项目下面可以新建多个产品,这里建立名为室内二氧化碳监测的产品,设备类型为:设备,因为项目使用的是esp8266 wifi模块,因此通信方式选择:Wi-Fi,认证方式选择:秘钥认证,数据协议选择:物模型

建立好产品后,会看到产品的基本信息:

然后根据本项目需要实现的功能进行功能定义,腾讯云平台采用了物模型协议将现实物理世界中的设备功能进行数字化定义,便于应用更便利的管理设备。
在产品定义物模型后,设备可以根据物模型中的定义上报属性、事件,并可对设备下发控制指令,物模型协议主要包括2部分:
设备属性上报:设备端将定义的属性根据设备端的业务逻辑向云端上报。
设备远程控制:从云端向设备端下发控制指令,即从云端设置设备的可写属性。
新建自定义功能:

功能类型:属性
功能名称:二氧化碳
标识符:co2
数据类型:整型
读写类型:只读(读写表示该属性即可从设备端上报到云端也可从云端发起控制,只读表示该属性只从设备向云端上报)
数据范围等参数根据前文SGP30传感器芯片参数填写即可:

同样的方式,再新建TVOC、温度、湿度等其它自定义功能:


最后,建立好的自定义功能如下所示:

查看物模型json格式数据如下:

建立好产品后,在进行小程序界面和MCU程序开发前,可以使用虚拟在线调试测试设计的正确性:

然后配置小程序界面,在交互设计选项卡选择面板配置:

小程序界面支持3种配置方案,这里使用傻瓜化的可视化面板:

可以通过简单的拖、拽控件、关联物模型数据等方式设计自定义的小程序界面,十分方便小白使用。以CO2数据显示为例,新增一个信息展示控件,然后关联物模型co2:

同样的方式设计其它控件:

除了数据展示功能外,还能配置告警消息推送功能:

通过拖曳控件的方式完成数据流配置:

设定数据过滤规则和阈值:

设定报警推送消息内容:

定义的报警信息如下:

5.2 ESP8266腾讯云固件烧录
esp8266模块烧写腾讯云定制固件后,就能连接到腾讯云平台,实现与腾讯云平台的数据交互,能够实现WIFI账号密码配置、MQTT连接、订阅、发布等功能。
乐鑫官网提供esp8266腾讯云AT固件:
https://docs.espressif.com/projects/esp-at/zh_CN/release-v2.2.0.0_esp8266/Customized_AT_Commands_and_Firmware/Tencent_Cloud_IoT_AT/index.html
注意烧录2.2.0.0版本,实测2.3版本不能顺利连接腾讯云。
使用乐鑫提供的esptool工具烧录即可:

5.3 MCU端程序设计
MCU端软件基于腾讯物联网终端操作系统TencentOS tiny构建,TencentOS tiny提供了ch32v307的板级支持包和丰富的示例程序,MCU端软件实现传感器数据采集、无线数据接入腾讯云IoT Explorer,从而设备联网控制与数据交互功能,结构如下图所示:

设备端主要完成ch32v307的外设初始化、传感器初始化、wifi初始化、协议栈初始化、传感器数据采集、mqtt协议数据发送等功能。基于TencentOS-Tiny物联网操作系统开发,设计了3个线程,定时采集传感器数据,控制线程,mqtt发送线程将数据通过腾讯云mqtt协议发送到云平台。
软件功能简要流程如图所示:

开发板提供了常用外设的驱动程序,与云平台的交互基于例子mqtt_iot_explorer.c进行开发。主函数main创建三个线程来进行不同功能的处理,线程间采用TencentOS-tiny提供的消息队列进行通知和数据交换,实现CPU资源高效利用。线程间传递的消息队列中的数据设计如下:

typedef struct{int tvoc;//tvoc浓度int co2;//co2浓度float tem;//温度float hum;//湿度bool fan;//风扇启用标志bool sleep;//睡眠模式启用标志}msg_t;
main.c内容如下,主要完成初始化内核、创建消息队列、创建线程、启动内核功能,需要注意的是,由于使用了printf打印浮点数,需要使用__aligned(8)(8字节对齐),否则将出现异常:
#include "debug.h"#include "tos_k.h"#define MQTT_TASK_STK_SIZE          2048k_task_t mqtt_task;__aligned(8) uint8_t mqtt_task_stk[MQTT_TASK_STK_SIZE];#define CONTROL_TASK_STK_SIZE       4096k_task_t control_task;__aligned(8) uint8_t control_task_stk[CONTROL_TASK_STK_SIZE];#define DATA_COLLECT_TASK_STK_SIZE       4096k_task_t data_collect_task;__aligned(8) uint8_t data_collect_task_stk[DATA_COLLECT_TASK_STK_SIZE];extern void mqtt_entry(void *arg);extern void control_entry(void *arg);extern void data_collect_entry(void *arg);k_msg_q_t msg_q;uint8_t DataMsgPool[100];int main(void){Delay_Init();USART_Printf_Init(115200);printf("SystemClk:%d\r\n",SystemCoreClock);printf("Welcome to TencentOS tiny(%s)\r\n", TOS_VERSION);tos_knl_init();tos_msg_q_create(&msg_q, DataMsgPool, 100);tos_task_create(&mqtt_task, "mqtt_task", mqtt_entry, NULL, 4, mqtt_task_stk, MQTT_TASK_STK_SIZE, 0);tos_task_create(&control_task, "control_task", control_entry, NULL, 5, control_task_stk, CONTROL_TASK_STK_SIZE, 0);tos_task_create(&data_collect_task, "data_collect_task", data_collect_entry, NULL, 6, data_collect_task_stk, DATA_COLLECT_TASK_STK_SIZE, 0);tos_knl_start();printf("should not run at here!\r\n");while(1);}
数据采集线程实现对SGP30、SHT40传感器的初始化,定时将采集数据放入消息队列:
void data_collect_entry(void *arg){uint16_t TVOC = 0, CO2 = 0;uint8_t ID[6]={0};while(sgp30_init() < 0){printf(" sgp30 init error\r\n");tos_sleep_ms(1000);}if(sgp30_get_serial_id(ID) < 0){printf(" sgp30 read serial id error\r\n");}else{printf("SGP30 Serial number: ");for(int i = 0; i < 6; i++)  printf("%02X", ID[i]);printf("\r\n");}// SGP30模块开机需要一定时间初始化,在初始化阶段读取的CO2浓度为400ppm,TVOC为0ppd且恒定不变。printf("wait for sgp30 init");fflush (stdout);do{if(sgp30_read(&CO2, &TVOC) < 0){printf("spg30 read error\r\n");}else{printf("-");fflush (stdout);}tos_sleep_ms(500);}while(TVOC == 0 && CO2 == 400);printf("sgp30 init ok\r\n");int16_t error = 0;sensirion_i2c_hal_init();uint32_t serial_number;int32_t temperature;int32_t humidity;error = sht4x_serial_number(&serial_number);if (error){printf("Error executing sht4x_serial_number(): %i\r\n", error);}else{printf("SHT40 Serial number: %u\r\n", serial_number);}msg_t msg={0};while (1){if(sgp30_read(&CO2, &TVOC) < 0){printf(" sgp30 read error\r\n");}else{printf("CO2:%5dppm TVOC:%5dppb\r\n", CO2, TVOC);}error = sht4x_measure_high_precision(&temperature, &humidity);if (error){printf("Error executing sht4x_measure_high_precision(): %i\n",error);}else{msg.tvoc = TVOC;msg.co2 = CO2;msg.tem = temperature / 1000.0f;msg.hum = humidity / 1000.0f;tos_msg_q_post(&msg_q,(void*)&msg);printf("Temperature:%0.2f℃,Humidity:%0.2f %%RH\n",temperature / 1000.0f, humidity / 1000.0f);}tos_sleep_ms(3000);}}

对接云平台,修改mqtt_iot_explorer.c文件开头的三元组信息产品 ID(ProductId)、设备名(DeviceName)、设备密钥(DeviceSecret)其中设备密钥由平台生成:

#define PRODUCT_ID              "test"#define DEVICE_NAME             "test"#define DEVICE_KEY              "test"

然后修改要接入WIFI的名称和密码:

esp8266_tencent_firmware_join_ap("ssid", "passwd");

mqtt线程首先完成esp8266初始化、wifi协议栈初始化、mqtt订阅主题等功能。当接收到消息后,将采集数据依据消息发布使用的物模型Topic打包,然后通过MQTT发送出去。属性上报主题格式如下所示:
$thing/up/property/${deviceID}/${deviceName}
根据腾讯云平台配置的物模型将数据打包为json格式上传,消息体json格式如下:

#define REPORT_DATA_TEMPLATE    "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"00000001\\\"\\,\\\"params\\\":{\\\"tvoc\\\":%d\\,\\\"co2\\\":%d\\,\\\"fan\\\":%d\\,\\\"sleep\\\":%d\\,\\\"temperature\\\":%0.1f\\,\\\"humidity\\\":%0.1f\\}}"

通过snprintf函数将两者连接起来:

    memset(report_topic_name, 0, sizeof(report_topic_name));size = snprintf(report_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/property/%s/%s", product_id, device_name);

将传感器数据格式化输入到payload:

        memset(payload, 0, sizeof(payload));snprintf(payload, sizeof(payload), REPORT_DATA_TEMPLATE, tvoc,co2,0,0,tem,hum);

最后调用

tos_tf_module_mqtt_pub(report_topic_name, QOS0, payload)

函数实现MQTT消息的发布。
推送传感器数据到腾讯云物联网开发平台IoT Explorer的mqtt线程如下:

void mqtt_demo_task(void){int ret = 0;int size = 0;mqtt_state_t state;char *product_id = PRODUCT_ID;char *device_name = DEVICE_NAME;char *key = DEVICE_KEY;device_info_t dev_info;memset(&dev_info, 0, sizeof(device_info_t));/*** Please Choose your AT Port first, default is HAL_UART_2(USART2)*/ret = esp8266_tencent_firmware_sal_init(HAL_UART_PORT_2);if (ret < 0) {printf("esp8266 tencent firmware sal init fail, ret is %d\r\n", ret);}esp8266_tencent_firmware_join_ap("HUAWEI-DQL", "dql8837150");strncpy(dev_info.product_id, product_id, PRODUCT_ID_MAX_SIZE);strncpy(dev_info.device_name, device_name, DEVICE_NAME_MAX_SIZE);strncpy(dev_info.device_serc, key, DEVICE_SERC_MAX_SIZE);tos_tf_module_info_set(&dev_info, TLS_MODE_PSK);mqtt_param_t init_params = DEFAULT_MQTT_PARAMS;if (tos_tf_module_mqtt_conn(init_params) != 0) {printf("module mqtt conn fail\n");} else {printf("module mqtt conn success\n");}if (tos_tf_module_mqtt_state_get(&state) != -1) {printf("MQTT: %s\n", state == MQTT_STATE_CONNECTED ? "CONNECTED" : "DISCONNECTED");}size = snprintf(report_reply_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/down/property/%s/%s", product_id, device_name);if (size < 0 || size > sizeof(report_reply_topic_name) - 1) {printf("sub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(report_reply_topic_name));}if (tos_tf_module_mqtt_sub(report_reply_topic_name, QOS0, default_message_handler) != 0) {printf("module mqtt sub fail\n");} else {printf("module mqtt sub success\n");}memset(report_topic_name, 0, sizeof(report_topic_name));size = snprintf(report_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/property/%s/%s", product_id, device_name);if (size < 0 || size > sizeof(report_topic_name) - 1){printf("pub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(report_topic_name));}void *MsgRecv;msg_t msg;int tvoc;int co2;float tem;float hum;while (1){//GPIO_SetBits(GPIOE,GPIO_Pin_5);//tos_sleep_ms(2000);//GPIO_ResetBits(GPIOE,GPIO_Pin_5);tos_msg_q_pend(&msg_q, &MsgRecv, TOS_TIME_FOREVER);memcpy(&msg,MsgRecv,sizeof(msg_t));tos_mutex_pend(&mutex);printf("tvoc:%d co2:%d temp:%d hum:%d\r\n",msg.tvoc,msg.co2,msg.tem,msg.hum);tos_mutex_post(&mutex);/* use AT+PUB AT command */tvoc = msg.tvoc;co2 = msg.co2;tem = msg.tem;hum = msg.hum;memset(payload, 0, sizeof(payload));snprintf(payload, sizeof(payload), REPORT_DATA_TEMPLATE, tvoc,co2,0,0,tem,hum);if (tos_tf_module_mqtt_pub(report_topic_name, QOS0, payload) != 0){printf("module mqtt pub fail\n");break;}else{printf("module mqtt pub success\n");}}}

程序运行正常的情况下,在云平台调试界面就可以看到设备发送的数据:

进入腾讯连连小程序连接设备后也能看到之前设计的小程序界面:

小程序收到超标告警消息:

总结

通过本项目体验了国产MCU、国产RTOS、国产IDE生态,了解了沁恒RISC-V内核微控制器 CH32V307VCT6应用、了解了国产物联网操作系统TencentOS-tiny和国产集成开发工具MounRiver Studio,感受到了国货的崛起。

由于本人能力水平不足,文章写的有误或者不清楚的地方敬请见谅。
---------------------
作者:dql2015
链接:https://bbs.21ic.com/icview-3273948-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

[单片机芯片]基于CH32V307腾讯连连小程序的二氧化碳TVOC环境监测仪相关推荐

  1. 【微信小程序控制硬件15 】 重认识无线物联网的配网协议,了解腾讯物联蓝牙协议LLSync SDK,腾讯连连小程序也可以蓝牙配网了。

    文章目录 一.配网的认识 1.1 各类Wi-Fi配网方式对比 1.2 设备热点配网 1.3 零配配网 1.4 蓝牙辅助配网 1.5 一键配网 1.6 手机热点配网 1.6 摄像头扫码配网 二.LLSy ...

  2. 微信小程序控制硬件第17篇 : 腾讯连连小程序通过LLSync蓝牙协议控制安信可PB-02模组,无需网络实现蓝牙本地通讯。(附带源码)

    文章目录 前言 一.注册腾讯物联开发平台设备 新建项目 新建产品 创建数据模板 选择设备开发方式 交互开发配置 新建设备 二.设备端操作 硬件简介与连接 准备软件环境 工程目录 烧录步骤 三.腾讯连连 ...

  3. 微信推出“腾讯QQ”小程序;马化腾又要发红包;GitLab 12.5 稳定版发布| 极客头条...

    整理 | 屠敏 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注 ...

  4. 基于云开发的微信小程序:个人相册ByUestcXiye

    基于云开发的微信小程序:个人相册ByUestcXiye 作业要求 第一次作业 第二次作业 结课作业 小程序开发入门 开发前的准备 注册微信小程序 新建一个模板小程序 开通云开发服务 第一次作业 参考资 ...

  5. 基于微信药店药品商城小程序系统设计与实现 开题报告

      毕业论文 基于微信药店药品商城小程序 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   名 Xxx ...

  6. 基于安卓android和微信小程序的点餐管理系统毕业设计(源码讲解)

    作者简介:Java.spring.安卓Android.ssm框架.前端.后端开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.技术分享 怎么做基于安卓android和微信 ...

  7. 基于低功耗蓝牙和微信小程序的门禁系统(FPGA课设设计)

    基于低功耗蓝牙和微信小程序的门禁系统(FPGA课设设计) 文章目录 基于低功耗蓝牙和微信小程序的门禁系统(FPGA课设设计) 一.低功耗蓝牙(BLE)的配置和与FPGA通信代码 1.1 低功耗蓝牙的介 ...

  8. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】分享

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

  9. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

最新文章

  1. 捷报!又一名HIV感染者被治愈,干细胞移植再次立功
  2. python3 判断list是否包含另一个list
  3. php+微信开发+解绑,微信开发之解绑设备通知的方法
  4. 剑指offer打卡计划、建议(持续进行)
  5. SQL 测验-自测结果
  6. SharePoint中CAML使用的一些总结
  7. centos php open_basedir,CentOS 5服务器安全基本设置
  8. 计算机组成原理课件ppt6,唐朔飞 计算机组成原理课件6.ppt
  9. java面试准备题目
  10. 一起玩转CAN卡“第五通道”吧!
  11. 工作流:一文让你学会使用flowable工作流
  12. 1.3 n-gram平滑算法:Good-Turning、拉普拉斯平滑
  13. android 焦点移动,Android TV 焦点上下左右移动
  14. Android 第三方 ROM
  15. 新换的手机号码被人注册了微信怎么办?
  16. 输入五个国家的名称按字母顺序排列输出
  17. 项目管理~基于禅道敏捷开发的详细流程图,关键节点及描述,诠释敏捷开发实施细节
  18. Python+Vue计算机毕业设计报刊征订管理系统uu609(源码+程序+LW+部署)
  19. MySQL索引原理和引擎
  20. 程序员需要具备的五个基本条件

热门文章

  1. EasyDSS RTMP流媒体解决方案之Windows服务安装方案
  2. Python求水仙花数(包含简单运算符使用方法)初级学习
  3. 索引表和ES的一点点思考
  4. 客户认可|数澜科技获评旭辉集团“创新供应商”称号
  5. python怎么打开ipynb文件_怎么在Jupyter里打开ipynb文件
  6. c语言二进制数怎么表示_C语言的二进制数、位和字节
  7. 个人免签即时到账收款接口 bufpay.com 支持多账号收款
  8. 迈锐宝1.5t噪音测试软件,迈锐宝1.5T动力够用不?车友作测贡献新车极速案例
  9. C++静态成员变量在内存中的存储方式
  10. PHP json_decode