项目介绍:
厨房是家庭中空气污染的高发区域,烹饪过程中产生的油烟、燃气、酒精泄漏以及挥发性有机化合物(VOCs)可能对健康造成威胁,甚至引起火灾。本项目旨在利用 BME688 传感器,实时监测厨房环境中的 VOC 浓度、温度、等参数,并通过物联网,及时提醒用户采取应对措施,保障厨房安全与健康。
硬件介绍:
Unit ENV-Pro 传感器:这是一款高集成度的环境检测单元,内置 BME688 传感器方案,支持测量 VOC 等挥发性有机化合物、二氧化碳当量、室内空气质量 ( IAQ )、温湿度和大气压等多种环境参数。传感器采用 I2C 通信接口 ( 0x77 ),适用于天气站、室内环境监测和空气质量检测等应用场景。
AtomS3 是一款基于 ESP32-S3 主控的高集成度可编程控制器,内部集成了 ESP32-S3 主控,集成 Wi-Fi 功能、8 MB 片上 FLASH、0.85 寸 IPS 屏幕。屏幕下方具有可编程按键功能,内置 5V 转 3.3V 电路、6 轴陀螺仪传感器 MPU6886 。
任务选择:
选择任务为 方向二:安全监测,实现系统安全。通过嗅觉和温度感知厨房里空气成分的变化,实时检测环境安全。
设计思路:
系统初始化后,会有两种状态。
状态一:环境正常。通过AtomS3的屏幕显示当前日期、时间、温度、湿度、空气IAQ值等信息,使用绿色色调。
状态二:当感知到环境温度过高、或者是空气质量IAQ处于不正常状态,则使用黄色或红色色调,显示当前温度和状态:警告或危险。并通过互联网将当前环境信息上传到百度物联网上。这样就可以通过互联网通知到人。防范风险。
下位机使用Vscode+platformIO,使用arduino编程。上位机使用python做了个简单的上位机展示。
任务实现:
查看BME688官方博世的文档,貌似提供了机器学习的能力,但是看文档是针对特定的传感器板子的数据收集、训练,才能获得指定的嗅觉效果。官方提供的传感器板子,使用了多颗BME688传感器,而手头的Unit ENV-Pro 传感器只有一颗BME688芯片,无法使用博世提供的机器学习方案。
Unit ENV-Pro 传感器连接到AtomS3的Grove口(GP1,GP2),使用I2C通信。驱动代码使用官网提供的驱动包,来进行读取。
Bsec2 envSensor;
void checkBsecStatus(Bsec2 bsec)
{
if (bsec.status < BSEC_OK)
{
Serial.println("BSEC error code : " + String(bsec.status));
}
else if (bsec.status > BSEC_OK)
{
Serial.println("BSEC warning code : " + String(bsec.status));
}
if (bsec.sensor.status < BME68X_OK)
{
Serial.println("BME68X error code : " + String(bsec.sensor.status));
}
else if (bsec.sensor.status > BME68X_OK)
{
Serial.println("BME68X warning code : " + String(bsec.sensor.status));
}
}
void newDataCallback(const bme68xData data, const bsecOutputs outputs,
Bsec2 bsec)
{
airQualityNode msgnode;
if (!outputs.nOutputs)
{
return;
}
// Serial.println();
// Serial.print(String((int)(outputs.output[0].time_stamp / INT64_C(1000000))));
for (uint8_t i = 0; i < outputs.nOutputs; i++)
{
const bsecData output = outputs.output[i];
switch (output.sensor_id)
{
case BSEC_OUTPUT_IAQ:
msgnode.air_IAQ = output.accuracy;
// Serial.println("\tiaq = " + String(output.signal));
// Serial.println("\tiaq accuracy = " +
// String((int)output.accuracy));
// Serial.print(" " + String((int)output.accuracy));
break;
case BSEC_OUTPUT_RAW_TEMPERATURE:
msgnode.temperature = output.signal;
// Serial.println("\ttemperature = " + String(output.signal));
// Serial.print(" " + String(output.signal));
break;
case BSEC_OUTPUT_RAW_PRESSURE:
msgnode.pressure = output.signal;
// Serial.println("\tpressure = " + String(output.signal));
// Serial.print(" " + String(output.signal));
break;
case BSEC_OUTPUT_RAW_HUMIDITY:
msgnode.humidity = output.signal;
// Serial.println("\thumidity = " + String(output.signal));
// Serial.print(" " + String(output.signal));
break;
case BSEC_OUTPUT_RAW_GAS:
msgnode.gasval = output.signal;
// Serial.println("\tgas resistance = " + String(output.signal));
// Serial.print(" " + String(output.signal));
break;
case BSEC_OUTPUT_STABILIZATION_STATUS:
// Serial.println("\tstabilization status = " +
// String(output.signal));
// Serial.print(" " + String(output.signal));
break;
case BSEC_OUTPUT_RUN_IN_STATUS:
// Serial.println("\trun in status = " + String(output.signal));
// Serial.print(" " + String(output.signal));
break;
default:
break;
}
}
xQueueSend(airQualityQueue, &msgnode, portMAX_DELAY);
}
读取到的数据内容有温度、湿度、大气压、空气电阻、和可信度。在传感器上电时可信度的值为0,此时空气质量的值不可信,需要将传感器放置在空气质量正常的环境中等待几分钟,等待传感器进行自我校正,当可信度大于0时,空气质量的值就是可用的了。
开辟两个任务,一个任务负责显示,将需要显示的内容通过屏幕显示出来。一个任务负责读取传感器,获得到传感器内容,两个任务使用消息队列通讯。
项目中空气质量的值使用经验值进行标定。当传感器在正常的环境中,空气质量的值基本都是超过30000,当遇到有挥发性气体(如:酒精)时,这个值就会迅速下降,这里使用30000作为阈值,当空气质量值低于30000时,就显示警告信息,当此值小于12000时,显示为危险信息,并且同时将收集到的信息上送物联网。
void dispTimeTask(void *pvParameters)
{
airQualityNode msgnode;
uint32_t lastTime = 0;
char msg[80];
while (1)
{
// 检查消息队列是否有消息
if (uxQueueMessagesWaiting(airQualityQueue) > 0)
{
// USBSerial.print("get message: ");
if (xQueueReceive(airQualityQueue, &msgnode, portMAX_DELAY) == pdPASS) // 消息出队
{
lastTime = millis();
USBSerial.print(msgnode.air_IAQ);
USBSerial.print(" ");
USBSerial.print(msgnode.temperature);
USBSerial.print(" ");
USBSerial.print(msgnode.humidity);
USBSerial.print(" ");
USBSerial.print(msgnode.pressure);
USBSerial.print(" ");
USBSerial.println(msgnode.gasval);
// 温度过高,或者 gas值过低 显示预警信息。gasval 目前使用经验数据,正常空气约为5W以上,遇到挥发气体,就迅速降低,低于3w需要警惕。
if (msgnode.air_IAQ > 0 && (msgnode.temperature > 40 || msgnode.gasval < 30000))
{
// 感知到异常情况
dispAirWarnInfo(msgnode); //显示警告、危险信息
// 组织消息,上送物联网
snprintf(msg, 80, "{\"temperature\":%.1f,\"humidity\":%.0f,\"pressure\":%.2f,\"gasval\":%.0f}", msgnode.temperature,msgnode.humidity,msgnode.pressure,msgnode.gasval);
Serial.print("Publish message: ");
Serial.println(msg); //串口打印,串口调试器可以看到的
mqttClient.publish(pubTopic, msg); //发送该主题消息
}
else
disptime(msgnode);
}
}
else if (millis() - lastTime > 20000) // 保持显示
{
disptime(msgnode);
vTaskDelay(1000);
}
else
{
vTaskDelay(1000);
}
}
}
效果演示:
开机后,置放在正常环境中,系统做初始化。在周围环境安全时,界面显示当前的时间。在上方用小字显示年月日和星期。在下方显示温度、湿度和获取到的空气质量的值。
向传感器附近的空气中喷了些花露水(乙醇),系统处于异常状态。
当系统报警后,会将当前环境信息上送到百度物联网。可以在任意地方通过互联网获取当前告警的环境信息。
同时,串口也有输出。
心得体会:
感谢电子森林和茂泽电子。茂泽电子商品极其丰富,且购买后物流也很快,买东西很方便。