基于STM32的工业仓库环境智能监控系统设计
项目开发背景
工业仓库作为企业物资存储的核心场所,其环境安全直接关系到货物品质、设备寿命及人员安全。传统仓库环境监测多依赖人工定时巡查与简单的独立报警装置,存在响应滞后、数据孤岛、无法实时预警和远程管理等问题。尤其对于存放易燃易爆、温湿度敏感物资的仓库,一旦发生烟雾积聚、有害气体泄漏或异常温升,若不能即时发现并处理,极易引发重大经济损失甚至安全事故。
随着物联网(IoT)技术与云平台的快速发展,构建智能化、网络化的环境监控系统成为必然趋势。STM32微控制器凭借其强大的实时处理能力、丰富的外设接口和低功耗特性,结合高精度传感器与无线通信技术,可实现对仓库关键环境参数(如温湿度、烟雾浓度、火焰状态、有毒气体)的连续精准采集与本地智能决策。通过自动报警、联动通风设备以及将数据实时上传至华为云平台,系统能显著提升风险响应速度,变被动处理为主动防护。
本项目旨在设计一套集成感知、决策、执行与云协同的智能监控解决方案。通过本地LCD屏提供直观状态反馈,利用ESP8266模块实现华为云IoT平台的稳定接入,并开发Qt上位机软件进行远程数据可视化与历史分析。这不仅解决了传统监测手段的缺陷,更为企业构建了可追溯的环境安全数据库,助力仓库管理的数字化升级,全面提升仓储安全性与运营效率。
设计实现的功能
(1)使用SHT30、MQ2、红外火焰传感器、MQ135实时监测仓库温湿度、烟雾浓度、火焰状态及有害气体浓度。
(2)当任一参数超出阈值时,触发有源蜂鸣器报警并通过继电器启动12V风扇通风。
(3)通过ESP8266 WiFi模块以MQTT协议将实时数据上传至华为云IoT平台,实现远程监测。
(4)基于Qt5+C++开发上位机软件,支持远程查看实时数据及历史数据趋势分析。
(5)通过SPI接口的1.44寸TFT LCD屏本地显示环境参数与系统状态(如温度、湿度、报警标志)。
项目硬件模块组成
(1)主控芯片:STM32F103C8T6
(2)温湿度检测:SHT30数字温湿度传感器(I2C接口)
(3)烟雾检测:MQ2烟雾传感器(模拟信号)
(4)火焰检测:红外火焰传感器(高低电平输出)
(5)有害气体检测:MQ135空气质量传感器(模拟信号)
(6)通信模块:ESP8266 WiFi模块(MQTT协议接入华为云)
(7)显示模块:1.44寸TFT LCD液晶屏(SPI接口)
(8)风扇控制模块:继电器驱动12V直流风扇
(9)报警模块:高电平触发有源蜂鸣器
(10)上位机软件:Qt5 + C++可视化监控平台
设计意义
设计意义:
该工业仓库环境智能监控系统通过集成多类传感器与智能控制模块,实现了对仓库环境的全方位实时监测与自动化管理。系统能够精准采集温湿度、烟雾、火焰及有害气体等关键参数,一旦检测到异常(如温度过高、烟雾浓度超标或可燃气体泄漏),立即触发本地蜂鸣器报警并自动启动风扇通风,快速降低环境风险,有效预防火灾、爆炸等安全事故,保障仓储物资安全与人员生命安全。
借助ESP8266模块与华为云IoT平台的对接,系统实现了环境数据的远程实时上传。管理人员可通过Qt开发的上位机软件远程查看仓库状态,分析历史数据趋势,及时制定环境优化策略。这种"云端+本地"的双重监控模式大幅提升了管理效率,减少人工巡检成本,尤其适用于大型或分散式仓库的集中化管理。
本地配备的TFT LCD显示屏为现场工作人员提供直观的环境状态反馈,确保即使网络中断时仍能维持基础监控功能。整体设计将环境感知、智能响应、远程监管与本地交互紧密结合,显著提升了工业仓库的安全等级与智能化管理水平,对降低企业运营风险、推动仓储数字化升级具有重要实践价值。
设计思路
设计思路
系统以STM32F103C8T6为核心控制器,通过多传感器协同工作实现仓库环境全维度监测。温湿度数据由SHT30传感器经I2C接口实时采集,烟雾浓度与有害气体浓度分别通过MQ2和MQ135的模拟信号输入至STM32的ADC模块进行量化分析。火焰检测采用数字式红外传感器,其高低电平信号直接接入GPIO口实现快速响应。
环境参数异常判定采用阈值比较机制。当任一传感器数据超过预设安全范围(如温度超限、烟雾浓度超标、火焰触发或气体泄漏),主控立即启动双重响应:通过GPIO驱动有源蜂鸣器发出声光报警,同时触发继电器控制12V直流风扇启动强制通风。所有传感器数据与报警状态实时刷新至1.44寸TFT LCD屏,SPI接口确保显示效率。
数据传输通过ESP8266模块实现,STM32通过UART发送AT指令建立WIFI连接,采用MQTT协议将结构化数据(包含传感器读数、设备状态及时间戳)上传至华为云IoT平台。云端数据持久化存储为上位机提供分析基础。
上位机基于Qt5框架开发,通过调用华为云API获取实时数据流及历史记录,可视化界面展示动态曲线、报警日志及环境参数分布。远程用户可通过该平台监控仓库状态,执行历史数据回溯分析,形成完整的监测-报警-远程管理闭环系统。所有功能严格遵循工业场景需求,无冗余设计。
框架图
系统框架图
+-----------------------------------------------------------------------------------------+
| 工业仓库环境智能监控系统 |
| |
| +-----------------+ +-------------------+ +-----------------+ +------------+ |
| | 传感器采集层 | | STM32主控 | | 执行控制层 | | 通信与云平台 | |
| | +-------------+ | | +---------------+ | | +-------------+ | | +---------+ | |
| | | SHT30 |----I2C----> | | | | 继电器控制 |<-----| | ESP8266 | | |
| | | 温湿度传感器| | | | | | | | | 12V风扇 | | | | WiFi模块 |----MQTT---> 华为云IoT平台 |
| | +-------------+ | | | | | | | +-------------+ | | | +---------+ | | | |
| | | | | | STM32F103C8T6 | | | | | | | | +-------------+
| | +-------------+ | | | | | | | +-------------+ | | | +---------+ | | | 上位机软件 |
| | | MQ2 |----ADC----> | | | | 有源蜂鸣器 |<-----| | | TFT LCD |<-----SPI----> (Qt5远程监控)|
| | | 烟雾传感器 | | | | | 数据处理 | | | | 报警器 | | | | | 1.44寸屏 | | | | 历史数据分析|
| | +-------------+ | | | | 阈值判断 | | | +-------------+ | | | +---------+ | | +-------------+
| | | | | | 逻辑控制 | | | | | | | |
| | +-------------+ | | | | | | | | | | | |
| | | 红外火焰 |----GPIO---> | | | | | | | |
| | | 传感器 | | | | | | | | | | | | |
| | +-------------+ | | | | 串口通信 |----UART----> | | | | |
| | | | | +---------------+ | | | | | | |
| | +-------------+ | | +-------------------+ | | | | | |
| | | MQ135 |----ADC----> | | | | | |
| | | 有害气体 | | | | | | | | |
| | +-------------+ | | +-----------------+ | +-------------+ |
| +-----------------+ +---------------------------------------------------+ |
| |
+-----------------------------------------------------------------------------------------+
框架说明:
-
传感器采集层
- SHT30(I2C):实时采集温湿度
- MQ2(ADC):检测烟雾浓度
- 红外火焰传感器(GPIO):火焰状态检测
- MQ135(ADC):监测有害气体浓度
-
STM32主控层
- STM32F103C8T6核心处理器
- 功能:
- 多接口数据采集(I2C/ADC/GPIO)
- 环境参数阈值判断与异常检测
- 控制逻辑决策(报警/通风)
- 串口通信驱动(连接ESP8266)
- SPI驱动LCD显示
-
执行控制层
- 继电器模块:控制12V风扇启停(通风)
- 有源蜂鸣器:高电平触发声光报警
-
通信与云平台层
- ESP8266:通过UART接收STM32数据,MQTT协议上传至华为云IoT
- TFT LCD(SPI):本地实时显示环境状态
- 华为云IoT平台:数据存储与远程访问枢纽
- Qt5上位机:远程监控/历史数据分析界面
系统总体设计
系统总体设计围绕STM32F103C8T6主控芯片构建,通过多传感器协同实现仓库环境智能监控。温湿度数据由SHT30传感器经I2C接口实时采集,烟雾浓度通过MQ2传感器模拟信号经ADC转换获取,火焰状态由红外火焰传感器数字信号直接输入GPIO,有害气体浓度则由MQ135传感器模拟信号经ADC转换监测。所有传感器数据在主控芯片进行实时融合处理。
当检测到任一参数超过安全阈值时,系统立即触发两级响应:通过GPIO驱动有源蜂鸣器发出声光报警,同时控制继电器启动12V直流风扇强制通风。环境状态及参数数值通过SPI接口在1.44寸TFT LCD屏上实时显示,提供本地可视化监控。
通信层面采用ESP8266 WiFi模块,通过AT指令集建立网络连接,基于MQTT协议将环境数据封装为JSON格式上传至华为云IoT平台。云平台实现数据持久化存储,为远程访问提供支持。
上位机采用Qt5框架开发,通过调用华为云API接口获取实时数据流及历史数据库,构建可视化监控界面。该界面支持多参数动态曲线展示、阈值配置及异常事件记录查询,实现远程仓库环境状态分析与管理。
系统功能总结
系统功能 | 主要实现模块 |
---|---|
实时监测仓库温湿度 | SHT30数字温湿度传感器(I2C接口) |
实时监测烟雾浓度 | MQ2烟雾传感器(模拟信号) |
实时监测火焰状态 | 红外火焰传感器(高低电平输出) |
实时监测有害气体泄漏 | MQ135空气质量传感器(模拟信号) |
环境异常自动声光报警 | 高电平触发有源蜂鸣器 |
环境异常自动通风控制 | 继电器驱动12V直流风扇 |
数据上传至华为云平台 | ESP8266 WiFi模块(MQTT协议) |
远程监测与历史数据分析 | 上位机软件(Qt5 + C++) |
本地环境状态显示 | 1.44寸TFT LCD液晶屏(SPI接口) |
核心控制与数据处理 | STM32F103C8T6主控芯片 |
设计的各个功能模块描述
主控制器模块
主控芯片采用STM32F103C8T6,负责协调所有硬件模块的运行。通过实时调度任务,完成数据采集、逻辑判断、报警控制、通信传输及显示驱动。其核心功能包括初始化外设接口(如I2C、SPI、ADC、UART)、处理传感器数据、执行异常响应策略(如启动风扇或蜂鸣器),并通过中断机制确保环境监测的实时性。
环境参数采集模块
该模块集成多种传感器:
- 温湿度检测:SHT30传感器通过I2C接口与STM32通信,实时采集仓库温度与湿度数据,数字信号输出精度高且抗干扰性强。
- 烟雾检测:MQ2传感器输出模拟信号,经STM32内部ADC转换为数字值,监测烟雾浓度变化。
- 火焰检测:红外火焰传感器输出高低电平信号,直接接入STM32 GPIO引脚,火焰出现时触发高电平报警。
- 有害气体检测:MQ135传感器通过模拟信号输出气体浓度,STM32的ADC模块量化数据以判断泄漏风险。
报警与执行模块
当任一传感器数据超出预设安全阈值时,系统立即响应:
- 触发有源蜂鸣器(高电平驱动)发出声光报警信号。
- 通过继电器控制12V直流风扇启动,强制通风以降低环境风险。
- 报警状态同步更新至LCD屏与云端,确保本地及远程实时获知异常。
无线通信模块
ESP8266 WiFi模块通过UART串口与STM32交互,采用MQTT协议将传感器数据封装并上传至华为云IoT平台。实现远程监测功能,支持上位机实时调取仓库环境状态,同时为历史数据分析提供云端数据存储基础。
本地显示模块
1.44寸TFT LCD屏通过SPI接口接收STM32指令,动态显示当前环境参数(温湿度、烟雾、火焰、气体浓度数值)及系统状态(正常/报警)。界面设计简洁,关键数据高亮提示,便于现场人员快速监控。
上位机软件模块
基于Qt5与C++开发的可视化监控平台,从华为云IoT平台获取数据。功能包括:
- 实时显示仓库多参数动态曲线与数值。
- 支持历史数据查询与分析(如温湿度趋势图、报警事件记录)。
- 提供参数阈值配置界面,增强远程管控灵活性。
上位机代码设计
以下是基于Qt5和C++的上位机监控系统完整代码设计,实现远程环境监控与数据分析功能:
#include <QtWidgets>
#include <QtMqtt>
#include <QtCharts>
#include <QDateTimeAxis>
#include <QValueAxis>
// 环境数据结构体
struct EnvData {
double temperature;
double humidity;
int smoke;
int flame;
int gas;
QDateTime timestamp;
};
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
setupUI();
setupMQTT();
setupDatabase();
}
private:
// UI组件
QTabWidget *tabWidget;
QMqttClient *mqttClient;
QSqlDatabase db;
QVector<EnvData> dataHistory;
// 实时监控页
QLabel *tempLabel, *humLabel, *smokeLabel, *flameLabel, *gasLabel;
// 历史数据页
QChartView *chartView;
QChart *dataChart;
QLineSeries *tempSeries, *humSeries;
// 报警日志页
QTextEdit *alarmLog;
void setupUI() {
// 主窗口设置
setWindowTitle("工业仓库环境监控系统");
setGeometry(100, 100, 800, 600);
// 标签页容器
tabWidget = new QTabWidget(this);
setCentralWidget(tabWidget);
// 1. 实时监控页
QWidget *realtimeTab = new QWidget;
QGridLayout *realtimeLayout = new QGridLayout;
realtimeLayout->addWidget(new QLabel("温度(℃):"), 0, 0);
tempLabel = new QLabel("--");
realtimeLayout->addWidget(tempLabel, 0, 1);
realtimeLayout->addWidget(new QLabel("湿度(%):"), 1, 0);
humLabel = new QLabel("--");
realtimeLayout->addWidget(humLabel, 1, 1);
realtimeLayout->addWidget(new QLabel("烟雾浓度:"), 2, 0);
smokeLabel = new QLabel("--");
realtimeLayout->addWidget(smokeLabel, 2, 1);
realtimeLayout->addWidget(new QLabel("火焰状态:"), 3, 0);
flameLabel = new QLabel("--");
realtimeLayout->addWidget(flameLabel, 3, 1);
realtimeLayout->addWidget(new QLabel("有害气体:"), 4, 0);
gasLabel = new QLabel("--");
realtimeLayout->addWidget(gasLabel, 4, 1);
realtimeTab->setLayout(realtimeLayout);
tabWidget->addTab(realtimeTab, "实时监控");
// 2. 历史数据页
QWidget *historyTab = new QWidget;
QVBoxLayout *historyLayout = new QVBoxLayout;
// 初始化图表
dataChart = new QChart;
chartView = new QChartView(dataChart);
chartView->setRenderHint(QPainter::Antialiasing);
// 时间轴
QDateTimeAxis *axisX = new QDateTimeAxis;
axisX->setFormat("hh:mm");
dataChart->addAxis(axisX, Qt::AlignBottom);
// 数值轴
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
dataChart->addAxis(axisY, Qt::AlignLeft);
// 数据序列
tempSeries = new QLineSeries;
tempSeries->setName("温度");
humSeries = new QLineSeries;
humSeries->setName("湿度");
dataChart->addSeries(tempSeries);
dataChart->addSeries(humSeries);
tempSeries->attachAxis(axisX);
tempSeries->attachAxis(axisY);
humSeries->attachAxis(axisX);
humSeries->attachAxis(axisY);
historyLayout->addWidget(chartView);
historyTab->setLayout(historyLayout);
tabWidget->addTab(historyTab, "历史数据");
// 3. 报警日志页
QWidget *alarmTab = new QWidget;
QVBoxLayout *alarmLayout = new QVBoxLayout;
alarmLog = new QTextEdit;
alarmLog->setReadOnly(true);
alarmLayout->addWidget(alarmLog);
QPushButton *clearBtn = new QPushButton("清空日志");
connect(clearBtn, &QPushButton::clicked, [this](){ alarmLog->clear(); });
alarmLayout->addWidget(clearBtn);
alarmTab->setLayout(alarmLayout);
tabWidget->addTab(alarmTab, "报警日志");
}
void setupMQTT() {
mqttClient = new QMqttClient(this);
mqttClient->setHostname("your_huaweicloud_address"); // 华为云地址
mqttClient->setPort(1883);
mqttClient->setUsername("your_username"); // 华为云用户名
mqttClient->setPassword("your_password"); // 华为云密码
connect(mqttClient, &QMqttClient::connected, [this](){
auto subscription = mqttClient->subscribe("env_data_topic", 0);
if (!subscription) {
QMessageBox::critical(this, "错误", "MQTT订阅失败!");
return;
}
});
connect(mqttClient, &QMqttClient::messageReceived, [this](const QByteArray &msg, const QMqttTopicName &){
processMessage(msg);
});
connect(mqttClient, &QMqttClient::stateChanged, [](QMqttClient::ClientState state){
qDebug() << "MQTT状态:" << state;
});
mqttClient->connectToHost();
}
void setupDatabase() {
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("env_data.db");
if (!db.open()) {
QMessageBox::critical(this, "数据库错误", "无法打开数据库!");
return;
}
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS env_data ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, "
"temperature REAL, "
"humidity REAL, "
"smoke INTEGER, "
"flame INTEGER, "
"gas INTEGER)");
}
void processMessage(const QByteArray &msg) {
QJsonDocument doc = QJsonDocument::fromJson(msg);
if (!doc.isObject()) return;
QJsonObject obj = doc.object();
EnvData data;
data.temperature = obj["temp"].toDouble();
data.humidity = obj["hum"].toDouble();
data.smoke = obj["smoke"].toInt();
data.flame = obj["flame"].toInt();
data.gas = obj["gas"].toInt();
data.timestamp = QDateTime::currentDateTime();
// 更新实时数据
tempLabel->setText(QString::number(data.temperature));
humLabel->setText(QString::number(data.humidity));
smokeLabel->setText(QString::number(data.smoke));
flameLabel->setText(data.flame ? "有火焰!" : "正常");
gasLabel->setText(QString::number(data.gas));
// 检查报警条件
if(data.temperature > 40 || data.humidity > 85 ||
data.smoke > 300 || data.flame || data.gas > 200) {
QString alarmMsg = QString("[%1] 报警! 温度:%2 湿度:%3 烟雾:%4 火焰:%5 气体:%6")
.arg(data.timestamp.toString("yyyy-MM-dd hh:mm:ss"))
.arg(data.temperature).arg(data.humidity)
.arg(data.smoke).arg(data.flame ? "是" : "否").arg(data.gas);
alarmLog->append(alarmMsg);
}
// 保存到数据库
QSqlQuery query;
query.prepare("INSERT INTO env_data (timestamp, temperature, humidity, smoke, flame, gas) "
"VALUES (?, ?, ?, ?, ?, ?)");
query.addBindValue(data.timestamp);
query.addBindValue(data.temperature);
query.addBindValue(data.humidity);
query.addBindValue(data.smoke);
query.addBindValue(data.flame);
query.addBindValue(data.gas);
query.exec();
// 更新图表
updateChart(data);
}
void updateChart(const EnvData &data) {
// 限制数据点数量
if (tempSeries->count() > 60) {
tempSeries->removePoints(0, tempSeries->count() - 60);
humSeries->removePoints(0, humSeries->count() - 60);
}
// 添加新数据点
qint64 msecs = data.timestamp.toMSecsSinceEpoch();
tempSeries->append(msecs, data.temperature);
humSeries->append(msecs, data.humidity);
// 更新坐标轴范围
QDateTimeAxis *axisX = qobject_cast<QDateTimeAxis*>(dataChart->axes(Qt::Horizontal)[0]);
if (axisX) {
axisX->setRange(
QDateTime::currentDateTime().addSecs(-300),
QDateTime::currentDateTime()
);
}
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 初始化Qt图表
QApplication::setApplicationName("工业仓库监控系统");
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
#include "main.moc"
上位机功能说明:
-
多标签页界面
- 实时监控:显示当前环境参数数值
- 历史数据:动态折线图展示温湿度变化
- 报警日志:记录异常事件及时间戳
-
核心功能实现
- MQTT连接华为云IoT平台接收实时数据
- SQLite数据库存储历史数据
- 动态图表展示(使用QtCharts)
- 多参数异常检测报警系统
- 数据持久化存储与检索
-
运行要求
- Qt5组件:QtCharts、QtMqtt、QtSql
- 华为云配置:替换MQTT连接参数
- 数据库:自动创建SQLite本地数据库
-
扩展功能
- 支持历史数据导出(CSV/Excel)
- 可添加阈值设置界面
- 支持多设备管理
- 可集成邮件/短信报警
使用说明:替换MQTT连接参数后直接编译运行,系统会自动创建数据库并接收云端数据。
模块代码设计
STM32工业仓库环境监控系统代码设计(寄存器方式)
#include "stm32f10x.h"
// 引脚定义
#define SHT30_SCL_PIN GPIO_Pin_6 // PB6
#define SHT30_SDA_PIN GPIO_Pin_7 // PB7
#define FLAME_SENSOR_PIN GPIO_Pin_2 // PA2
#define BUZZER_PIN GPIO_Pin_3 // PA3
#define FAN_PIN GPIO_Pin_4 // PA4
#define LCD_CS_PIN GPIO_Pin_8 // PA8
#define LCD_DC_PIN GPIO_Pin_0 // PB0
#define LCD_RST_PIN GPIO_Pin_1 // PB1
// 报警阈值
#define TEMP_HIGH_LIMIT 40.0
#define HUMI_HIGH_LIMIT 80.0
#define SMOKE_THRESHOLD 800
#define GAS_THRESHOLD 600
#define FLAME_ALARM_LEVEL 0 // 低电平触发报警
// 全局变量
float temperature = 0;
float humidity = 0;
uint16_t smoke_value = 0;
uint16_t gas_value = 0;
uint8_t flame_state = 1; // 默认安全状态
// 系统时钟初始化
void RCC_Configuration(void) {
// 开启外设时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |
RCC_APB2ENR_ADC1EN | RCC_APB2ENR_USART1EN |
RCC_APB2ENR_SPI1EN | RCC_APB2ENR_AFIOEN;
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
}
// GPIO初始化
void GPIO_Configuration(void) {
// I2C引脚 (PB6, PB7)
GPIOB->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_CNF7);
GPIOB->CRL |= GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_1; // 开漏输出
GPIOB->CRL |= GPIO_CRL_MODE6 | GPIO_CRL_MODE7; // 输出模式50MHz
// ADC引脚 (PA0-MQ2, PA1-MQ135)
GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1 | GPIO_CRL_MODE0 | GPIO_CRL_MODE1);
GPIOA->CRL |= GPIO_CRL_MODE0 | GPIO_CRL_MODE1; // 模拟输入模式
// 火焰传感器(PA2-输入), 蜂鸣器(PA3-输出), 风扇(PA4-输出)
GPIOA->CRL &= ~(GPIO_CRL_CNF2 | GPIO_CRL_CNF3 | GPIO_CRL_CNF4);
GPIOA->CRL |= GPIO_CRL_CNF2_0; // PA2浮空输入
GPIOA->CRL |= GPIO_CRL_MODE3 | GPIO_CRL_MODE4; // PA3/PA4输出模式50MHz
// LCD控制引脚 (PB0-DC, PB1-RST, PA8-CS)
GPIOB->CRL |= GPIO_CRL_MODE0 | GPIO_CRL_MODE1; // PB0/PB1推挽输出
GPIOA->CRH |= GPIO_CRH_MODE8; // PA8推挽输出
}
// I2C初始化
void I2C_Configuration(void) {
I2C1->CR1 &= ~I2C_CR1_PE; // 禁用I2C
// 配置时钟: 72MHz PCLK1, SM模式(100kHz)
I2C1->CR2 = 0x24; // FREQ = 36MHz
I2C1->CCR = 0xB4; // CCR = 180 (100kHz)
I2C1->TRISE = 0x25; // TRISE = 37 (1000ns)
I2C1->CR1 |= I2C_CR1_PE; // 启用I2C
}
// SHT30温湿度读取
uint8_t SHT30_ReadData(float *temp, float *humi) {
uint8_t cmd[2] = {0x2C, 0x06}; // 高精度测量命令
uint8_t data[6] = {0};
// 发送测量命令
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
I2C1->DR = 0x44 << 1; // SHT30地址+写
while(!(I2C1->SR1 & I2C_SR1_ADDR));
(void)I2C1->SR2; // 清除ADDR标志
I2C1->DR = cmd[0];
while(!(I2C1->SR1 & I2C_SR1_TXE));
I2C1->DR = cmd[1];
while(!(I2C1->SR1 & I2C_SR1_BTF));
I2C1->CR1 |= I2C_CR1_STOP;
// 延时等待测量完成
for(volatile int i=0; i<10000; i++);
// 读取数据
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
I2C1->DR = (0x44 << 1) | 0x01; // SHT30地址+读
while(!(I2C1->SR1 & I2C_SR1_ADDR));
(void)I2C1->SR2;
for(int i=0; i<5; i++) {
while(!(I2C1->SR1 & I2C_SR1_RXNE));
data[i] = I2C1->DR;
}
I2C1->CR1 &= ~I2C_CR1_ACK;
I2C1->CR1 |= I2C_CR1_STOP;
while(!(I2C1->SR1 & I2C_SR1_RXNE));
data[5] = I2C1->DR;
// 数据转换
uint16_t rawTemp = (data[0] << 8) | data[1];
uint16_t rawHumi = (data[3] << 8) | data[4];
*temp = -45 + 175 * (rawTemp / 65535.0f);
*humi = 100 * (rawHumi / 65535.0f);
return 1;
}
// ADC初始化
void ADC_Configuration(void) {
ADC1->CR2 = ADC_CR2_ADON; // 开启ADC
// 校准
ADC1->CR2 |= ADC_CR2_RSTCAL;
while(ADC1->CR2 & ADC_CR2_RSTCAL);
ADC1->CR2 |= ADC_CR2_CAL;
while(ADC1->CR2 & ADC_CR2_CAL);
// 配置通道0(MQ2)和通道1(MQ135)
ADC1->SMPR2 = (0x07 << (0 * 3)) | (0x07 << (1 * 3)); // 采样时间239.5周期
// 连续扫描模式
ADC1->CR1 = ADC_CR1_SCAN;
ADC1->CR2 = ADC_CR2_CONT | ADC_CR2_ADON;
}
// 读取ADC值
uint16_t ADC_Read(uint8_t channel) {
// 设置转换序列
ADC1->SQR3 = channel; // 单次转换
ADC1->CR2 |= ADC_CR2_SWSTART; // 开始转换
while(!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成
return ADC1->DR;
}
// 火焰传感器读取
uint8_t FlameSensor_Read(void) {
return GPIOA->IDR & FLAME_SENSOR_PIN ? 0 : 1; // 低电平触发
}
// 蜂鸣器控制
void Buzzer_Control(uint8_t state) {
if(state) GPIOA->BSRR = BUZZER_PIN;
else GPIOA->BRR = BUZZER_PIN;
}
// 风扇控制
void Fan_Control(uint8_t state) {
if(state) GPIOA->BSRR = FAN_PIN;
else GPIOA->BRR = FAN_PIN;
}
// 报警检测逻辑
void Check_Alarm(void) {
uint8_t alarm = 0;
if(temperature > TEMP_HIGH_LIMIT) alarm = 1;
if(humidity > HUMI_HIGH_LIMIT) alarm = 1;
if(smoke_value > SMOKE_THRESHOLD) alarm = 1;
if(gas_value > GAS_THRESHOLD) alarm = 1;
if(flame_state) alarm = 1;
if(alarm) {
Buzzer_Control(1);
Fan_Control(1);
} else {
Buzzer_Control(0);
Fan_Control(0);
}
}
// USART1初始化 (ESP8266)
void USART1_Configuration(void) {
// 波特率115200
USART1->BRR = 0x1D4C; // 72MHz/115200=625
USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
USART1->CR2 = 0;
USART1->CR3 = 0;
}
// 通过ESP8266发送数据到华为云
void Send_To_HuaweiCloud(void) {
char buffer[128];
sprintf(buffer, "T:%.1fC H:%.1f%% SMK:%d GAS:%d FL:%d",
temperature, humidity, smoke_value, gas_value, flame_state);
// 发送数据
for(char *p = buffer; *p; p++) {
while(!(USART1->SR & USART_SR_TXE));
USART1->DR = *p;
}
}
// LCD初始化 (SPI1)
void SPI1_Configuration(void) {
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_0 | SPI_CR1_BR_1; // 主模式, 18MHz
SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; // 软件NSS管理
SPI1->CR1 |= SPI_CR1_SPE; // 启用SPI
}
// LCD显示函数
void LCD_Display(void) {
// 简化显示实现
LCD_SendCommand(0x2A); // 设置列地址
// ... 具体显示实现
LCD_DrawString(10, 10, "Temp:");
LCD_DrawFloat(60, 10, temperature, 1);
// ... 其他数据显示
}
// 主函数
int main(void) {
// 系统初始化
RCC_Configuration();
GPIO_Configuration();
I2C_Configuration();
ADC_Configuration();
USART1_Configuration();
SPI1_Configuration();
// LCD初始化
LCD_Init();
while(1) {
// 读取传感器数据
SHT30_ReadData(&temperature, &humidity);
smoke_value = ADC_Read(0); // MQ2
gas_value = ADC_Read(1); // MQ135
flame_state = FlameSensor_Read();
// 报警检测
Check_Alarm();
// 上传数据到云平台
Send_To_HuaweiCloud();
// LCD显示
LCD_Display();
// 延时2秒
for(volatile int i=0; i<1000000; i++);
}
}
关键模块说明
-
SHT30温湿度传感器:
- 使用I2C接口(PB6/PB7)
- 发送高精度测量命令0x2C06
- 读取6字节数据并转换为实际温湿度值
-
MQ2/MQ135气体传感器:
- 使用ADC1通道0(PA0)和通道1(PA1)
- 239.5周期采样时间保证精度
- 返回12位ADC原始值(0-4095)
-
火焰传感器:
- 数字输入PA2
- 低电平触发报警(返回1表示火焰检测)
-
报警控制系统:
- 蜂鸣器(PA3)和风扇(PA4)控制
- 多参数阈值判断触发联动
-
华为云通信:
- USART1(PA9/PA10)连接ESP8266
- 通过MQTT协议传输格式化数据
- 实际使用需配置AT指令和MQTT连接
-
TFT LCD显示:
- SPI1接口(PA5/6/7)控制
- 显示当前环境参数和报警状态
- 需要实现底层SPI传输和显示驱动
项目核心代码
以下是基于STM32F103C8T6的工业仓库监控系统main.c
完整代码(寄存器开发方式):
#include "stm32f10x.h"
#include "sht30.h" // 温湿度传感器驱动
#include "lcd_spi.h" // LCD显示驱动
#include "mqtt_cloud.h" // 华为云MQTT通信
#include <stdio.h>
#include <string.h>
// 硬件引脚定义
#define FLAME_SENSOR_GPIO GPIOC
#define FLAME_SENSOR_PIN GPIO_Pin_0
#define BUZZER_GPIO GPIOC
#define BUZZER_PIN GPIO_Pin_1
#define FAN_RELAY_GPIO GPIOC
#define FAN_RELAY_PIN GPIO_Pin_2
#define MQ2_ADC_CHANNEL ADC_Channel_0 // PA0
#define MQ135_ADC_CHANNEL ADC_Channel_1 // PA1
// 报警阈值
#define TEMP_ALARM_MAX 40.0 // 温度报警值(℃)
#define HUMI_ALARM_MAX 80.0 // 湿度报警值(%)
#define SMOKE_ALARM_THRESHOLD 800 // 烟雾ADC报警值
#define GAS_ALARM_THRESHOLD 700 // 有害气体ADC报警值
// 全局变量
volatile uint16_t adc_mq2 = 0; // 烟雾传感器ADC值
volatile uint16_t adc_mq135 = 0; // 有害气体ADC值
float temperature = 0.0; // 温度值
float humidity = 0.0; // 湿度值
uint8_t flame_state = 0; // 火焰状态(0:正常, 1:有火焰)
uint8_t alarm_flag = 0; // 综合报警标志
// 函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void ADC_Configuration(void);
void TIM3_Init(void);
void NVIC_Configuration(void);
uint16_t Get_ADC_Value(uint8_t channel);
void Check_Alarm_Condition(void);
void Send_Cloud_Data(void);
int main(void) {
// 系统初始化
RCC_Configuration();
GPIO_Configuration();
ADC_Configuration();
TIM3_Init();
NVIC_Configuration();
LCD_Init(); // 初始化LCD
SHT30_Init(); // 初始化温湿度传感器
ESP8266_Init(); // 初始化WiFi模块
MQTT_Connect(); // 连接华为云
LCD_Clear(BLACK);
LCD_ShowString(10, 5, "Warehouse Monitor", WHITE, BLACK);
while(1) {
// 1. 读取传感器数据
SHT30_ReadData(&temperature, &humidity);
flame_state = GPIO_ReadInputDataBit(FLAME_SENSOR_GPIO, FLAME_SENSOR_PIN);
// 2. 检查报警条件
Check_Alarm_Condition();
// 3. LCD显示数据
char disp_buf[50];
sprintf(disp_buf, "Temp: %.1fC Humi: %.1f%%", temperature, humidity);
LCD_ShowString(10, 30, disp_buf, WHITE, BLACK);
sprintf(disp_buf, "Smoke: %d Gas: %d", adc_mq2, adc_mq135);
LCD_ShowString(10, 50, disp_buf, WHITE, BLACK);
sprintf(disp_buf, "Flame: %s", flame_state ? "DETECT!" : "Normal");
LCD_ShowString(10, 70, flame_state ? RED : GREEN, BLACK, disp_buf);
sprintf(disp_buf, "Status: %s", alarm_flag ? "ALARM!" : "Normal");
LCD_ShowString(10, 90, alarm_flag ? RED : GREEN, BLACK, disp_buf);
// 4. 每5秒上传数据到云端
static uint32_t cloud_timer = 0;
if(HAL_GetTick() - cloud_timer > 5000) {
cloud_timer = HAL_GetTick();
Send_Cloud_Data();
}
}
}
// 系统时钟配置
void RCC_Configuration(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC时钟=72MHz/6=12MHz
}
// GPIO配置
void GPIO_Configuration(void) {
// 火焰传感器输入(PC0)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = FLAME_SENSOR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(FLAME_SENSOR_GPIO, &GPIO_InitStructure);
// 蜂鸣器输出(PC1)
GPIO_InitStructure.GPIO_Pin = BUZZER_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(BUZZER_GPIO, &GPIO_InitStructure);
// 风扇继电器(PC2)
GPIO_InitStructure.GPIO_Pin = FAN_RELAY_PIN;
GPIO_Init(FAN_RELAY_GPIO, &GPIO_InitStructure);
}
// ADC配置
void ADC_Configuration(void) {
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
// TIM3初始化(用于ADC定时采样)
void TIM3_Init(void) {
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Period = 999; // 1kHz
TIM_InitStructure.TIM_Prescaler = 71; // 72MHz/72=1MHz
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_InitStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
// 中断配置
void NVIC_Configuration(void) {
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// ADC采样中断服务函数
void TIM3_IRQHandler(void) {
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
adc_mq2 = Get_ADC_Value(MQ2_ADC_CHANNEL); // 采样MQ2
adc_mq135 = Get_ADC_Value(MQ135_ADC_CHANNEL); // 采样MQ135
}
}
// 获取ADC采样值
uint16_t Get_ADC_Value(uint8_t channel) {
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
// 报警条件检查
void Check_Alarm_Condition(void) {
alarm_flag = 0;
// 温度超标
if(temperature > TEMP_ALARM_MAX) {
alarm_flag = 1;
}
// 湿度超标
if(humidity > HUMI_ALARM_MAX) {
alarm_flag = 1;
}
// 烟雾检测
if(adc_mq2 > SMOKE_ALARM_THRESHOLD) {
alarm_flag = 1;
}
// 有害气体检测
if(adc_mq135 > GAS_ALARM_THRESHOLD) {
alarm_flag = 1;
}
// 火焰检测
if(flame_state) {
alarm_flag = 1;
}
// 触发报警设备
if(alarm_flag) {
GPIO_SetBits(BUZZER_GPIO, BUZZER_PIN); // 开启蜂鸣器
GPIO_SetBits(FAN_RELAY_GPIO, FAN_RELAY_PIN); // 开启风扇
} else {
GPIO_ResetBits(BUZZER_GPIO, BUZZER_PIN); // 关闭蜂鸣器
GPIO_ResetBits(FAN_RELAY_GPIO, FAN_RELAY_PIN); // 关闭风扇
}
}
// 发送数据到华为云
void Send_Cloud_Data(void) {
char json_buf[128];
snprintf(json_buf, sizeof(json_buf),
"{\"temp\":%.1f,\"humi\":%.1f,\"smoke\":%d,\"gas\":%d,\"flame\":%d,\"alarm\":%d}",
temperature, humidity, adc_mq2, adc_mq135, flame_state, alarm_flag);
MQTT_PublishData(json_buf); // 通过MQTT协议发布数据
}
代码说明:
-
传感器数据采集:
- SHT30通过I2C读取温湿度
- MQ2/MQ135通过ADC定时采样(TIM3触发)
- 火焰传感器通过GPIO输入检测
-
报警控制逻辑:
- 温度>40℃/湿度>80%/烟雾>800/气体>700/火焰触发时
- 触发蜂鸣器(PC1)和风扇继电器(PC2)
-
数据显示与通信:
- 实时在TFT LCD显示环境参数
- 每5秒通过ESP8266以MQTT协议上传数据到华为云
- 数据格式为JSON:
{"temp":25.5,"humi":45.0,...}
-
关键外设驱动:
- ADC多通道轮询采样
- TIM3定时器触发采样
- GPIO控制报警设备
- SPI驱动LCD显示
总结
本文设计的基于STM32的工业仓库环境智能监控系统,以STM32F103C8T6为核心控制器,通过多传感器协同实现了对仓库环境的全面监测。系统集成了SHT30温湿度传感器、MQ2烟雾传感器、红外火焰传感器和MQ135有害气体检测模块,构建了高可靠性的环境参数采集网络。实时数据通过SPI接口的1.44寸TFT LCD本地显示,同时利用ESP8266 WiFi模块通过MQTT协议将数据上传至华为云平台,实现了远程监控与历史数据分析的双重保障。
系统具备智能响应机制,当检测到温湿度超标、烟雾浓度异常、火焰或有害气体泄漏时,STM32主控将立即触发有源蜂鸣器报警,并通过继电器驱动12V直流风扇启动强制通风。这种本地-云端联动的设计既保证了异常情况的快速处置,又通过华为云平台为上位机(基于Qt5开发的可视化平台)提供了数据支撑,实现了仓库环境的多维度安全管理。
该设计充分考虑了工业场景的实际需求,硬件选型兼顾成本与性能,软件架构实现了数据采集、异常处理、云端通信的有机融合。系统不仅提升了仓库环境监控的智能化水平,其模块化设计也为未来功能扩展(如增加入侵检测或照明控制)奠定了基础,具有较高的工程应用价值。
- 点赞
- 收藏
- 关注作者
评论(0)