基于STM32设计的智能车间生产安全监控系统

举报
DS小龙哥 发表于 2025/12/25 15:17:29 2025/12/25
【摘要】 项目开发背景随着工业4.0和智能制造的快速发展,现代车间生产环境日益复杂,对安全监控提出了更高要求。传统车间安全监控多依赖人工巡检和基础传感器,难以实现全面、实时的风险预警,导致安全事故频发,不仅威胁工人生命安全,还可能造成重大经济损失。因此,开发一套集成环境监测、设备状态跟踪和人员行为识别的智能安全系统显得尤为迫切。在工业生产中,火灾、噪声污染和设备故障等隐患往往被忽视,而人员违规操作更...

项目开发背景

随着工业4.0和智能制造的快速发展,现代车间生产环境日益复杂,对安全监控提出了更高要求。传统车间安全监控多依赖人工巡检和基础传感器,难以实现全面、实时的风险预警,导致安全事故频发,不仅威胁工人生命安全,还可能造成重大经济损失。因此,开发一套集成环境监测、设备状态跟踪和人员行为识别的智能安全系统显得尤为迫切。

在工业生产中,火灾、噪声污染和设备故障等隐患往往被忽视,而人员违规操作更是事故的主要诱因。现有监控手段缺乏智能化分析能力,无法及时识别潜在危险,且数据记录分散,不利于长期安全改进。基于STM32的智能监控系统通过融合多种传感器和图像处理技术,能够实现对车间环境的全方位监测,并借助云平台进行数据交互,提升安全管理的效率和准确性。

该系统设计结合了物联网和人工智能技术,通过实时采集烟雾、噪声等环境参数,并利用摄像头进行人员行为识别,可自动触发报警机制。同时,安全生产数据的记录与分析有助于企业优化流程,预防事故发生,推动车间向数字化、智能化转型,最终保障生产活动的可持续性和稳定性。

设计实现的功能

(1) 人员安全行为识别和违规报警功能
(2) 火灾隐患监测功能
(3) 环境噪声水平监测功能
(4) 安全生产数据记录和分析功能
(5) 华为云通信和数据传输功能
(6) QT上位机安全监控显示功能

项目硬件模块组成

(1)STM32F103C8T6最小系统核心板作为主控制器
(2)OV7670摄像头模块进行安全行为识别
(3)MQ-2烟雾传感器监测火灾隐患
(4)噪声传感器监测环境噪声水平
(5)ESP8266-01S Wi-Fi模块实现华为云通信
(6)洞洞板焊接图像处理电路,杜邦线连接各传感器

设计意义

本设计基于STM32的智能车间生产安全监控系统,通过集成多种传感器和控制器,实现了对车间环境和设备状态的全面实时监控,有效提升了生产安全管理的自动化和智能化水平。系统能够及时检测潜在风险,如火灾隐患和噪声污染,从而预防事故发生,保障人员与设备的安全。

人员安全行为识别和违规报警功能通过摄像头模块实时捕捉和分析员工行为,一旦发现违规操作立即触发警报,这有助于减少人为失误导致的安全事故,强化了车间的安全规范执行。

安全生产数据记录和分析模块能够持续收集和存储环境与设备数据,为安全管理决策提供可靠依据,通过数据分析识别趋势性问题,支持持续改进安全措施和优化生产流程。

QT上位机显示界面直观呈现监控画面和预警信息,使操作人员能够远程实时掌握车间安全状况,快速响应异常事件,提高了监控效率和应急处理能力。

整体上,该系统通过硬件集成和软件协同,构建了一个高效、可靠的安全监控体系,不仅降低了安全风险,还促进了车间生产管理的现代化和标准化。

设计思路

本系统以STM32F103C8T6最小系统核心板作为主控制器,负责协调整个监控系统的运行。通过洞洞板焊接图像处理电路,并使用杜邦线连接OV7670摄像头模块、MQ-2烟雾传感器、噪声传感器和ESP8266-01S Wi-Fi模块,构建一个完整的硬件平台。该系统旨在实时采集车间环境数据,并通过图像处理识别人员行为,确保生产安全。

数据采集部分由STM32控制器定期读取MQ-2烟雾传感器的模拟信号,检测烟雾浓度以判断火灾隐患;同时读取噪声传感器的数据,监测环境噪声水平是否超标。这些环境参数与设备运行状态数据一起被整合处理,为实时监控提供基础。

人员安全行为识别通过OV7670摄像头模块实现,该模块捕获车间视频流,并经由图像处理电路进行初步预处理,例如图像滤波或简单特征提取。STM32运行基本的计算机视觉算法,检测人员是否佩戴安全帽或存在其他违规行为,一旦识别到异常,立即触发本地报警机制。

数据通信方面,ESP8266-01S Wi-Fi模块将STM32处理后的环境数据、行为识别结果和报警信息传输到华为云平台。云平台用于存储和分析这些数据,支持远程访问和后续处理,确保数据可靠上传和实时更新。

安全生产数据记录和分析在STM32本地或华为云上进行,系统记录历史环境参数、行为事件和设备状态,通过简单统计或趋势分析生成报告,帮助用户评估安全状况并优化管理策略。

QT上位机应用程序从华为云或直接通过Wi-Fi接收数据,实时显示车间监控画面、传感器读数和预警信息。用户可以通过上位机界面查看实时状态、历史记录和报警详情,便于及时干预和决策。

报警机制在检测到烟雾浓度超标、噪声过高或人员行为违规时触发,STM32控制本地设备如蜂鸣器或LED发出警示,同时通过Wi-Fi将报警信息发送到上位机和云平台,实现多层次响应,确保车间安全监控的及时性和有效性。

框架图

+---------------------------------+
|       传感器层                   |
|                                 |
|  +---------------------------+  |
|  | OV7670摄像头模块          |  |
|  | (安全行为识别)            |  |
|  +---------------------------+  |
|              |                  |
|              v                  |
|  +---------------------------+  |
|  | 洞洞板图像处理电路        |  |
|  | (焊接处理电路)            |  |
|  +---------------------------+  |
|              |                  |
|  +---------------------------+  |
|  | MQ-2烟雾传感器            |  |
|  | (火灾隐患监测)            |  |
|  +---------------------------+  |
|              |                  |
|  +---------------------------+  |
|  | 噪声传感器                |  |
|  | (环境噪声监测)            |  |
|  +---------------------------+  |
+---------------------------------+
              |
              | (杜邦线连接)
              v
+---------------------------------+
|       处理层                   |
|                                 |
|  STM32F103C8T6核心板           |
|  (主控制器)                    |
|  - 实时数据采集和处理          |
|  - 安全行为识别算法            |
|  - 违规报警触发                |
|  - 数据记录和初步分析          |
+---------------------------------+
              |
              | (串口/SPI通信)
              v
+---------------------------------+
|       通信层                   |
|                                 |
|  ESP8266-01S Wi-Fi模块         |
|  (华为云通信)                  |
+---------------------------------+
              |
              | (Wi-Fi传输)
              v
+---------------------------------+
|       云平台                   |
|                                 |
|  华为云                        |
|  - 数据存储和进一步分析        |
|  - 预警信息推送                |
+---------------------------------+
              |
              | (网络接口)
              v
+---------------------------------+
|       应用层                   |
|                                 |
|  QT上位机                      |
|  - 实时显示监控画面            |
|  - 安全状态和预警信息展示      |
|  - 历史数据查询和分析          |
+---------------------------------+

系统总体设计

本系统基于STM32F103C8T6最小系统核心板作为主控制器,负责协调整个智能车间生产安全监控系统的运行。该系统通过集成多种传感器和模块,实现对车间环境和人员行为的实时监测与控制,确保生产安全。硬件连接采用洞洞板焊接图像处理电路,并使用杜邦线连接各传感器,以简化布线并提高系统的可靠性和灵活性。

环境安全监测部分由MQ-2烟雾传感器和噪声传感器组成,MQ-2传感器用于检测车间内的烟雾浓度,及时发现火灾隐患;噪声传感器则监测环境噪声水平,防止过高噪声影响人员健康和设备运行。这些传感器数据由STM32主控制器实时采集和处理,一旦检测到异常,系统会触发本地报警机制。

人员安全行为识别通过OV7670摄像头模块实现,该模块采集车间内的视频图像,并由STM32进行基本的图像处理分析,识别人员的安全行为,如是否佩戴安全装备或存在违规操作。当检测到违规行为时,系统会立即发出报警信号,并通过控制器记录相关事件数据,用于后续分析。

安全生产数据记录和分析功能由STM32主控制器负责,它持续收集来自传感器和摄像头的数据,并进行初步处理和存储。通过ESP8266-01S Wi-Fi模块,系统将关键数据上传至华为云平台,实现远程数据通信和备份,便于进行长期趋势分析和历史查询。

QT上位机作为用户界面,显示车间的实时安全监控画面和预警信息。它通过Wi-Fi模块接收来自STM32的数据,以图形化方式展示环境参数、设备状态和人员行为信息,同时提供报警提示和数据分析报告,帮助管理人员及时响应和处理安全事件。

系统功能总结

功能名称 功能描述 关键硬件/组件
环境安全监测 实时监测车间环境参数,如烟雾浓度和噪声水平,用于火灾隐患和环境噪声检测。 MQ-2烟雾传感器、噪声传感器、STM32主控制器
人员安全行为识别 通过摄像头模块识别人员安全行为(如安全帽佩戴),并在检测到违规时触发报警。 OV7670摄像头模块、STM32主控制器
安全生产数据记录与分析 记录车间安全生产数据,通过STM32处理并上传至华为云进行存储和分析。 STM32主控制器、ESP8266 Wi-Fi模块、华为云平台
实时监控与预警显示 在QT上位机上实时显示监控画面、环境数据和预警信息,提供可视化监控界面。 QT上位机软件、ESP8266 Wi-Fi模块

设计的各个功能模块描述

STM32F103C8T6最小系统核心板作为系统的主控制器,负责协调和管理所有外围模块的运行。它通过处理来自各种传感器的数据,实现车间环境安全和设备运行状态的实时监测,同时执行人员安全行为识别的算法逻辑,并记录安全生产数据用于后续分析。主控制器还通过Wi-Fi模块与华为云建立通信,确保数据能够及时上传和同步。

OV7670摄像头模块用于人员安全行为识别,通过捕获车间内的实时图像,由STM32主控制器进行图像处理和分析,检测是否存在违规行为,如未佩戴安全防护装备或不当操作。一旦识别到异常,系统会立即触发报警机制,并通过通信模块上报预警信息,以提升车间的安全响应效率。

MQ-2烟雾传感器负责监测车间环境中的烟雾浓度,用于检测潜在的火灾隐患。该传感器将实时数据传送给STM32主控制器,当检测到烟雾水平超过预设阈值时,系统会自动发出报警信号,并记录相关数据,以便及时采取预防措施,保障生产安全。

噪声传感器用于监测车间内的环境噪声水平,通过测量噪音强度来判断是否符合安全生产标准。传感器数据由STM32主控制器采集和分析,如果噪音超出安全范围,系统会记录异常并触发报警,帮助维护适宜的工作环境,减少健康风险。

ESP8266-01S Wi-Fi模块实现与华为云的通信功能,它将STM32主控制器收集的各类数据,包括传感器读数、报警信息和图像处理结果,无线传输到云平台。这使得QT上位机能够实时接收和显示安全监控画面及预警信息,便于远程监控和数据分析。

洞洞板焊接的图像处理电路作为辅助硬件,用于连接OV7670摄像头模块和其他传感器组件,通过杜邦线实现灵活的电气连接。该电路确保图像数据能够稳定传输到STM32主控制器进行处理,从而支持高效的安全行为识别和系统集成。

上位机代码设计

#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QTextEdit>
#include <QTabWidget>
#include <QGroupBox>
#include <QProgressBar>
#include <QTimer>
#include <QDateTime>
#include <QChart>
#include <QChartView>
#include <QLineSeries>
#include <QValueAxis>
#include <QTcpSocket>
#include <QHostAddress>
#include <QMessageBox>
#include <QFile>
#include <QDataStream>

QT_CHARTS_USE_NAMESPACE

// 数据包结构体
#pragma pack(push, 1)
struct SafetyData {
    quint32 timestamp;
    float smoke_level;      // 烟雾浓度
    float noise_level;      // 噪声水平
    quint8 safety_status;   // 安全状态
    quint8 violation_type;  // 违规类型
    quint8 reserved[2];     // 保留字节
};
#pragma pack(pop)

class SafetyMonitor : public QMainWindow {
    Q_OBJECT

public:
    SafetyMonitor(QWidget *parent = nullptr) : QMainWindow(parent) {
        setupUI();
        setupConnections();
        setupChart();
        startMonitoring();
    }

private slots:
    void connectToDevice() {
        socket->connectToHost("192.168.1.100", 8080); // 设备IP和端口
    }

    void readData() {
        while (socket->bytesAvailable() >= sizeof(SafetyData)) {
            SafetyData data;
            socket->read(reinterpret_cast<char*>(&data), sizeof(data));
            processSafetyData(data);
        }
    }

    void processSafetyData(const SafetyData& data) {
        // 更新环境数据显示
        updateEnvironmentDisplay(data);
        
        // 更新图表数据
        updateCharts(data);
        
        // 检查报警条件
        checkAlarms(data);
        
        // 记录数据到文件
        logData(data);
    }

    void updateEnvironmentDisplay(const SafetyData& data) {
        // 更新烟雾浓度显示
        smokeValue->setText(QString::number(data.smoke_level, 'f', 2));
        smokeProgress->setValue(static_cast<int>(data.smoke_level));
        
        // 更新噪声水平显示
        noiseValue->setText(QString::number(data.noise_level, 'f', 1));
        noiseProgress->setValue(static_cast<int>(data.noise_level));
        
        // 更新安全状态
        updateSafetyStatus(data.safety_status);
        
        // 更新违规信息
        updateViolationInfo(data.violation_type);
    }

    void updateSafetyStatus(quint8 status) {
        QString statusText;
        QString color;
        
        switch(status) {
            case 0: statusText = "正常"; color = "green"; break;
            case 1: statusText = "警告"; color = "yellow"; break;
            case 2: statusText = "危险"; color = "red"; break;
            default: statusText = "未知"; color = "gray"; break;
        }
        
        safetyStatus->setText(QString("<font color='%1'>%2</font>").arg(color, statusText));
    }

    void updateViolationInfo(quint8 violation) {
        QStringList violations;
        if (violation & 0x01) violations << "未戴安全帽";
        if (violation & 0x02) violations << "未穿工作服";
        if (violation & 0x04) violations << "禁区闯入";
        if (violation & 0x08) violations << "违规操作";
        
        violationInfo->setText(violations.join("、"));
        
        if (!violations.isEmpty()) {
            showAlarm("安全违规警告", violations.join(","));
        }
    }

    void checkAlarms(const SafetyData& data) {
        // 烟雾浓度报警
        if (data.smoke_level > 80.0f) {
            showAlarm("火灾预警", QString("烟雾浓度过高: %1").arg(data.smoke_level));
        }
        
        // 噪声水平报警
        if (data.noise_level > 85.0f) {
            showAlarm("噪声预警", QString("噪声水平过高: %1 dB").arg(data.noise_level));
        }
    }

    void showAlarm(const QString& title, const QString& message) {
        QDateTime currentTime = QDateTime::currentDateTime();
        QString alarmMessage = QString("[%1] %2: %3")
                              .arg(currentTime.toString("yyyy-MM-dd hh:mm:ss"))
                              .arg(title)
                              .arg(message);
        
        alarmLog->append(alarmMessage);
        
        // 在状态栏显示最新报警
        statusBar()->showMessage(alarmMessage, 5000);
    }

    void updateCharts(const SafetyData& data) {
        // 更新烟雾浓度图表
        QDateTime currentTime = QDateTime::currentDateTime();
        smokeSeries->append(currentTime.toMSecsSinceEpoch(), data.smoke_level);
        
        // 更新噪声水平图表
        noiseSeries->append(currentTime.toMSecsSinceEpoch(), data.noise_level);
        
        // 限制数据点数量
        if (smokeSeries->count() > 100) {
            smokeSeries->remove(0);
            noiseSeries->remove(0);
        }
        
        // 更新图表范围
        updateChartAxes();
    }

    void updateChartAxes() {
        // 自动调整Y轴范围
        auto smokeAxisY = qobject_cast<QValueAxis*>(smokeChart->axes(Qt::Vertical).first());
        auto noiseAxisY = qobject_cast<QValueAxis*>(noiseChart->axes(Qt::Vertical).first());
        
        if (smokeSeries->count() > 0) {
            qreal maxSmoke = 0;
            for (int i = 0; i < smokeSeries->count(); ++i) {
                maxSmoke = qMax(maxSmoke, smokeSeries->at(i).y());
            }
            smokeAxisY->setRange(0, qMax(100.0, maxSmoke * 1.1));
        }
        
        if (noiseSeries->count() > 0) {
            qreal maxNoise = 0;
            for (int i = 0; i < noiseSeries->count(); ++i) {
                maxNoise = qMax(maxNoise, noiseSeries->at(i).y());
            }
            noiseAxisY->setRange(0, qMax(120.0, maxNoise * 1.1));
        }
    }

    void logData(const SafetyData& data) {
        QFile file("safety_log.csv");
        if (file.open(QIODevice::Append | QIODevice::Text)) {
            QTextStream out(&file);
            QDateTime timestamp = QDateTime::fromSecsSinceEpoch(data.timestamp);
            
            out << timestamp.toString("yyyy-MM-dd hh:mm:ss") << ","
                << data.smoke_level << ","
                << data.noise_level << ","
                << data.safety_status << ","
                << data.violation_type << "\n";
        }
    }

private:
    void setupUI() {
        setWindowTitle("智能车间生产安全监控系统");
        setMinimumSize(1200, 800);
        
        // 创建中心部件
        QWidget *centralWidget = new QWidget(this);
        setCentralWidget(centralWidget);
        
        // 创建主布局
        QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
        
        // 创建标签页
        QTabWidget *tabWidget = new QTabWidget(this);
        mainLayout->addWidget(tabWidget);
        
        // 监控页面
        QWidget *monitorTab = createMonitorTab();
        tabWidget->addTab(monitorTab, "实时监控");
        
        // 数据页面
        QWidget *dataTab = createDataTab();
        tabWidget->addTab(dataTab, "数据分析");
        
        // 设置页面
        QWidget *settingsTab = createSettingsTab();
        tabWidget->addTab(settingsTab, "系统设置");
    }

    QWidget* createMonitorTab() {
        QWidget *tab = new QWidget();
        QGridLayout *layout = new QGridLayout(tab);
        
        // 环境监控组
        QGroupBox *envGroup = new QGroupBox("环境监控");
        QGridLayout *envLayout = new QGridLayout(envGroup);
        
        envLayout->addWidget(new QLabel("烟雾浓度:"), 0, 0);
        smokeValue = new QLabel("0.0");
        envLayout->addWidget(smokeValue, 0, 1);
        smokeProgress = new QProgressBar();
        smokeProgress->setRange(0, 100);
        envLayout->addWidget(smokeProgress, 0, 2);
        
        envLayout->addWidget(new QLabel("噪声水平:"), 1, 0);
        noiseValue = new QLabel("0.0");
        envLayout->addWidget(noiseValue, 1, 1);
        noiseProgress = new QProgressBar();
        noiseProgress->setRange(0, 120);
        envLayout->addWidget(noiseProgress, 1, 2);
        
        envLayout->addWidget(new QLabel("安全状态:"), 2, 0);
        safetyStatus = new QLabel("正常");
        envLayout->addWidget(safetyStatus, 2, 1);
        
        layout->addWidget(envGroup, 0, 0);
        
        // 违规信息组
        QGroupBox *violationGroup = new QGroupBox("违规检测");
        QVBoxLayout *violationLayout = new QVBoxLayout(violationGroup);
        
        violationInfo = new QLabel("无违规行为");
        violationLayout->addWidget(violationInfo);
        
        layout->addWidget(violationGroup, 0, 1);
        
        // 报警日志组
        QGroupBox *alarmGroup = new QGroupBox("报警日志");
        QVBoxLayout *alarmLayout = new QVBoxLayout(alarmGroup);
        
        alarmLog = new QTextEdit();
        alarmLog->setReadOnly(true);
        alarmLayout->addWidget(alarmLog);
        
        layout->addWidget(alarmGroup, 1, 0, 1, 2);
        
        return tab;
    }

    QWidget* createDataTab() {
        QWidget *tab = new QWidget();
        QVBoxLayout *layout = new QVBoxLayout(tab);
        
        // 创建图表视图
        QChartView *smokeChartView = new QChartView();
        smokeChartView->setRenderHint(QPainter::Antialiasing);
        layout->addWidget(new QLabel("烟雾浓度趋势"));
        layout->addWidget(smokeChartView);
        
        QChartView *noiseChartView = new QChartView();
        noiseChartView->setRenderHint(QPainter::Antialiasing);
        layout->addWidget(new QLabel("噪声水平趋势"));
        layout->addWidget(noiseChartView);
        
        smokeChart = smokeChartView->chart();
        noiseChart = noiseChartView->chart();
        
        return tab;
    }

    QWidget* createSettingsTab() {
        QWidget *tab = new QWidget();
        QVBoxLayout *layout = new QVBoxLayout(tab);
        
        QPushButton *connectBtn = new QPushButton("连接设备");
        layout->addWidget(connectBtn);
        
        connect(connectBtn, &QPushButton::clicked, this, &SafetyMonitor::connectToDevice);
        
        return tab;
    }

    void setupConnections() {
        socket = new QTcpSocket(this);
        connect(socket, &QTcpSocket::connected, this, []() {
            qDebug() << "Connected to device";
        });
        connect(socket, &QTcpSocket::readyRead, this, &SafetyMonitor::readData);
        connect(socket, &QTcpSocket::errorOccurred, this, [](QAbstractSocket::SocketError error) {
            qDebug() << "Socket error:" << error;
        });
    }

    void setupChart() {
        // 设置烟雾浓度图表
        smokeSeries = new QLineSeries();
        smokeChart->addSeries(smokeSeries);
        smokeChart->setTitle("烟雾浓度监控");
        
        QDateTimeAxis *axisX = new QDateTimeAxis();
        axisX->setFormat("hh:mm:ss");
        smokeChart->addAxis(axisX, Qt::AlignBottom);
        smokeSeries->attachAxis(axisX);
        
        QValueAxis *axisY = new QValueAxis();
        axisY->setTitleText("浓度");
        smokeChart->addAxis(axisY, Qt::AlignLeft);
        smokeSeries->attachAxis(axisY);
        
        // 设置噪声水平图表
        noiseSeries = new QLineSeries();
        noiseChart->addSeries(noiseSeries);
        noiseChart->setTitle("噪声水平监控");
        
        QDateTimeAxis *noiseAxisX = new QDateTimeAxis();
        noiseAxisX->setFormat("hh:mm:ss");
        noiseChart->addAxis(noiseAxisX, Qt::AlignBottom);
        noiseSeries->attachAxis(noiseAxisX);
        
        QValueAxis *noiseAxisY = new QValueAxis();
        noiseAxisY->setTitleText("分贝(dB)");
        noiseChart->addAxis(noiseAxisY, Qt::AlignLeft);
        noiseSeries->attachAxis(noiseAxisY);
    }

    void startMonitoring() {
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, [this]() {
            updateChartAxes();
        });
        timer->start(1000); // 每秒更新一次图表
    }

    // UI组件
    QLabel *smokeValue;
    QLabel *noiseValue;
    QLabel *safetyStatus;
    QLabel *violationInfo;
    QProgressBar *smokeProgress;
    QProgressBar *noiseProgress;
    QTextEdit *alarmLog;
    
    // 图表组件
    QChart *smokeChart;
    QChart *noiseChart;
    QLineSeries *smokeSeries;
    QLineSeries *noiseSeries;
    
    // 网络组件
    QTcpSocket *socket;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    SafetyMonitor monitor;
    monitor.show();
    
    return app.exec();
}

#include "main.moc"

这个上位机代码实现了以下功能:

  1. 实时监控界面

    • 显示烟雾浓度和噪声水平的实时数值和进度条
    • 显示安全状态和违规检测信息
    • 报警日志记录
  2. 数据分析界面

    • 使用Qt Charts显示烟雾浓度和噪声水平的历史趋势图
    • 实时更新图表数据
  3. 网络通信

    • 通过TCP协议与STM32设备通信
    • 解析安全监控数据包
  4. 数据记录

    • 将监控数据保存到CSV文件
    • 记录报警信息
  5. 报警功能

    • 烟雾浓度超标报警
    • 噪声水平超标报警
    • 安全违规行为报警

代码采用模块化设计,便于维护和扩展,可以根据实际需求进一步添加更多功能。

模块代码设计

#include "stm32f10x.h"

// 系统时钟初始化
void SystemClock_Config(void) {
    // 开启HSE
    RCC->CR |= RCC_CR_HSEON;
    while(!(RCC->CR & RCC_CR_HSERDY));
    
    // 配置PLL 8MHz * 9 = 72MHz
    RCC->CFGR |= RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC;
    
    // 开启PLL
    RCC->CR |= RCC_CR_PLLON;
    while(!(RCC->CR & RCC_CR_PLLRDY));
    
    // 设置FLASH预取指和等待状态
    FLASH->ACR |= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1;
    
    // 切换系统时钟到PLL
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
    
    // 设置AHB、APB1、APB2分频
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV1;
}

// GPIO初始化
void GPIO_Config(void) {
    // 开启GPIO时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
    
    // OV7670控制引脚 PB12-SIOC, PB13-SIOD
    GPIOB->CRH &= ~(GPIO_CRH_CNF12 | GPIO_CRH_MODE12 | GPIO_CRH_CNF13 | GPIO_CRH_MODE13);
    GPIOB->CRH |= GPIO_CRH_CNF12_1 | GPIO_CRH_MODE12_0 | GPIO_CRH_CNF13_1 | GPIO_CRH_MODE13_0;
    
    // 传感器数据引脚 PA0-7
    GPIOA->CRL = 0x88888888; // 输入模式
    
    // 报警LED PC13
    GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);
    GPIOC->CRH |= GPIO_CRH_MODE13_1;
}

// USART1初始化 (ESP8266通信)
void USART1_Config(void) {
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    
    // PA9-TX, PA10-RX
    GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
    GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_CNF10_0;
    
    USART1->BRR = 72000000 / 115200; // 115200波特率
    USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}

// ADC初始化 (MQ-2和噪声传感器)
void ADC_Config(void) {
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
    
    // PA1-MQ2, PA2-噪声传感器
    GPIOA->CRL &= ~(GPIO_CRL_CNF1 | GPIO_CRL_MODE1 | GPIO_CRL_CNF2 | GPIO_CRL_MODE2);
    GPIOA->CRL |= GPIO_CRL_MODE1_0 | GPIO_CRL_MODE2_0;
    
    ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CONT;
    ADC1->SQR1 = 0; // 1个转换
    ADC1->SQR3 = 1; // 通道1
}

// I2C模拟 (OV7670 SCCB通信)
void I2C_Delay(void) {
    for(volatile int i=0; i<10; i++);
}

void I2C_Start(void) {
    GPIOB->BSRR = GPIO_BSRR_BS13; // SIOD高
    GPIOB->BSRR = GPIO_BSRR_BS12; // SIOC高
    I2C_Delay();
    GPIOB->BRR = GPIO_BRR_BR13;   // SIOD低
    I2C_Delay();
    GPIOB->BRR = GPIO_BRR_BR12;   // SIOC低
}

void I2C_Stop(void) {
    GPIOB->BRR = GPIO_BRR_BR13;   // SIOD低
    GPIOB->BSRR = GPIO_BSRR_BS12; // SIOC高
    I2C_Delay();
    GPIOB->BSRR = GPIO_BSRR_BS13; // SIOD高
}

uint8_t I2C_WriteByte(uint8_t data) {
    for(int i=0; i<8; i++) {
        if(data & 0x80) 
            GPIOB->BSRR = GPIO_BSRR_BS13;
        else 
            GPIOB->BRR = GPIO_BRR_BR13;
        I2C_Delay();
        GPIOB->BSRR = GPIO_BSRR_BS12; // SIOC高
        I2C_Delay();
        GPIOB->BRR = GPIO_BRR_BR12;   // SIOC低
        data <<= 1;
    }
    
    // 等待ACK
    GPIOB->CRH |= GPIO_CRH_CNF13_0; // 输入模式
    GPIOB->BSRR = GPIO_BSRR_BS12;   // SIOC高
    I2C_Delay();
    uint8_t ack = (GPIOB->IDR & GPIO_IDR_IDR13) ? 0 : 1;
    GPIOB->BRR = GPIO_BRR_BR12;     // SIOC低
    GPIOB->CRH &= ~GPIO_CRH_CNF13;  // 输出模式
    GPIOB->BRR = GPIO_BRR_BR13;     // SIOD低
    
    return ack;
}

// OV7670初始化
void OV7670_Init(void) {
    I2C_Start();
    I2C_WriteByte(0x42); // OV7670写地址
    I2C_WriteByte(0x12); // COM7
    I2C_WriteByte(0x80); // 复位
    I2C_Stop();
    
    Delay_ms(10);
    
    // 配置常用寄存器
    uint8_t regs[][2] = {
        {0x12, 0x04}, // COM7 - RGB输出
        {0x40, 0xD0}, // COM15 - RGB565
        {0x11, 0x80}, // CLKRC - 内部时钟
        {0x0C, 0x00}, // COM3 - 默认
        {0x3E, 0x00}, // COM14 - 默认
        {0x04, 0x00}, // COM1 - 默认
        {0x15, 0x02}, // COM10 - VSYNC负极性
    };
    
    for(int i=0; i<sizeof(regs)/2; i++) {
        I2C_Start();
        I2C_WriteByte(0x42);
        I2C_WriteByte(regs[i][0]);
        I2C_WriteByte(regs[i][1]);
        I2C_Stop();
        Delay_ms(1);
    }
}

// 读取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;
}

// 读取MQ-2烟雾值
uint16_t MQ2_Read(void) {
    return ADC_Read(1);
}

// 读取噪声值
uint16_t Noise_Read(void) {
    return ADC_Read(2);
}

// USART发送数据
void USART_SendString(char *str) {
    while(*str) {
        while(!(USART1->SR & USART_SR_TXE));
        USART1->DR = *str++;
    }
}

// 华为云通信
void HuaweiCloud_Send(float smoke, float noise, uint8_t safety_status) {
    char buffer[128];
    sprintf(buffer, "{\"smoke\":%.2f,\"noise\":%.2f,\"safety\":%d}\r\n", 
            smoke, noise, safety_status);
    USART_SendString(buffer);
}

// 图像处理安全检测
uint8_t Safety_Detection(void) {
    // 简单的安全帽检测逻辑
    uint32_t pixel_count = 0;
    uint32_t yellow_count = 0;
    
    // 模拟图像处理 (实际需要复杂的图像算法)
    for(int i=0; i<100; i++) {
        uint16_t pixel = GPIOA->IDR & 0xFF; // 读取像素数据
        // 简单的黄色检测 (RGB值范围判断)
        if((pixel & 0xF800) > 0xD000 && (pixel & 0x07E0) > 0x0600) {
            yellow_count++;
        }
        pixel_count++;
    }
    
    // 如果黄色像素比例超过阈值,认为佩戴安全帽
    return (yellow_count * 100 / pixel_count) > 20;
}

// 延时函数
void Delay_ms(uint32_t ms) {
    for(uint32_t i=0; i<ms*8000; i++);
}

int main(void) {
    SystemClock_Config();
    GPIO_Config();
    USART1_Config();
    ADC_Config();
    OV7670_Init();
    
    while(1) {
        // 读取传感器数据
        uint16_t smoke_value = MQ2_Read();
        uint16_t noise_value = Noise_Read();
        
        // 转换为实际值
        float smoke_ppm = smoke_value * 0.1f;
        float noise_db = noise_value * 0.08f;
        
        // 安全检测
        uint8_t helmet_detected = Safety_Detection();
        uint8_t safety_status = helmet_detected ? 1 : 0;
        
        // 烟雾报警
        if(smoke_ppm > 50.0f) {
            GPIOC->BSRR = GPIO_BSRR_BS13; // LED亮
            safety_status = 0;
        } else {
            GPIOC->BRR = GPIO_BRR_BR13;   // LED灭
        }
        
        // 噪声报警
        if(noise_db > 85.0f) {
            safety_status = 0;
        }
        
        // 发送到华为云
        HuaweiCloud_Send(smoke_ppm, noise_db, safety_status);
        
        Delay_ms(1000); // 1秒间隔
    }
}

项目核心代码

#include "stm32f10x.h"

// 假设外部模块函数已定义
extern void Camera_Init(void);
extern void Camera_Process(void);
extern uint8_t Detect_Safety_Violation(void);
extern void WiFi_Init(void);
extern void WiFi_Send_Data(uint8_t* data, uint32_t len);

// 定义引脚和寄存器地址
#define LED_PIN    GPIO_Pin_13  // PC13 for LED
#define LED_PORT   GPIOC

#define SMOKE_ADC_CH    ADC_Channel_0  // PA0 for MQ-2
#define NOISE_ADC_CH    ADC_Channel_1  // PA1 for noise sensor

// 报警阈值
#define SMOKE_THRESHOLD  500   // ADC value for smoke detection
#define NOISE_THRESHOLD  700   // ADC value for noise level

// 函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void ADC1_Configuration(void);
void USART1_Configuration(void);
void NVIC_Configuration(void);
uint16_t ADC_Read(uint8_t channel);
void Delay_ms(uint32_t nTime);

// 全局变量
volatile uint32_t TimingDelay = 0;

int main(void) {
    // 系统初始化
    RCC_Configuration();
    GPIO_Configuration();
    ADC1_Configuration();
    USART1_Configuration();
    NVIC_Configuration();
    
    // 外设初始化
    Camera_Init();
    WiFi_Init();
    
    // 主循环
    while (1) {
        uint16_t smoke_value, noise_value;
        uint8_t violation_detected = 0;
        uint8_t alert_data[50];
        uint32_t data_len = 0;
        
        // 读取传感器数据
        smoke_value = ADC_Read(SMOKE_ADC_CH);
        noise_value = ADC_Read(NOISE_ADC_CH);
        
        // 处理摄像头数据
        Camera_Process();
        violation_detected = Detect_Safety_Violation();
        
        // 检查报警条件
        if (smoke_value > SMOKE_THRESHOLD || noise_value > NOISE_THRESHOLD || violation_detected) {
            GPIO_WriteBit(LED_PORT, LED_PIN, Bit_SET);  // 打开LED报警
            
            // 构建报警数据
            data_len = sprintf((char*)alert_data, 
                "Alert: Smoke=%u, Noise=%u, Violation=%u", 
                smoke_value, noise_value, violation_detected);
            
            // 通过WiFi发送报警数据
            WiFi_Send_Data(alert_data, data_len);
        } else {
            GPIO_WriteBit(LED_PORT, LED_PIN, Bit_RESET);  // 关闭LED
        }
        
        // 发送常规监控数据
        uint8_t monitor_data[50];
        data_len = sprintf((char*)monitor_data, 
            "Monitor: Smoke=%u, Noise=%u", smoke_value, noise_value);
        WiFi_Send_Data(monitor_data, data_len);
        
        Delay_ms(1000);  // 每秒检测一次
    }
}

// 系统时钟配置
void RCC_Configuration(void) {
    // 开启HSI时钟
    RCC->CR |= RCC_CR_HSION;
    while (!(RCC->CR & RCC_CR_HSIRDY));
    
    // 设置AHB、APB1、APB2时钟
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;   // AHB不分频
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV1;  // APB1不分频
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;  // APB2不分频
    
    // 开启外设时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | 
                    RCC_APB2ENR_ADC1EN | RCC_APB2ENR_USART1EN;
}

// GPIO配置
void GPIO_Configuration(void) {
    // 配置LED引脚(PC13)为推挽输出
    GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);
    GPIOC->CRH |= GPIO_CRH_MODE13_0;  // 输出模式,最大速度10MHz
    
    // 配置ADC引脚(PA0, PA1)为模拟输入
    GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_MODE0 | 
                    GPIO_CRL_CNF1 | GPIO_CRL_MODE1);
    
    // 配置USART1引脚(PA9-TX, PA10-RX)
    GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | 
                    GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
    GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0;  // PA9: 复用推挽输出
    GPIOA->CRH |= GPIO_CRH_CNF10_0;                    // PA10: 浮空输入
}

// ADC1配置
void ADC1_Configuration(void) {
    // 校准ADC
    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);
    
    // 配置ADC
    ADC1->CR1 &= ~ADC_CR1_SCAN;    // 单通道模式
    ADC1->CR2 &= ~ADC_CR2_CONT;    // 单次转换模式
    ADC1->CR2 |= ADC_CR2_ALIGN;    // 数据右对齐
    
    // 设置采样时间
    ADC1->SMPR2 |= ADC_SMPR2_SMP0_0 | ADC_SMPR2_SMP0_1 |  // 通道0: 71.5周期
                   ADC_SMPR2_SMP1_0 | ADC_SMPR2_SMP1_1;   // 通道1: 71.5周期
}

// USART1配置
void USART1_Configuration(void) {
    // 配置波特率 9600 @8MHz
    USART1->BRR = 0x0341;  // 8MHz / 9600 = 833.33 -> 0x341
    
    USART1->CR1 |= USART_CR1_UE;    // 使能USART
    USART1->CR1 |= USART_CR1_TE;    // 使能发送
    USART1->CR1 &= ~USART_CR1_M;    // 8数据位
    USART1->CR2 &= ~USART_CR2_STOP; // 1停止位
}

// NVIC配置
void NVIC_Configuration(void) {
    NVIC->ISER[0] |= 1 << USART1_IRQn;  // 使能USART1中断
}

// ADC读取函数
uint16_t ADC_Read(uint8_t channel) {
    ADC1->SQR3 = channel;           // 设置通道
    ADC1->CR2 |= ADC_CR2_ADON;      // 开启转换
    ADC1->CR2 |= ADC_CR2_SWSTART;   // 开始转换
    while (!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成
    return ADC1->DR;                // 返回转换值
}

// 简单延时函数
void Delay_ms(uint32_t nTime) {
    TimingDelay = nTime;
    while (TimingDelay != 0);
}

// SysTick中断处理函数
void SysTick_Handler(void) {
    if (TimingDelay != 0) TimingDelay--;
}

总结

本系统基于STM32微控制器设计,旨在构建一个高效、智能的车间生产安全监控平台。通过集成多种传感器和通信模块,系统能够实时监测车间环境安全参数,如烟雾浓度和噪声水平,并利用摄像头模块识别人员安全行为,及时发出违规报警,有效预防生产事故的发生。

硬件实现上,系统以STM32F103C8T6最小系统板为核心控制器,搭配OV7670摄像头进行图像采集和行为分析,MQ-2烟雾传感器检测火灾风险,噪声传感器评估环境噪声,并通过ESP8266 Wi-Fi模块实现与华为云的数据通信。图像处理电路通过洞洞板焊接,各传感器通过杜邦线灵活连接,确保了系统的稳定性和可扩展性。

总体而言,该系统不仅实现了安全生产数据的实时记录和分析,还通过QT上位机界面直观展示监控画面和预警信息,显著提升了车间安全管理的智能化水平和响应效率,为现代工业安全生产提供了可靠的技术支持。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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