基于STM32单片机的TVOC有害气体检测物联网系统
- 1、项目简介
- 1.1 系统功能
- 1.2 演示视频
- 2、部分电路设计
- 2.1 STM32单片机核心板电路设计
- 2.2 SGP30 TVOC检测电路设计
- 2.3 ESP8266 WIFI无线通信电路设计
- 2.4 OLED显示电路设计
- 3、单片机代码展示
- 3.1 系统初始化
- 3.2 SGP30初始化程序
- 3.3 SGP30读取TVOC与CO2数据程序
- 3.4 连接onenet物联网云平台
1、项目简介
1.1 系统功能
- 系统构成
- STM32单片机最小系统+SGP30 TVOC检测传感器电路+蜂鸣器报警电路+esp8266 WIFI电路+OLD液晶显示电路+风扇控制电路+按键电路
- 功能介绍:
- 1、stm32单片机通过sgp30采集tvoc,并通过oled显示
- 2、利用wifi把数据上传云平台,通过云平台显示
- 3、当有害气体超出阈值,蜂鸣器报警,并打开风扇,反之关闭
- 4、通过按键可以修改阈值
1.2 演示视频
2、部分电路设计
2.1 STM32单片机核心板电路设计
- 基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
- 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
- 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
- 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。
STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:
- 高性能和低功耗:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。
- 多种通信和外设接口:STM32单片机具备广泛的通信和外设接口,如I2C、SPI、USART、USB等,便于开发者实现各种复杂功能。
- 易于开发和调试:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统。
- 高集成度和设计灵活性:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性
单片机最小系统原理图如下图所示:
实物图:
2.2 SGP30 TVOC检测电路设计
- SGP30是一种室内空气质量传感器,能够检测二氧化碳(CO2)和挥发性有机化合物(VOC)的浓度。这个模块采用了先进的传感器技术,可以提供高精度的空气质量数据。
- SGP3x 是一个数字化多像素气体传感器平台,专为轻松集成到空气净化器、按需新风控制和物联网应用中而设计。SGP30 设计用于智能家居、家电和物联网应用,它提供两个经过校准的空气质量信号和湿度补偿功能。Sensirion 还通过 SGPC3 为移动应用提供低功率的可靠气体传感解决方案。
- SGP30模块通常包括一个集成的传感器芯片和相应的电路,使其能够方便地与微控制器连接。它通常通过I2C总线与微控制器通信,因此可以轻松地集成到各种不同的嵌入式系统中。
其具体电路原理图如下图所示:
实物图如下:
*
2.3 ESP8266 WIFI无线通信电路设计
- ESP8266-01s是由安信可科技开发的Wi-Fi模块,其核心处理器是ESP8266,这款处理器在较小的尺寸封装中集成了业界领先的Tensilica L106 超低功耗 32 位微型 MCU,支持 80 MHz 和 160 MHz 的主频,并带有 16 位精简模式。ESP8266-01s 支持RTOS,集成Wi-Fi MAC/BB/RF/PA/LNA,支持标准的IEEE802.11 b/g/n协议和完整的TCP/IP协议栈。这使得用户可以为现有设备添加联网功能,或者构建独立的网络控制器。
- ESP8266-01s 以其高性能和低成本的特性,为Wi-Fi功能的嵌入提供了无限可能,特别适用于物联网和智能家居等应用场景
其具体电路原理图如下图所示:
实物图如下:
2.4 OLED显示电路设计
- OLED显示屏是一款无需背景光源,自发光式的显示模块。模块采用蓝色背景,显示尺寸控制在0.96英寸,采用OLED专用驱动芯片SSD1306控制。该模块支持通过I2C接口与控制器通信,支持高传输速率,能够实现60Hz的刷新频率。
其具体电路原理图如下图所示:
实物图:
3、单片机代码展示
3.1 系统初始化
void HardWare_Init(void)
{
Usart1_Init(115200); //串口1
Usart2_Init(115200); //串口2 驱动ESP8266用
Beep_Init(); //蜂鸣器初始化
KEY_Init(); //按键初始化
RelayInit(); //继电器初始化
OLED_Init(); //OLED初始化
ConnectionNtpOneNet(); //连接OneNET云平台
RELAY_ON; //风扇打开
delay_ms(500);//延时500ms
RELAY_OFF; //风扇关闭
//清除数据
memset(&sample_data, 0, sizeof(SampleData));
memset(&system_mode, 0, sizeof(SystemMode));
memset(&show_data, 0, sizeof(ShowDataStr));
//初始化数据
system_mode.sys_mode = SystemModeStateAuto;
sample_data.tvoc_h = 150;
//初始化tvoc传感器
SGP30Init(&sample_data.spg30);
}
3.2 SGP30初始化程序
void SGP30Init(SGP30Data *sgp30_data)
{
u32 sgp30_dat;
SGP30_Init();
delay_ms(100);
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
sgp30_data->co2_ = (sgp30_dat & 0xffff0000) >> 16;
sgp30_data->tvoc_ = sgp30_dat & 0x0000ffff;
//SGP30模块开机需要一定时间初始化,在初始化阶段读取的CO2浓度为400ppm,TVOC为0ppd且恒定不变,因此上电后每隔一段时间读取一次
//SGP30模块的值,如果CO2浓度为400ppm,TVOC为0ppd,发送“正在检测中...”,直到SGP30模块初始化完成。
//初始化完成后刚开始读出数据会波动比较大,属于正常现象,一段时间后会逐渐趋于稳定。
//气体类传感器比较容易受环境影响,测量数据出现波动是正常的,可自行添加滤波函数。
while(sgp30_data->co2_ == 400 && sgp30_data->tvoc_ == 0)
{
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
sgp30_data->co2_ = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
sgp30_data->tvoc_ = sgp30_dat & 0x0000ffff; //取出TVOC值
// u1_printf("正在检测中...\r\n");
delay_ms(500);
}
}
3.3 SGP30读取TVOC与CO2数据程序
void SGP30Read(SGP30Data *sgp30_data)
{
u32 sgp30_dat = 0;
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
sgp30_data->co2_ = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
sgp30_data->tvoc_ = sgp30_dat & 0x0000ffff; //取出TVOC值
}
3.4 连接onenet物联网云平台
static void ConnectionNtpOneNet(void) {
ESP8266_Init(); //初始化ESP8266
UsartPrintf(USART_DEBUG, "Connect MQTTs Server...\r\n");
while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
delay_ms(500);
UsartPrintf(USART_DEBUG, "NET_OK\r\n");
while(OneNet_DevLink()) //接入OneNET
delay_ms(500);
OneNET_Subscribe();
}