自改革开放以来,我国经济发展越来越快,随着居民收入水平的提高及安全意识的增强,人们开始注重生活质量。但是据调查发现,现在市面上的空气检测仪要么是功能单一,检测结果不精准,要么不能和空气净化器/空调等其他设备智能联动,要么不能手机APP远程查看,要么就是价格太高无法接受。
怎么办?怎么办?怎么办?
涂鸦有方案!!!
为了解决上述这些痛点,我们设计了一款新的个人健康空气管理智能硬件方案,环境安全卫士。
该方案功能强大,可以检测当前环境中甲醛,PM2.5 的浓度,并且将这两个数值在涂鸦 App 中实时显示。还可以实时监控烟雾,燃气,火焰这三种物质的浓度,当检测对象的浓度超过一定值时,会触发报警,联动其他智能设备,保障用户自身和财产安全。
由涂鸦智能开发的一款低功耗嵌入式Wi-Fi+BLE 双协议模组。它由一个高集成度的无线射频芯片BK7231T和少量外围器件构成,内置了Wi-Fi网络协议栈和丰富的库函数。查看详情
一款是数字控制的模拟开关,它的导通电阻只有24欧姆,漏电流只有1nA。
模组利用电化学原理,对空气中存在的CH2O进行探测,具有良好的选择性,稳定性。
整合了红外 PM2.5 检测原理和较为成熟的 VOC 检测技术,能够同时检测环境中 PM2.5 和 VOC。
可用于家庭和工厂的气体泄漏监测装置,适宜于液化气、苯、烷、酒精、氢气、烟雾等的探测。
探测火源或波长在 700 ~ 1000 nm 范围内的热源。
当异常发生时,自动断开 220V 市电,降低损失。
主控单元选择 WB3S 模组。WB3S 模组是一款低功耗嵌入式 Wi-Fi+BLE 双协议模组。它由一个高集成度的无线射频芯片 BK7231T 和少量外围器件构成,内置了 Wi-Fi 网络协议栈和丰富的库函数。
由于模组的 ADC 口资源不足,我们还需对其进行适当修改,拓展 ADC 接口。在电路中增加一款四通道模拟多路复用/解复用器芯片 RS2255,这是一款是数字控制的模拟开关,导通电阻只有 24 Ω,漏电流只有 1nA。
本方案使用了较多传感器,为了减少走线,使整体更加简洁美观,主控板需要引出各种传感器接口,而且各个模块与主控板的通信接口电平存在不匹配的现象,模块供电电压也存在差异。为了解决上述问题:
原理图设计如下(点击下载原理图文件):
PCB 设计如下(点击下载 PCB 文件):
本方案采用通用型、小型化的 ZE08-CH2O 型电化学甲醛模组。
模组利用电化学原理,对空气中存在的CH2O进行探测,具有良好的选择性,稳定性。内置温度传感器,可进行温度补偿。同时具有数字输出与模拟电压输出,方便使用。
电气参数:
产品型号 | ZE08-CH2O |
---|---|
检测气体 | 甲醛 |
干扰气体 | 酒精,一氧化碳等气体 |
输出数据 | DAC(0.4~2V 电压信号对应浓度:0~满量程) |
UART输出(3V TTL电平) | |
工作电压 | 3.7V~5.5V |
预热时间 | ≤3 分钟 |
响应时间 | ≤60秒 |
恢复时间 | ≤60秒 |
量程 | 0~5 ppm |
分辨率 | ≤0.01ppm |
工作温度 | -20℃~50℃ |
工作湿度 | 15%RH-90%RH(无凝结) |
存储温度 | 0~25℃ |
使用寿命 | 5年(空气中 18℃~25℃) |
管脚定义:
管脚名称 | 管脚说明 |
---|---|
Pin1 | 预留 |
Pin2 | DAC (0.4~2V,对应0-满量程 |
Pin3 | GND |
Pin4 | Vin(电压输入3.7V~5.5V) |
Pin5 | UART(RXD) 0~3.3V数据输入 |
Pin6 | UART(TXD) 0~3.3V数据输出 |
Pin7 | 预留 |
串口通讯协议:
Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 | Byte8 |
---|---|---|---|---|---|---|---|---|
起始位 | 气体名称 | 单位 | 小数位数 | 气体浓度 | 气体浓度 | 满量程 | 满量程 | 校验值 |
(CH2O) | (ppb) | 无 | 高位 | 低位 | 高位 | 低位 | ||
0xFF | 0x17 | 0x04 | 0x00 | 0x00 | 0x25 | 0x13 | 0x88 | 0x25 |
说明:
气体浓度值(PPB)=气体浓度高位*256+气体浓度低位
,当转换为PPM时:PPM=PPB/1000
、1PPM×1.25=1.25mg/m3
。
其中,Byte8校验值=(取反(Byte1+Byte2+……+Byte7))+1
。
PM 2.5 检测采用 ZPH02 空污粉尘传感器。它整合了红外 PM2.5 检测原理和较为成熟的 VOC 检测技术,能够同时检测环境中 PM2.5 和 VOC。
该传感器中 PM2.5 检测采用粒子计数原理,可灵敏检测直径 1μm 以上灰尘颗粒物,VOC 传感器对有机挥发气体具有极高的灵敏度。
电气参数:
产品型号 | ZPH02 | |
---|---|---|
工作电压范围 | 5±0.2 V(DC) | |
输出方式 | UART(9600,1Hz±1%) | |
PWM (周期:1Hz±1%) | ||
输出信号电压 | 5±0.2 V | |
检测能力 | VOC检测气体总类 | CH2O、C6H6、CO、H2、NH3、C2H5OH、香烟烟雾、香精等 |
检出粉尘最小粒子 | 1 μm | |
预热时间 | ≤5min | |
工作电流 | ≤150mA | |
湿度范围 储存环境 | ≤90%RH | |
工作环境 | ≤90%RH | |
温度范围 储存环境 | -20℃~50℃ | |
工作环境 | 0℃~50℃ | |
外形尺寸 | 59.5×44.5×17mm | |
(L×W×H) | ||
物理接口 | EH2.54-5P端子插座 |
管脚定义如下表所示:
PIN1 | 控制脚(MOD) |
---|---|
PIN2 | 输出脚OUT2/RXD |
PIN3 | 电源正(VCC) |
PIN4 | 输出脚 OUT1/TXD |
PIN5 | 电源地(GND) |
串口通讯协议:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
起始位 | 检测类型 | 单位 | 低脉冲率 | 低脉冲率 | 预留 | VOC等级 | 预留 | 校验值 |
名称编码 | (低脉冲率) | 整数部分 | 小数部分 | |||||
0XFF | 0X18 | 0X00 | 0x00-0x63 | 0x00-0x63 | 0x00 | 0x01-0x04 | 0x00 | 0x00-0xFF |
计算 PM 2.5 值的示例
其中,Byte8校验值=(取反(Byte1+Byte2+……+Byte7))+ 1
。
烟雾检测采用MQ-2烟雾传感器,该传感器可用于家庭和工厂的气体泄漏监测装置,适宜于液化气、苯、烷、酒精、氢气、烟雾等的探测。
电气特性:
产品型号 | MQ-2 | ||
---|---|---|---|
产品类型 | 半导体气敏元件 | ||
标准封装 | 胶木,金属罩 | ||
检测气体 | 可燃气体、烟雾 | ||
检测浓度 | 300~10000ppm(可燃气体) | ||
标准电路条件 | 回路电压 | Vc | ≤24V DC |
加热电压 | VH | 5.0V±0.1V AC or DC | |
负载电阻 | RL | 可调 | |
标准测试条件下气敏元件特性 | 加热电阻 | RH | 29Ω±3Ω(室温) |
加热功耗 | PH | ≤950mW | |
灵敏度 | S | Rs(in air)/Rs(2000ppm C3H8)≥5 | |
输出电压 | Vs | 2.5V~4.0V(in 2000ppmC3H8) | |
浓度斜率 | α | ≤0.6(R3000ppm/R1000ppm C3H8) | |
标准测试条件 | 温度、湿度 | 20℃±2℃;55%±5%RH | |
标准测试电路 | Vc:5.0V±0.1V; | ||
VH:5.0V±0.1V | |||
预热时间 | 不少于48小时 | ||
氧气含量 | 21%(不低于18%,(氧气浓度会影 | ||
响传感器的初始值、灵敏度及重 | |||
复性,在低氧气浓度下使用时请 | |||
咨询使用) | |||
寿命 | 10年 |
传感器灵敏度:
为了减少开发周期,本次采购了MQ-2烟雾传感器模组:
模组原理图:
如图可知,可以通过检测 AO 端的电平电压,来判断烟雾大小。电压越高,烟雾浓度越高。
燃气检测采用MQ-4气体传感器。该传感器对甲烷,天燃气有很高的灵敏度,广泛适用于家用气体泄漏报警器、工业可燃气体报警器、便携式气体检测器。
电气特性:
产品型号 | MQ-4 | ||
---|---|---|---|
产品类型 | 半导体气敏元件 | ||
标准封装 | 胶木,金属罩 | ||
检测气体 | 甲烷 | ||
检测浓度 | 300~10000ppm(甲烷) | ||
标准电路条件 | 回路电压 | Vc | ≤24V DC |
加热电压 | VH | 5.0V±0.1V AC or DC | |
负载电阻 | RL | 可调 | |
标准测试条件下气敏元件特性 | 加热电阻 | RH | 29Ω±3Ω(室温) |
加热功耗 | PH | ≤950mW | |
灵敏度 | S | Rs(in air)/Rs(in 5000ppm甲烷)≥5 | |
输出电压 | Vs | 2.5V~4.0V (in 5000ppm CH4) | |
浓度斜率 | α | ≤0.6(R5000ppm/R1000ppm CH4) | |
标准测试条件 | 温度、湿度 | 20℃±2℃;55%±5%RH | |
标准测试电路 | Vc:5.0V±0.1V; | ||
VH:5.0V±0.1V | |||
预热时间 | 不少于48小时 | ||
氧气含量 | 21%(不低于18%,(氧气浓度会影 | ||
响传感器的初始值、灵敏度及重 | |||
复性,在低氧气浓度下使用时请 | |||
咨询使用) | |||
寿命 | 10年 |
传感器灵敏度:
为了减少开发周期,本次采购了MQ-4气体传感器模组。该模组的原理图和MQ-2烟雾传感器模组相同,可以通过检测AO端的电平电压,来判断燃气浓度(电压越高,燃气浓度越高)。
火焰检测采用红外接收管。该管可以探测火源或波长在 700 ~ 1000 nm 范围内的热源。
为了减少开发周期,本次采购了市面上常见的火焰传感器模组:
原理图如下:
可以通过检测AO端的电平电压,来判断火势的强弱(电压越低,火势越强)。
为了增加产品的可使用性,我们选择了一款带台灯的插座,对其进行改造。
将环境安全卫士固定在台灯支架上,在检测房间空气质量的同时,还可以检测插座上的设备是否出现火灾等危险情况。例如,对手机等锂电池设备供电引发的安全问题进行提前通知。
当然,您也可以根据自身需求,将本环境安全卫士和其他设备进行关联。
台灯内可增加一路继电器控制,当异常发生时,自动断开 220V 市电,降低损失。
由于之前已经设计了转接板,因此该步骤比较简单,只需要根据结构空间要求,将各个传感器模组安插在对应的位置上,并完成焊接固定。
为了使走线更加精简,可直接将甲醛传感器的VCC,GND,TXD 焊到 P5 的VCC、GND、RXD,其他传感器同理。
将台灯的灯罩拆开,可以看到里面的 LED 灯板和两根正负电源线,用电烙铁等工具将 LED 灯板拆除。
将台灯底座的四个海绵垫拆除,卸下螺丝,可以拆除底座。
将主控板固定在灯罩区域适当位置,将两根正负电源线分别焊到主控板上的 P6 端。这样,当按下插座上的 台灯 按钮时,插座就可以给主控板提供 5V 电压,注意区分正负极。
修改台灯电路,在火线电路中串入一个继电器,并引出继电器控制线。
将上一步引出的控制线焊于主控板 P2 的 Sig 处,并安装灯罩,底座。
当然,您也可以激发自己创意,给它穿上不同外衣。
这样,整机搭建基本完成。另外,也可以根据自己的创意,设计出其他外观,如下所示
外形结构文件下载链接
进入 涂鸦 IoT 平台,点击创建产品。
根据自身需要选择功能。
若缺少自身需要的功能,可自定义功能,根据实际需求进行配置。
选择 App 面板,开始调试时可选择调试面板,后面可根据自身需要进行自由配置面板。
选择开发方式,下载 SDK 和相关文件。
我们选择 SDK 开发,使用 WB3S 模组进行开发。
本 Demo 代码 是基于 1.0.2 协议版本的 SDK 进行开发的。如果您第一次接触 SoC 开发,可以在 涂鸦 GitHub Repo 上拉取代码进行学习和开发。该代码中的 apps/template-demo
相对简单,可在其基础上进行开发。
本 Demo 主要是通过串口、ADC、检测引脚高低电平三种方式获取传感器信息的。下面将以这三种方式进行简单的介绍。
通过阅读甲醛传感器的资料我们可以发现,传感器数据上传格式和计算方法如下:
/***********************************************************
* Function: get_ch2o_sensor_value
* Input: none
* Output: none
* Return: none
* Notice: 得到并上传甲醛的数据
***********************************************************/
static VOID get_ch2o_sensor_value(VOID)
{
UINT_T buff_ret, find_head_index = 0;
// 甲醛数据高位,低位
UCHAR_T ch2o_data_high, ch2o_data_low;
// 校验和
UCHAR_T check_sums = 0x00;
// 串口数据缓存区
UCHAR_T ch2o_receive_buffer[CH2O_BUFFER_SIZE];
// 指向甲醛数据头部
UCHAR_T *p_ch2o_value = NULL;
memset(ch2o_receive_buffer, 0, sizeof(ch2o_receive_buffer));
// 读取串口数据
bk_uart_recv(CH2O_SENSOR_UART, ch2o_receive_buffer, CH2O_BUFFER_SIZE, 0xFFFF);
// for (find_head_index = 0; find_head_index<CH2O_BUFFER_SIZE; find_head_index++) {
// PR_NOTICE("ch2o_receive_buffer[%d] = %02x", find_head_index, ch2o_receive_buffer[find_head_index]);
// }
//寻找 ch2o 传感器发送过来的头部
for (find_head_index = 0; find_head_index<CH2O_BUFFER_SIZE; find_head_index++) {
if (ch2o_receive_buffer[find_head_index] == 0xff && \
ch2o_receive_buffer[find_head_index+1] == 0x17 && \
ch2o_receive_buffer[find_head_index+2] == 0x04){
//PR_NOTICE("find head is %d", find_head_index);
break;
}
}
//本次采集数据不完整
if (find_head_index > 11) {
PR_ERR("ch2o get uart data no complete!");
return;
}
//将指针指向 ch2o 数据中的头部
p_ch2o_value = ch2o_receive_buffer + find_head_index;
//检验和,确认读取的数据的准确性
check_sums = ch2o_check_sum(p_ch2o_value, 9);
if (check_sums != *(p_ch2o_value + 8)) {
PR_ERR("ch2o check_sums error");
return;
}
ch2o_data_high = *(p_ch2o_value+4);
ch2o_data_low = *(p_ch2o_value+5);
gs_air_box.ch2o_value = ch2o_data_high * 256 + ch2o_data_low;
//PR_NOTICE("ch2o value is : %d .", gs_air_box.ch2o_value);
//上传 ch2o 数据到涂鸦云
updata_dp_single(gs_air_box.dp_ch2o_value, PROP_VALUE, gs_air_box.ch2o_value);
return;
}
校验和的计算方式为:
校验和 = (取反(Byte1+Byte2+......+Byte7))+1
/***********************************************************
* Function: ch2o_check_sum
* Input: none
* Output: none
* Return: none
* Notice: 甲醛数据校验和
***********************************************************/
static UCHAR_T ch2o_check_sum(UCHAR_T *data, UCHAR_T len)
{
UCHAR_T i, tempq = 0;
data += 1; //指向data[1]
for(i=0; i<(len-2); i++)
{
tempq += *data;
data++;
}
tempq = (~tempq) + 1;
return (tempq);
}
PM 2.5 数据的获取方法和甲醛数据很相似,这里不再过多介绍。
由于在 WB3S 模组上只要一个ADC,所以我们使用 RS2255 芯片进行复用,引脚选择如下:
A(PWM0/GPIOA_6) | B(PWM1/GPIOA_7) | ON CHANNEL(S) |
---|---|---|
0 | 0 | A0 |
0 | 1 | A1 |
1 | 0 | A2 |
1 | 1 | A3 |
初始化 ADC:
/* ADC */
static tuya_adc_dev_t tuya_adc;
static VOID adc_init(VOID)
{
tuya_adc.priv.pData = Malloc(ADC_DATA_LEN * sizeof(USHORT_T)); //这里一直使用tuya_adc,所有后面就没有释放该空间
memset(tuya_adc.priv.pData, 0, ADC_DATA_LEN*sizeof(USHORT_T));
tuya_adc.priv.data_buff_size = ADC_DATA_LEN; //设置数据缓存个数
}
采集 ADC:
/***********************************************************
* Function: get_adc_value
* Input: none
* Output: adc_value : 采集到的 adc 值
* Return: none
* Notice: 得到 adc 采集的电压值
***********************************************************/
VOID get_adc_value(OUT USHORT_T* adc_value)
{
INT_T ret;
if (adc_value == NULL) {
PR_ERR("pm25_adc_value is NULL");
return;
}
memset(tuya_adc.priv.pData, 0, ADC_DATA_LEN*sizeof(USHORT_T));
ret = tuya_hal_adc_init(&tuya_adc);
if (ret != OPRT_OK) {
PR_ERR("ADC init error : %d ", ret);
return;
}
ret = ret = tuya_hal_adc_value_get(ADC_DATA_LEN, adc_value);
if (ret != OPRT_OK) {
PR_ERR("ADC get value error : %d ", ret);
}
tuya_hal_adc_finalize(&tuya_adc);
return;
}
获取烟雾传感器数据:
/* 烟雾传感器 */
/***********************************************************
* Function: get_smoke_sensor_value
* Input: none
* Output: none
* Return: none
* Notice: 得到并上传烟雾的数据,A1
***********************************************************/
static VOID get_smoke_sensor_value(VOID)
{
USHORT_T smoke_adc_value;
FLOAT_T smoke_volt;
//复用 adc 到 A1
tuya_gpio_write(RS2255_A, FALSE);
tuya_gpio_write(RS2255_B, TRUE);
tuya_hal_system_sleep(500);
//得到烟雾传感器 ad 值
get_adc_value(&smoke_adc_value);
//PR_NOTICE("smoke_adc_value : %d ", smoke_adc_value);
//计算实际电压值
smoke_volt = (smoke_adc_value / 4095.0) * 2.4 * 2;
//PR_NOTICE("smoke_volt : %lf ", smoke_volt);
//判断是否到报警门限值
if (smoke_volt >= SMOKE_ALARM_LIM) {
gs_air_box.smoke_state = ALARM;
} else {
gs_air_box.smoke_state = NORMAL;
}
//上传数据
updata_dp_single(gs_air_box.dp_smoke_state, PROP_ENUM, gs_air_box.smoke_state);
//PR_NOTICE("get smoke value, updata...");
return;
}
燃气传感器和烟雾相似,这里就不再过多介绍。
火焰传感器检测到火焰后断开 220v 电源,重启后 220v 通电,防止发生意外情况。
/***********************************************************
* Function: get_smoke_sensor_value
* Input: none
* Output: none
* Return: none
* Notice: 得到并上传火焰的数据
***********************************************************/
static VOID get_flame_sensor_value(VOID)
{
if (FALSE == tuya_gpio_read(FLAME_SENSOR_PIN)) {
gs_air_box.flame_state = ALARM;
/* 检测到火焰,拉低220V控制引脚,断电 */
tuya_gpio_write(POWER_OFF_220V_PIN, FALSE);
} else {
gs_air_box.flame_state = NORMAL;
}
updata_dp_single(gs_air_box.dp_flame_state, PROP_ENUM, gs_air_box.flame_state);
return;
}
启动设备时,先初始化环境安全卫士相关的外设和引脚,创建信号量、传感器预热、预热完成后释放信号量、开始采集。
/***********************************************************
* Function: air_box_device_init
* Input: none
* Output: none
* Return: none
* Notice: 环境安全卫士设备初始化
***********************************************************/
VOID air_box_device_init(VOID)
{
INT_T opRet = OPRT_OK;
/* 火焰传感器相关外设初始化 */
tuya_gpio_inout_set(FLAME_SENSOR_PIN, TRUE);
tuya_gpio_inout_set(POWER_OFF_220V_PIN, FALSE);
/* 启动时,拉高220V控制引脚,通电 */
tuya_gpio_write(POWER_OFF_220V_PIN, TRUE);
/* ADC 复用,相关引脚初始化 */
tuya_gpio_inout_set(RS2255_A, FALSE);
tuya_gpio_inout_set(RS2255_B, FALSE);
adc_init();
/* 甲醛传感器使用 uart2 接收数据,在函数 app_init() 里面已经修改完成波特率 */
/* pm2.5 传感器 串口 初始化 */
ty_uart_init(PM25_SENSOR_UART, TYU_RATE_9600, TYWL_8B, TYP_NONE, TYS_STOPBIT1, (PM25_BUFFER_SIZE * SIZEOF(UCHAR_T)), TRUE);
/* 创建信号量 */
opRet = tuya_hal_semaphore_create_init(&preheat_semaphore, 0, 1);
if (opRet != OPRT_OK) {
PR_ERR("creat preheat semaphore error : %d", opRet);
}
/* 预热 60s 后释放信号量,开始采集传感器数据 */
opSocSWTimerStart(preheat_timer, SENSOR_PREHEAT_TIME, preheat_semaphore_post_task);
xTaskCreate(acquire_data_task, "acquire sensor data", 512, NULL, TRD_PRIO_2, NULL);
}
预热完成释放信号量:
VOID preheat_semaphore_post_task(VOID)
{
//预热完成,释放信号量
tuya_hal_semaphore_post(preheat_semaphore);
//关闭预热软件定时器
opSocSWTimerStop(preheat_timer);
//预热完成,上传预热完成数据到涂鸦云
gs_air_box.preheat_state = false;
updata_dp_single(gs_air_box.dp_preheat, PROP_BOOL, gs_air_box.preheat_state);
}
传感器采集数据轮询任务:
/***********************************************************
* Function: acquire_data_task
* Input: none
* Output: none
* Return: none
* Notice: 获取传感器数据任务
***********************************************************/
VOID acquire_data_task(VOID)
{
//等待预热完成
tuya_hal_semaphore_wait(preheat_semaphore);
while (1) {
get_ch2o_sensor_value();
get_flame_sensor_value();
get_gas_sensor_value();
get_pm25_sensor_value();
get_smoke_sensor_value();
tuya_hal_system_sleep(500);
}
}
烧录授权完成后,设备就可以正常配网了。有关模组烧录授权的详情,请参考 WB 系列模组烧录授权。
连接 Wi-Fi,打开蓝牙,按照配网流程成功配网后,即可使用涂鸦智能 App 控制设备。已经配网成功的设备,可长按按键再次进入配网模式。环境安全卫士在 App 上的显示界面:
当烟雾,燃气或者火焰三者中有一种的浓度大于设定值,则涂鸦智能 App 会显示报警状态,并且断开 220V 电压。环境安全卫士在 App 上的显示界面: