基于STM32的工业仓库环境智能监控系统设计

举报
DS小龙哥 发表于 2025/06/22 18:33:21 2025/06/22
【摘要】 项目开发背景工业仓库作为企业物资存储的核心场所,其环境安全直接关系到货物品质、设备寿命及人员安全。传统仓库环境监测多依赖人工定时巡查与简单的独立报警装置,存在响应滞后、数据孤岛、无法实时预警和远程管理等问题。尤其对于存放易燃易爆、温湿度敏感物资的仓库,一旦发生烟雾积聚、有害气体泄漏或异常温升,若不能即时发现并处理,极易引发重大经济损失甚至安全事故。随着物联网(IoT)技术与云平台的快速发展...

项目开发背景

工业仓库作为企业物资存储的核心场所,其环境安全直接关系到货物品质、设备寿命及人员安全。传统仓库环境监测多依赖人工定时巡查与简单的独立报警装置,存在响应滞后、数据孤岛、无法实时预警和远程管理等问题。尤其对于存放易燃易爆、温湿度敏感物资的仓库,一旦发生烟雾积聚、有害气体泄漏或异常温升,若不能即时发现并处理,极易引发重大经济损失甚至安全事故。

随着物联网(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---->                    |                 | |    |             | |
|   | | 有害气体    | | |                            |                 | |    |             | |
|   | +-------------+ | |                            +-----------------+ |    +-------------+ |
|   +-----------------+ +---------------------------------------------------+                 |
|                                                                                             |
+-----------------------------------------------------------------------------------------+

框架说明:

  1. 传感器采集层

    • SHT30(I2C):实时采集温湿度
    • MQ2(ADC):检测烟雾浓度
    • 红外火焰传感器(GPIO):火焰状态检测
    • MQ135(ADC):监测有害气体浓度
  2. STM32主控层

    • STM32F103C8T6核心处理器
    • 功能:
      • 多接口数据采集(I2C/ADC/GPIO)
      • 环境参数阈值判断与异常检测
      • 控制逻辑决策(报警/通风)
      • 串口通信驱动(连接ESP8266)
      • SPI驱动LCD显示
  3. 执行控制层

    • 继电器模块:控制12V风扇启停(通风)
    • 有源蜂鸣器:高电平触发声光报警
  4. 通信与云平台层

    • 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"

上位机功能说明:

  1. 多标签页界面

    • 实时监控:显示当前环境参数数值
    • 历史数据:动态折线图展示温湿度变化
    • 报警日志:记录异常事件及时间戳
  2. 核心功能实现

    • MQTT连接华为云IoT平台接收实时数据
    • SQLite数据库存储历史数据
    • 动态图表展示(使用QtCharts)
    • 多参数异常检测报警系统
    • 数据持久化存储与检索
  3. 运行要求

    • Qt5组件:QtCharts、QtMqtt、QtSql
    • 华为云配置:替换MQTT连接参数
    • 数据库:自动创建SQLite本地数据库
  4. 扩展功能

    • 支持历史数据导出(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++);
    }
}

关键模块说明

  1. SHT30温湿度传感器

    • 使用I2C接口(PB6/PB7)
    • 发送高精度测量命令0x2C06
    • 读取6字节数据并转换为实际温湿度值
  2. MQ2/MQ135气体传感器

    • 使用ADC1通道0(PA0)和通道1(PA1)
    • 239.5周期采样时间保证精度
    • 返回12位ADC原始值(0-4095)
  3. 火焰传感器

    • 数字输入PA2
    • 低电平触发报警(返回1表示火焰检测)
  4. 报警控制系统

    • 蜂鸣器(PA3)和风扇(PA4)控制
    • 多参数阈值判断触发联动
  5. 华为云通信

    • USART1(PA9/PA10)连接ESP8266
    • 通过MQTT协议传输格式化数据
    • 实际使用需配置AT指令和MQTT连接
  6. 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协议发布数据
}

代码说明:

  1. 传感器数据采集

    • SHT30通过I2C读取温湿度
    • MQ2/MQ135通过ADC定时采样(TIM3触发)
    • 火焰传感器通过GPIO输入检测
  2. 报警控制逻辑

    • 温度>40℃/湿度>80%/烟雾>800/气体>700/火焰触发时
    • 触发蜂鸣器(PC1)和风扇继电器(PC2)
  3. 数据显示与通信

    • 实时在TFT LCD显示环境参数
    • 每5秒通过ESP8266以MQTT协议上传数据到华为云
    • 数据格式为JSON:{"temp":25.5,"humi":45.0,...}
  4. 关键外设驱动

    • ADC多通道轮询采样
    • TIM3定时器触发采样
    • GPIO控制报警设备
    • SPI驱动LCD显示

总结

本文设计的基于STM32的工业仓库环境智能监控系统,以STM32F103C8T6为核心控制器,通过多传感器协同实现了对仓库环境的全面监测。系统集成了SHT30温湿度传感器、MQ2烟雾传感器、红外火焰传感器和MQ135有害气体检测模块,构建了高可靠性的环境参数采集网络。实时数据通过SPI接口的1.44寸TFT LCD本地显示,同时利用ESP8266 WiFi模块通过MQTT协议将数据上传至华为云平台,实现了远程监控与历史数据分析的双重保障。

系统具备智能响应机制,当检测到温湿度超标、烟雾浓度异常、火焰或有害气体泄漏时,STM32主控将立即触发有源蜂鸣器报警,并通过继电器驱动12V直流风扇启动强制通风。这种本地-云端联动的设计既保证了异常情况的快速处置,又通过华为云平台为上位机(基于Qt5开发的可视化平台)提供了数据支撑,实现了仓库环境的多维度安全管理。

该设计充分考虑了工业场景的实际需求,硬件选型兼顾成本与性能,软件架构实现了数据采集、异常处理、云端通信的有机融合。系统不仅提升了仓库环境监控的智能化水平,其模块化设计也为未来功能扩展(如增加入侵检测或照明控制)奠定了基础,具有较高的工程应用价值。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。