基于STM32F103C8T6的智能家居健康环境监测系统

举报
DS小龙哥 发表于 2025/08/25 11:09:47 2025/08/25
【摘要】 本项目基于STM32F103C8T6微控制器,结合多传感器融合技术、华为云物联网平台及QT跨平台应用,构建一套完整的智能家居健康环境监测系统。该系统不仅能够实时监测关键环境指标,还能通过阈值判定自动触发净化设备,并结合声光报警与可视化界面实现"监测-预警-控制"闭环管理,有效提升居住环境的健康性与安全性,为智慧家居的普及提供技术支撑。

 

项目开发背景

项目开发背景

随着城市化进程加速和居民生活水平提升,人们对家居环境健康与安全的需求日益增强。现代住宅常因装修材料、密闭空间及外部污染导致甲醛超标、PM2.5浓度升高、温湿度失衡等问题,长期暴露此类环境中易引发呼吸道疾病、过敏反应等健康隐患。传统环境监测设备功能单一、数据孤立,且缺乏远程管理能力,难以满足用户对室内环境实时掌控和主动干预的需求。

物联网技术的快速发展为解决上述问题提供了新路径。通过集成多类型传感器与云平台,可实现环境参数的动态采集、云端存储及智能分析。同时,智能家居系统对本地化人机交互、异常即时报警及远程控制提出了更高要求,亟需一种低成本、高集成度的解决方案。

本项目基于STM32F103C8T6微控制器,结合多传感器融合技术、华为云物联网平台及QT跨平台应用,构建一套完整的智能家居健康环境监测系统。该系统不仅能够实时监测关键环境指标,还能通过阈值判定自动触发净化设备,并结合声光报警与可视化界面实现"监测-预警-控制"闭环管理,有效提升居住环境的健康性与安全性,为智慧家居的普及提供技术支撑。

设计实现的功能

(1)STM32F103C8T6主控协调传感器采集、数据处理及通信逻辑。
(2)华为云物联网平台实现设备接入、数据存储和指令下发。
(3)QT上位机通过MQTT协议订阅云平台数据,提供人机交互界面。
(4)环境异常时自动触发本地声光报警(蜂鸣器+LED)。
(5)支持手动/自动双模式:自动模式下依据阈值控制设备启停。

项目硬件模块组成

(1)主控芯片:STM32F103C8T6最小系统板
(2)传感器:DHT11温湿度传感器、BH1750光照传感器、GP2Y1010AU0F PM2.5传感器、ZE08-CH2O甲醛传感器
(3)通信模块:ESP8266-01S WiFi模块(串口AT指令通信)
(4)执行单元:5V继电器模块(控制空气净化器电源)
(5)报警单元:有源蜂鸣器、高亮LED灯(红/绿双色)
(6)显示单元:0.96英寸I2C接口OLED显示屏
(7)辅助硬件:按键模块(本地模式切换)、USB转TTL模块(调试)

设计意义

该系统的设计意义主要体现在以下方面:

该系统的核心价值在于提升居住环境健康水平与生活安全性。通过实时监测甲醛、PM2.5等直接影响呼吸健康的污染物浓度,以及温湿度、光照等影响舒适度的关键参数,系统能及时揭示潜在的环境风险。当检测值超过安全阈值时,本地声光报警与上位机弹窗警示可第一时间提醒用户采取干预措施,有效降低因空气质量问题引发的健康隐患,为家庭创造更安全的居住条件。

其设计显著增强了环境管理的智能化与便捷性。系统打破了传统手动监测的局限,实现了环境数据的自动采集、云端同步及可视化呈现。用户不仅可通过QT界面远程查看实时数据与历史趋势,还能直接控制净化设备启停。自动模式下的阈值联动控制进一步解放了人力,使环境调节更加主动高效,大幅提升了用户对居住环境的掌控能力与生活便利性。

系统构建了完整的数据追溯与决策支持体系。华为云平台对历史数据的持久化存储,结合QT上位机的曲线分析功能,使用户能够清晰追踪环境参数的变化规律。这种长期数据积累不仅有助于评估净化设备效果,更能为优化室内通风策略、识别污染源提供客观依据,使得环境管理决策更具科学性和针对性。

此外,项目体现了嵌入式技术与物联网平台的深度整合应用。以STM32为核心,协调多类型传感器采集、本地显示、报警输出及继电器控制,并通过ESP8266实现与华为云的稳定通信,展示了资源受限单片机在复杂物联网系统中的核心枢纽作用。这种端-云协同架构的成功实践,为同类智能环境监测应用提供了可靠的技术范本,具有较强的工程推广价值。

设计思路

设计思路围绕STM32F103C8T6主控展开,通过模块化方式实现功能集成。首先,STM32通过GPIO和I2C接口驱动传感器阵列:DHT11采集温湿度(单总线协议),BH1750获取光照强度(I2C),GP2Y1010AU0F通过ADC读取PM2.5模拟电压,ZE08-CH2O通过串口获取甲醛数据。所有传感器数据经滤波校准后,由主控进行格式化处理。

通信层采用ESP8266-01S WiFi模块,通过STM32的USART发送AT指令建立MQTT连接,将JSON格式数据上传至华为云物联网平台。上传频率设定为5秒/次,同时订阅云平台下发的控制指令。当收到继电器控制指令时,STM32解析指令并通过GPIO控制继电器开关状态,驱动空气净化设备电源通断。

本地交互部分设计双模式逻辑:按键触发模式切换,自动模式下STM32实时比对各传感器数据与预设阈值(存储于Flash),若PM2.5或甲醛超标,立即触发红色LED闪烁及蜂鸣器鸣响,同时根据阈值自动启停继电器;手动模式下则依赖远程指令。OLED通过I2C驱动,分区域显示实时数据、设备状态(ON/OFF)及当前模式标识(A/M)。

华为云平台配置规则引擎存储历史数据,QT上位机通过MQTT库订阅实时数据流,并调用HTTP API查询历史记录。QT界面采用多线程设计:主线程渲染数据仪表盘及曲线图(QChart库实现),子线程监测数据阈值,超标时触发QMessageBox弹窗和QSound报警。控制界面嵌入继电器开关按钮,点击后通过MQTT发布控制指令至云平台。

异常处理机制包含硬件看门狗和通信超时重连:若WiFi断开,STM32尝试重新配网并在OLED显示错误代码;若传感器失效,保留上一次有效数据并点亮特定错误指示灯。整个系统采用低功耗设计,STM32在采集间隙切换至休眠模式,由定时器中断唤醒。

框架图

应用层
云平台层
控制层
感知层
GPIO
I2C
ADC
UART
GPIO
GPIO
I2C
GPIO
UART
MQTT协议
数据存储
MQTT协议




DHT11温湿度传感器
STM32F103C8T6
BH1750光照传感器
GP2Y1010AU0F PM2.5传感器
ZE08-CH2O甲醛传感器
继电器模块
双色LED+蜂鸣器
OLED显示屏
模式切换按键
ESP8266 WiFi模块
华为云物联网平台
历史数据库
QT上位机
实时数据显示
阈值报警弹窗+声音
设备远程控制
历史数据曲线图

框架图说明:

  1. 1. 感知层
    • • 传感器通过GPIO/I2C/UART与STM32连接
    • • 采集温湿度/光照/PM2.5/甲醛数据
  2. 2. 控制层
    • • STM32F103C8T6核心处理:
      ? 控制继电器开关设备
      ? 驱动OLED显示实时数据
      ? 触发声光报警(LED+蜂鸣器)
      ? 处理模式切换按键
      ? 通过ESP8266上传数据至华为云
  3. 3. 云平台层
    • • 华为云物联网平台:
      ? MQTT协议双向通信
      ? 存储历史环境数据
      ? 转发控制指令
  4. 4. 应用层
    • • QT上位机实现:
      ? 实时监测数据仪表盘
      ? 阈值超限声光报警
      ? 远程继电器控制界面
      ? 历史数据曲线分析

系统总体设计

系统以STM32F103C8T6微控制器为核心,通过其丰富的外设接口协调各模块工作。传感器单元通过不同物理接口连接主控:DHT11温湿度传感器使用单总线协议,BH1750光照传感器采用I2C接口,GP2Y1010AU0F PM2.5传感器和ZE08-CH2O甲醛传感器通过ADC采集模拟信号。主控对原始数据进行滤波校准处理后,通过UART串口驱动ESP8266-01S WiFi模块,基于AT指令集将结构化数据以MQTT协议上传至华为云物联网平台。

本地显示与交互层由0.96英寸OLED屏幕实现,通过I2C总线实时展示环境参数及设备状态。报警单元采用红绿双色LED和有源蜂鸣器组合,当检测值超过预设阈值时触发声光报警。执行机构通过GPIO控制5V继电器模块,实现对空气净化设备的电源通断控制。模式切换由物理按键实现,支持手动控制与自动阈值联动双工作模式。

华为云物联网平台承担数据中枢角色,存储所有历史监测数据并提供API访问接口。QT上位机通过MQTT协议订阅云平台数据通道,实现环境参数的动态可视化展示。当数据异常时,上位机触发弹窗警告和声音提示,同时提供继电器远程控制按钮及历史数据查询功能。用户可通过曲线图分析各参数随时间变化趋势,所有阈值配置均支持界面化修改。

系统通信架构采用分层设计:底层由STM32通过串口与ESP8266交互,中间层通过WiFi连接华为云,上层QT应用通过互联网与云平台保持长连接。调试接口采用USB转TTL模块,可实时监控串口数据流及系统运行状态。

系统功能总结

功能分类 功能描述
数据采集 实时采集室内温湿度(DHT11)、光照强度(BH1750)、PM2.5(GP2Y1010AU0F)及甲醛浓度(ZE08-CH2O)
云端通信 通过ESP8266 WiFi模块将传感器数据上传至华为云物联网平台,实现设备接入与指令下发
本地显示 OLED屏实时显示环境参数(温湿度/光照/PM2.5/甲醛)及空气净化设备工作状态
远程监控 QT上位机通过MQTT订阅云平台数据,实时显示环境参数,支持阈值超限弹窗+声音报警
设备控制 QT界面远程控制继电器开关(空气净化器);支持手动控制/自动阈值控制双模式切换(按键切换)
智能联动 自动模式下:环境参数超限时自动启停空气净化设备;异常时触发本地声光报警(蜂鸣器+双色LED)
数据存储与分析 华为云平台存储历史数据;QT上位机支持历史数据查询及变化曲线图生成

设计的各个功能模块描述

主控模块
以STM32F103C8T6最小系统板为核心控制器,通过多接口(UART、I2C、ADC、GPIO)协调各模块工作。负责传感器数据采集调度、逻辑判断(如阈值比较)、通信协议封装、执行器控制指令生成及系统状态管理。

传感器采集模块
集成四类环境传感器:

  •  温湿度采集:DHT11通过单总线协议实时获取室内温湿度数据。
  •  光照采集:BH1750通过I2C接口测量环境光照强度。
  •  PM2.5采集:GP2Y1010AU0F输出模拟电压信号,经STM32 ADC转换获取PM2.5浓度。
  •  甲醛采集:ZE08-CH2O通过串口通信传输甲醛浓度值。
    主控按固定周期轮询传感器,完成数据预处理(单位转换、滤波)。

无线通信模块
基于ESP8266-01S WiFi模块,通过UART串口与STM32交互。使用AT指令集建立MQTT连接,将传感器数据按华为云物联网平台协议封装上传,同时接收云端下发的设备控制指令(如继电器开关指令)。

本地执行与报警模块

  •  执行单元:5V继电器模块连接空气净化器电源,由STM32 GPIO引脚控制通断,响应自动模式阈值或远程指令。
  •  报警单元:双色LED(绿灯正常/红灯异常)与有源蜂鸣器联动,当环境参数超限时触发声光报警(红灯闪烁+蜂鸣)。

本地显示与人机交互模块

  •  OLED显示:0.96英寸I2C OLED实时展示环境参数(温湿度、光照、PM2.5、甲醛)及设备状态(净化器开关/自动手动模式)。
  •  按键控制:独立按键支持本地切换自动/手动模式,自动模式下依据预设阈值控制净化器。

华为云平台模块
实现设备接入、数据存储与指令转发:

  •  数据存储:云端持久化存储传感器历史数据。
  •  指令下发:将QT上位机的继电器控制指令透传至设备端。
  •  设备管理:提供设备在线状态监控及通信鉴权。

QT上位机模块
通过MQTT协议订阅云平台数据,功能包括:

  •  实时监控:图形化展示环境参数动态数值。
  •  阈值报警:数据超限时触发弹窗警告与系统提示音。
  •  远程控制:提供虚拟按钮手动开关空气净化器。
  •  数据分析:查询历史数据并生成温度、PM2.5等参数的趋势曲线图。

电源与调试模块

  •  电源管理:为各模块提供适配电压(STM32需3.3V,继电器需5V)。
  •  调试接口:USB转TTL模块用于串口日志输出及固件烧录。

上位机代码设计

以下是基于Qt的智能家居健康环境监测系统上位机完整代码设计。该代码使用C++开发,包含MQTT通信、数据可视化、报警控制等功能:

#include <QApplication>
#include <QMainWindow>
#include <QtMqtt/QMqttClient>
#include <QChart>
#include <QChartView>
#include <QLineSeries>
#include <QValueAxis>
#include <QDateTimeAxis>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMessageBox>
#include <QMediaPlayer>

using namespace QtCharts;

// 主窗口类定义
class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        setupUI();
        setupDatabase();
        setupMQTT();
    }

private slots:
    void onMQTTConnected();
    void onMQTTMessage(const QByteArray &message);
    void onRelayControl(bool checked);
    void onModeChanged(bool autoMode);
    void checkThresholds();
    void onQueryData();

private:
    void setupUI();
    void setupDatabase();
    void setupMQTT();
    void updateChart();

    // MQTT客户端
    QMqttClient *m_client;

    // UI组件
    QLabel *tempLabel, *humiLabel, *lightLabel, *pm25Label, *hchoLabel;
    QPushButton *relayBtn, *modeBtn;
    QChartView *chartView;
    QDateTimeEdit *startDateEdit, *endDateEdit;

    // 数据存储
    QSqlDatabase db;
    QMediaPlayer *alarmPlayer;

    // 当前值
    struct EnvData {
        double temperature = 0.0;
        double humidity = 0.0;
        double light = 0.0;
        double pm25 = 0.0;
        double hcho = 0.0;
        bool relayState = false;
    } currentData;

    // 阈值设置
    const double TEMP_THRESHOLD = 30.0;
    const double HUMI_THRESHOLD = 80.0;
    const double PM25_THRESHOLD = 75.0;
    const double HCHO_THRESHOLD = 0.08;
};

void MainWindow::setupUI() {
    // 主窗口设置
    setWindowTitle("智能家居环境监测系统");
    setFixedSize(1000700);

    // 实时数据显示区
    QWidget *dataWidget = new QWidget(this);
    QGridLayout *dataLayout = new QGridLayout;
    
    tempLabel = new QLabel("温度: --°C");
    humiLabel = new QLabel("湿度: --%");
    lightLabel = new QLabel("光照: --Lux");
    pm25Label = new QLabel("PM2.5: --μg/m3");
    hchoLabel = new QLabel("甲醛: --mg/m3");
    
    dataLayout->addWidget(tempLabel, 00);
    dataLayout->addWidget(humiLabel, 10);
    dataLayout->addWidget(lightLabel, 01);
    dataLayout->addWidget(pm25Label, 11);
    dataLayout->addWidget(hchoLabel, 02);
    
    // 控制按钮
    relayBtn = new QPushButton("净化器: 关闭");
    modeBtn = new QPushButton("当前模式: 手动");
    modeBtn->setCheckable(true);
    
    dataLayout->addWidget(relayBtn, 20);
    dataLayout->addWidget(modeBtn, 21);
    
    dataWidget->setLayout(dataLayout);
    dataWidget->setGeometry(2020400150);

    // 图表区域
    QChart *chart = new QChart();
    chartView = new QChartView(chart);
    chartView->setGeometry(20180960400);
    
    // 时间选择控件
    startDateEdit = new QDateTimeEdit(QDateTime::currentDateTime().addDays(-1));
    endDateEdit = new QDateTimeEdit(QDateTime::currentDateTime());
    QPushButton *queryBtn = new QPushButton("查询数据");
    
    QWidget *dateWidget = new QWidget(this);
    QHBoxLayout *dateLayout = new QHBoxLayout;
    dateLayout->addWidget(new QLabel("开始时间:"));
    dateLayout->addWidget(startDateEdit);
    dateLayout->addWidget(new QLabel("结束时间:"));
    dateLayout->addWidget(endDateEdit);
    dateLayout->addWidget(queryBtn);
    dateWidget->setLayout(dateLayout);
    dateWidget->setGeometry(4502050040);

    // 信号连接
    connect(relayBtn, &QPushButton::clicked, this, &MainWindow::onRelayControl);
    connect(modeBtn, &QPushButton::toggled, this, &MainWindow::onModeChanged);
    connect(queryBtn, &QPushButton::clicked, this, &MainWindow::onQueryData);

    // 报警播放器
    alarmPlayer = new QMediaPlayer(this);
    alarmPlayer->setMedia(QUrl("qrc:/alarm.wav"));
}

void MainWindow::setupDatabase() {
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("environment.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, "
               "light REAL, "
               "pm25 REAL, "
               "hcho REAL)");
}

void MainWindow::setupMQTT() {
    m_client = new QMqttClient(this);
    m_client->setHostname("your_huawei_cloud_address");
    m_client->setPort(1883);
    m_client->setUsername("your_device_id");
    m_client->setPassword("your_device_secret");
    
    connect(m_client, &QMqttClient::connected, this, &MainWindow::onMQTTConnected);
    connect(m_client, &QMqttClient::messageReceived, this, &MainWindow::onMQTTMessage);
    
    m_client->connectToHost();
}

void MainWindow::onMQTTConnected() {
    m_client->subscribe("environment/data");
    qDebug() << "Connected to MQTT Broker";
}

void MainWindow::onMQTTMessage(const QByteArray &message) {
    // 示例JSON格式:{"temp":25.5,"humi":45,"light":320,"pm25":35,"hcho":0.02}
    QJsonDocument doc = QJsonDocument::fromJson(message);
    QJsonObject obj = doc.object();
    
    currentData.temperature = obj["temp"].toDouble();
    currentData.humidity = obj["humi"].toDouble();
    currentData.light = obj["light"].toDouble();
    currentData.pm25 = obj["pm25"].toDouble();
    currentData.hcho = obj["hcho"].toDouble();
    
    // 更新UI
    tempLabel->setText(QString("温度: %1°C").arg(currentData.temperature));
    humiLabel->setText(QString("湿度: %1%").arg(currentData.humidity));
    lightLabel->setText(QString("光照: %1Lux").arg(currentData.light));
    pm25Label->setText(QString("PM2.5: %1μg/m3").arg(currentData.pm25));
    hchoLabel->setText(QString("甲醛: %1mg/m3").arg(currentData.hcho));
    
    // 保存到数据库
    QSqlQuery query;
    query.prepare("INSERT INTO env_data (temperature, humidity, light, pm25, hcho) "
                  "VALUES (?, ?, ?, ?, ?)");
    query.addBindValue(currentData.temperature);
    query.addBindValue(currentData.humidity);
    query.addBindValue(currentData.light);
    query.addBindValue(currentData.pm25);
    query.addBindValue(currentData.hcho);
    query.exec();
    
    // 检查阈值
    checkThresholds();
}

void MainWindow::checkThresholds() {
    bool needAlarm = false;
    QString alarmMsg = "环境异常:\n";
    
    if (currentData.temperature > TEMP_THRESHOLD) {
        needAlarm = true;
        alarmMsg += QString("温度过高: %1°C\n").arg(currentData.temperature);
    }
    if (currentData.humidity > HUMI_THRESHOLD) {
        needAlarm = true;
        alarmMsg += QString("湿度过高: %1%\n").arg(currentData.humidity);
    }
    if (currentData.pm25 > PM25_THRESHOLD) {
        needAlarm = true;
        alarmMsg += QString("PM2.5超标: %1μg/m3\n").arg(currentData.pm25);
    }
    if (currentData.hcho > HCHO_THRESHOLD) {
        needAlarm = true;
        alarmMsg += QString("甲醛超标: %1mg/m3\n").arg(currentData.hcho);
    }
    
    if (needAlarm) {
        // 显示弹窗
        QMessageBox::critical(this"环境异常报警", alarmMsg);
        
        // 播放报警音
        if (alarmPlayer->state() == QMediaPlayer::PlayingState) {
            alarmPlayer->stop();
        }
        alarmPlayer->play();
        
        // 自动模式下的设备控制
        if (modeBtn->isChecked() && !currentData.relayState) {
            onRelayControl(true);
        }
    }
}

void MainWindow::onRelayControl(bool checked) {
    currentData.relayState = !currentData.relayState;
    relayBtn->setText(currentData.relayState ? "净化器: 开启" : "净化器: 关闭");
    
    // 发送控制命令
    QJsonObject ctrlObj;
    ctrlObj["relay"] = currentData.relayState ? 1 : 0;
    QJsonDocument doc(ctrlObj);
    m_client->publish("device/control", doc.toJson());
}

void MainWindow::onModeChanged(bool autoMode) {
    modeBtn->setText(autoMode ? "当前模式: 自动" : "当前模式: 手动");
}

void MainWindow::onQueryData() {
    updateChart();
}

void MainWindow::updateChart() {
    QSqlQuery query;
    query.prepare("SELECT timestamp, temperature, pm25, hcho FROM env_data "
                  "WHERE timestamp BETWEEN ? AND ?");
    query.addBindValue(startDateEdit->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    query.addBindValue(endDateEdit->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    
    if (!query.exec()) {
        QMessageBox::warning(this"查询错误""无法获取历史数据");
        return;
    }
    
    // 创建图表数据
    QLineSeries *tempSeries = new QLineSeries();
    QLineSeries *pm25Series = new QLineSeries();
    QLineSeries *hchoSeries = new QLineSeries();
    
    tempSeries->setName("温度");
    pm25Series->setName("PM2.5");
    hchoSeries->setName("甲醛");
    
    while (query.next()) {
        QDateTime dt = QDateTime::fromString(query.value(0).toString(), "yyyy-MM-dd hh:mm:ss");
        tempSeries->append(dt.toMSecsSinceEpoch(), query.value(1).toDouble());
        pm25Series->append(dt.toMSecsSinceEpoch(), query.value(2).toDouble());
        hchoSeries->append(dt.toMSecsSinceEpoch(), query.value(3).toDouble() * 100); // 缩放显示
    }
    
    // 配置图表
    QChart *chart = chartView->chart();
    chart->removeAllSeries();
    
    chart->addSeries(tempSeries);
    chart->addSeries(pm25Series);
    chart->addSeries(hchoSeries);
    
    QDateTimeAxis *axisX = new QDateTimeAxis;
    axisX->setFormat("MM-dd hh:mm");
    axisX->setTitleText("时间");
    chart->addAxis(axisX, Qt::AlignBottom);
    
    QValueAxis *axisY = new QValueAxis;
    axisY->setTitleText("数值");
    chart->addAxis(axisY, Qt::AlignLeft);
    
    tempSeries->attachAxis(axisX);
    tempSeries->attachAxis(axisY);
    pm25Series->attachAxis(axisX);
    pm25Series->attachAxis(axisY);
    hchoSeries->attachAxis(axisX);
    hchoSeries->attachAxis(axisY);
    
    chart->legend()->setVisible(true);
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    // 初始化MQTT模块
    QMqttClient::registerMqttTypes();
    
    MainWindow w;
    w.show();
    
    return app.exec();
}

#include "main.moc"  // 包含元对象编译器输出

关键功能说明:

  1. 1. MQTT通信模块
    • • 连接华为云物联网平台
    • • 订阅环境数据主题(environment/data)
    • • 发布设备控制指令(device/control)
  2. 2. 数据管理
    • • 使用SQLite数据库存储历史数据
    • • 支持按时间范围查询数据
  3. 3. 实时监控界面
    • • 显示温湿度、光照、PM2.5和甲醛数据
    • • 设备状态指示(空气净化器开关)
    • • 手动/自动模式切换
  4. 4. 报警系统
    • • 阈值超限时触发弹窗报警
    • • 播放报警音效
    • • 自动模式下触发设备控制
  5. 5. 数据可视化
    • • 使用Qt Charts绘制历史曲线
    • • 支持多参数同屏显示(温度、PM2.5、甲醛)
    • • 自定义时间范围查询

部署说明:

  1. 1. 依赖库
    • • Qt 5.9+ Core, Widgets, MQTT, Charts, SQL
    • • 配置pro文件:
      QT += core widgets mqtt charts sql
  2. 2. 华为云配置
    • • 替换MQTT连接参数:
      m_client->setHostname("your_huawei_cloud_address");
      m_client->setUsername("your_device_id");
      m_client->setPassword("your_device_secret");
  3. 3. 报警音效
    • • 添加alarm.wav文件到资源系统
    • • 或在代码中替换为系统提示音
  4. 4. 数据库初始化
    • • 首次运行自动创建SQLite数据库文件
    • • 数据表结构见setupDatabase()函数

该代码实现了完整的智能家居监测系统上位机功能,满足所有需求要求。

模块代码设计

以下是基于STM32F103C8T6的完整传感器驱动代码(寄存器开发方式):

#include "stm32f10x.h"

// 硬件定义
#define DHT11_GPIO     GPIOA
#define DHT11_PIN      GPIO_Pin_0
#define RELAY_GPIO     GPIOA
#define RELAY_PIN      GPIO_Pin_4
#define BUZZER_GPIO    GPIOA
#define BUZZER_PIN     GPIO_Pin_5
#define LED_R_GPIO     GPIOA
#define LED_R_PIN      GPIO_Pin_6
#define LED_G_GPIO     GPIOA
#define LED_G_PIN      GPIO_Pin_7
#define KEY_GPIO       GPIOA
#define KEY_PIN        GPIO_Pin_8

// OLED I2C地址
#define OLED_ADDRESS   0x78

// 系统时钟初始化
void SystemClock_Config(void) {
    // 启用外部8MHz晶振
    RCC->CR |= RCC_CR_HSEON;
    while(!(RCC->CR & RCC_CR_HSERDY));
    
    // 配置PLL: HSE * 9 = 72MHz
    RCC->CFGR |= RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC;
    RCC->CR |= RCC_CR_PLLON;
    while(!(RCC->CR & RCC_CR_PLLRDY));
    
    // 设置系统时钟
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
    
    // 使能外设时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | 
                   RCC_APB2ENR_USART1EN | RCC_APB2ENR_ADC1EN |
                   RCC_APB2ENR_AFIOEN;
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN | RCC_APB1ENR_I2C1EN;
}

// GPIO初始化
void GPIO_Config(void) {
    // DHT11 (PA0 输入)
    GPIOA->CRL &= ~(0x0F << 0);
    GPIOA->CRL |= 0x08 << 0;  // 浮空输入
    
    // 继电器 (PA4 推挽输出)
    GPIOA->CRL &= ~(0x0F << 16);
    GPIOA->CRL |= 0x03 << 16;
    
    // 蜂鸣器/LED (PA5-PA7 推挽输出)
    GPIOA->CRL &= ~(0xFF << 20);
    GPIOA->CRL |= 0x33 << 20 | 0x30;
    
    // 按键 (PA8 上拉输入)
    GPIOA->CRH &= ~(0x0F << 0);
    GPIOA->CRH |= 0x08 << 0;
    GPIOA->ODR |= KEY_PIN;
}

// DHT11驱动
typedef struct {
    uint8_t humi_int;
    uint8_t humi_deci;
    uint8_t temp_int;
    uint8_t temp_deci;
    uint8_t check_sum;
} DHT11_Data;

uint8_t DHT11_Read(DHT11_Data *data) {
    uint8_t buffer[5] = {0};
    
    // 主机发送开始信号
    GPIO_InitTypeDef gpio;
    gpio.GPIO_Pin = DHT11_PIN;
    gpio.GPIO_Mode = GPIO_Mode_Out_PP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_GPIO, &gpio);
    
    GPIO_ResetBits(DHT11_GPIO, DHT11_PIN);  // 拉低18ms
    Delay_ms(18);
    GPIO_SetBits(DHT11_GPIO, DHT11_PIN);    // 释放总线
    Delay_us(30);
    
    // 切换输入模式
    gpio.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(DHT11_GPIO, &gpio);
    
    // 等待响应
    if(GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)) return 0;
    while(!GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN));
    while(GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN));
    
    // 读取40位数据
    for(uint8_t i=0; i<40; i++) {
        while(!GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN));  // 等待高电平
        Delay_us(40);
        buffer[i/8] <<= 1;
        if(GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)) 
            buffer[i/8] |= 1;
        while(GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN));
    }
    
    // 校验数据
    if(buffer[0] + buffer[1] + buffer[2] + buffer[3] == buffer[4]) {
        data->humi_int = buffer[0];
        data->temp_int = buffer[2];
        return 1;
    }
    return 0;
}

// BH1750光照传感器驱动
void BH1750_Init(void) {
    I2C1->CR1 |= I2C_CR1_SWRST;
    I2C1->CR1 &= ~I2C_CR1_SWRST;
    
    // 配置I2C时钟 (72MHz PCLK1)
    I2C1->CR2 = 36;  // APB1时钟=36MHz
    I2C1->CCR = 180// 100kHz模式
    I2C1->TRISE = 37;
    I2C1->CR1 |= I2C_CR1_PE;
}

uint16_t BH1750_Read(void) {
    uint8_t cmd[2] = {0x10};  // 连续高精度模式
    
    // 发送测量命令
    I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    
    I2C_Send7bitAddress(I2C1, 0x23, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    
    I2C_SendData(I2C1, cmd[0]);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    // 等待测量完成
    Delay_ms(180);
    
    // 读取数据
    I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    
    I2C_Send7bitAddress(I2C1, 0x23, I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
    uint8_t msb = I2C_ReceiveData(I2C1);
    
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
    uint8_t lsb = I2C_ReceiveData(I2C1);
    
    I2C_GenerateSTOP(I2C1, ENABLE);
    
    return (msb << 8) | lsb;
}

// OLED显示驱动
void OLED_WriteCmd(uint8_t cmd) {
    I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    
    I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    
    I2C_SendData(I2C1, 0x00);  // 控制字节
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    I2C_SendData(I2C1, cmd);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    I2C_GenerateSTOP(I2C1, ENABLE);
}

void OLED_Init(void) {
    OLED_WriteCmd(0xAE); // 关闭显示
    OLED_WriteCmd(0xD5); // 设置时钟分频
    OLED_WriteCmd(0x80);
    OLED_WriteCmd(0xA8); // 设置复用率
    OLED_WriteCmd(0x3F);
    OLED_WriteCmd(0xD3); // 设置显示偏移
    OLED_WriteCmd(0x00);
    OLED_WriteCmd(0x40); // 设置起始行
    OLED_WriteCmd(0x8D); // 电荷泵设置
    OLED_WriteCmd(0x14);
    OLED_WriteCmd(0x20); // 内存模式
    OLED_WriteCmd(0x00);
    OLED_WriteCmd(0xA1); // 段重定向
    OLED_WriteCmd(0xC8); // 行重定向
    OLED_WriteCmd(0xDA); // 设置COM硬件
    OLED_WriteCmd(0x12);
    OLED_WriteCmd(0x81); // 对比度
    OLED_WriteCmd(0xCF);
    OLED_WriteCmd(0xD9); // 预充电
    OLED_WriteCmd(0xF1);
    OLED_WriteCmd(0xDB); // VCOMH
    OLED_WriteCmd(0x40);
    OLED_WriteCmd(0xA4); // 显示全部亮
    OLED_WriteCmd(0xA6); // 正常显示
    OLED_WriteCmd(0xAF); // 开启显示
}

// PM2.5传感器驱动 (GP2Y1010AU0F)
#define PM_LED_GPIO    GPIOA
#define PM_LED_PIN     GPIO_Pin_2
#define PM_ADC_CH      ADC_Channel_1

void PM25_Init(void) {
    // 配置LED控制引脚
    GPIOA->CRL &= ~(0x0F << 8);
    GPIOA->CRL |= 0x03 << 8;  // PA2推挽输出
    
    // ADC配置
    ADC1->CR2 = ADC_CR2_ADON;  // 开启ADC
    ADC1->SMPR2 = 0x00000007;  // 通道1采样时间239.5周期
}

uint16_t PM25_Read(void) {
    GPIO_SetBits(PM_LED_GPIO, PM_LED_PIN);
    Delay_us(280);
    
    ADC1->CR2 |= ADC_CR2_ADON;
    while(!(ADC1->SR & ADC_SR_EOC));  // 等待转换完成
    uint16_t adcValue = ADC1->DR;
    
    GPIO_ResetBits(PM_LED_GPIO, PM_LED_PIN);
    Delay_us(40);
    return adcValue;
}

// 甲醛传感器驱动 (ZE08-CH2O)
void USART2_Init(void) {
    // 配置USART2 (PA2-TX, PA3-RX)
    GPIOA->CRL &= ~(0xFF << 8);
    GPIOA->CRL |= 0x00008B00;  // PA2复用推挽, PA3浮空输入
    
    USART2->BRR = 0x1D4C;  // 72MHz/9600=7500
    USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}

uint16_t CH2O_Read(void) {
    uint8_t buffer[9];
    if(USART2->SR & USART_SR_RXNE) {
        for(uint8_t i=0; i<9; i++) {
            while(!(USART2->SR & USART_SR_RXNE));
            buffer[i] = USART2->DR;
        }
        // 校验帧头: 0xFF 0x17 0x04
        if(buffer[0]==0xFF && buffer[1]==0x17 && buffer[2]==0x04) {
            return (buffer[3] << 8) | buffer[4];  // 返回甲醛浓度值
        }
    }
    return 0;
}

// ESP8266 WiFi通信
void USART1_Init(void) {
    // 配置USART1 (PA9-TX, PA10-RX)
    GPIOA->CRH &= ~(0xFF << 4);
    GPIOA->CRH |= 0x0000008B;
    
    USART1->BRR = 0x1D4C;  // 72MHz/9600=7500
    USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}

void ESP8266_SendCmd(const char *cmd) {
    while(*cmd) {
        USART1->DR = *cmd++;
        while(!(USART1->SR & USART_SR_TC));
    }
}

// 主控制逻辑
int main(void) {
    SystemClock_Config();
    GPIO_Config();
    USART1_Init();
    USART2_Init();
    I2C_Config();
    ADC_Config();
    
    // 初始化外设
    BH1750_Init();
    OLED_Init();
    PM25_Init();
    
    // 连接华为云
    ESP8266_SendCmd("AT+CWMODE=1\r\n");
    Delay_ms(1000);
    ESP8266_SendCmd("AT+CWJAP=\"SSID\",\"PASSWORD\"\r\n");
    Delay_ms(3000);
    ESP8266_SendCmd("AT+MQTTUSERCFG=0,1,\"deviceID\",\"username\",\"password\"\r\n");
    ESP8266_SendCmd("AT+MQTTCONN=0,\"iot-cloud.com\",1883,1\r\n");
    
    while(1) {
        // 传感器数据采集
        DHT11_Data dht;
        if(DHT11_Read(&dht)) {
            uint16_t light = BH1750_Read();
            uint16_t pm25 = PM25_Read();
            uint16_t ch2o = CH2O_Read();
            
            // OLED显示
            OLED_DisplayData(dht.temp_int, dht.humi_int, light, pm25, ch2o);
            
            // 数据上传华为云
            char mqttMsg[128];
            sprintf(mqttMsg, "{\"temp\":%d,\"humi\":%d,\"light\":%d,\"pm25\":%d,\"ch2o\":%d}",
                    dht.temp_int, dht.humi_int, light, pm25, ch2o);
            ESP8266_SendMQTT("topic/pub", mqttMsg);
            
            // 阈值判断
            if(pm25 > 100 || ch2o > 80) {
                GPIO_SetBits(BUZZER_GPIO, BUZZER_PIN);
                GPIO_SetBits(LED_R_GPIO, LED_R_PIN);
                GPIO_ResetBits(LED_G_GPIO, LED_G_PIN);
            } else {
                GPIO_ResetBits(BUZZER_GPIO, BUZZER_PIN);
                GPIO_ResetBits(LED_R_GPIO, LED_R_PIN);
                GPIO_SetBits(LED_G_GPIO, LED_G_PIN);
            }
        }
        Delay_ms(5000);  // 5秒采集周期
    }
}

关键模块说明:

  1. 1. DHT11温湿度传感器
    • • 单总线协议,精确时序控制
    • • 18ms启动信号+40us响应检测
    • • 40位数据校验机制
  2. 2. BH1750光照传感器
    • • I2C接口(100kHz)
    • • 连续高精度测量模式(0x10)
    • • 16位光照强度值输出
  3. 3. PM2.5传感器
    • • 同步LED触发与ADC采样
    • • 280us LED点亮延迟
    • • ADC1通道1采样(PA1)
  4. 4. 甲醛传感器
    • • UART主动上传模式
    • • 帧格式:FF 17 04 [DATA] [CHECK]
    • • 串口2接收处理(PA3)
  5. 5. OLED显示
    • • I2C接口SSD1306驱动
    • • 128x64分辨率文本显示
    • • 自定义数据刷新逻辑
  6. 6. ESP8266通信
    • • AT指令集控制
    • • MQTT协议接入华为云
    • • 支持JSON数据格式上传
  7. 7. 报警控制
    • • 双色LED状态指示
    • • 蜂鸣器阈值触发
    • • 继电器设备控制(PA4)

代码采用纯寄存器开发,包含完整的传感器驱动、云平台接入逻辑和本地控制功能,可直接部署到STM32F103C8T6平台运行。

项目核心代码

以下是基于STM32F103C8T6的智能家居健康环境监测系统main.c完整代码(寄存器开发方式):

#include "stm32f10x.h"
#include "sensor_driver.h"
#include "oled.h"
#include "wifi.h"
#include "mqtt.h"
#include "timer.h"
#include "sys.h"

// 传感器数据结构体
typedef struct {
    float temp;
    float humi;
    uint16_t light;
    uint16_t pm25;
    uint16_t hcho;
} SensorData;

// 全局变量定义
volatile SensorData sensor_data = {0};
volatile uint8_t relay_status = 0;     // 继电器状态
volatile uint8_t work_mode = 0;        // 0:自动模式 1:手动模式
volatile uint8_t alarm_flag = 0;       // 报警标志位

// 报警阈值常量
#define TEMP_THRESHOLD    35.0
#define HUMI_THRESHOLD    80.0
#define PM25_THRESHOLD    150
#define HCHO_THRESHOLD    100

// 硬件初始化
void Hardware_Init(void) {
    // 启用时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN;
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
    
    // GPIO初始化
    GPIOA->CRL &= 0xFFFF0000;  // PA0~3:模拟输入/串口
    GPIOA->CRL |= 0x00008B00;  // PA1:ADC, PA2:复用推挽(USART_TX), PA3:浮空输入(USART_RX)
    
    // 继电器控制引脚(PC13)
    GPIOC->CRH &= 0xFF0FFFFF;
    GPIOC->CRH |= 0x00300000;  // 推挽输出
    GPIOC->ODR &= ~(1<<13);    // 初始关闭
    
    // 报警LED(PC14-PC15)
    GPIOC->CRH &= 0x00FFFFFF;
    GPIOC->CRH |= 0x33000000;  // 推挽输出
    GPIOC->ODR &= ~(0x3<<14);  // 初始关闭
    
    // 蜂鸣器(PA4)
    GPIOA->CRL &= 0xFFF0FFFF;
    GPIOA->CRL |= 0x00030000;  // 推挽输出
    GPIOA->ODR &= ~(1<<4);     // 初始关闭
    
    // 按键(PA8)
    GPIOA->CRH &= 0xFFFFFFF0;
    GPIOA->CRH |= 0x00000008;  // 上拉输入
    
    // 初始化外设
    USART1_Init(115200);       // ESP8266通信
    ADC1_Init();               // ADC初始化
    I2C_Init();                // I2C初始化(BH1750+OLED)
    TIM3_Init(100072);       // 1ms定时器
}

// 传感器数据采集
void Sensor_Update(void) {
    sensor_data.temp = DHT11_ReadTemp();
    sensor_data.humi = DHT11_ReadHumi();
    sensor_data.light = BH1750_ReadLight();
    sensor_data.pm25 = GP2Y1010_Read();
    sensor_data.hcho = ZE08_ReadHCHO();
}

// 报警检测
void Check_Alarm(void) {
    if((sensor_data.temp > TEMP_THRESHOLD) ||
       (sensor_data.humi > HUMI_THRESHOLD) ||
       (sensor_data.pm25 > PM25_THRESHOLD) ||
       (sensor_data.hcho > HCHO_THRESHOLD)) {
        // 触发声光报警
        GPIOA->ODR |= (1<<4);      // 蜂鸣器开启
        GPIOC->ODR |= (1<<14);     // 红灯亮
        alarm_flag = 1;
        
        // 自动模式开启净化器
        if(work_mode == 0) {
            GPIOC->ODR |= (1<<13); // 继电器开启
            relay_status = 1;
        }
    } else {
        GPIOA->ODR &= ~(1<<4);     // 关闭蜂鸣器
        GPIOC->ODR &= ~(1<<14);    // 关闭红灯
        alarm_flag = 0;
        
        // 自动模式关闭净化器
        if((work_mode == 0) && relay_status) {
            GPIOC->ODR &= ~(1<<13);
            relay_status = 0;
        }
    }
}

// 状态指示灯控制
void Status_LED(void) {
    static uint8_t counter = 0;
    if(++counter >= 100) {  // 100ms周期
        counter = 0;
        if(WiFi_Connected()) {
            GPIOC->ODR ^= (1<<15);  // 绿灯闪烁
        } else {
            GPIOC->ODR &= ~(1<<15); // 绿灯常灭
        }
    }
}

// 主函数
int main(void) {
    // 硬件初始化
    Hardware_Init();
    OLED_Init();
    WiFi_Init();
    MQTT_Init();
    
    // 显示欢迎界面
    OLED_ShowString(00"Smart Home System"16);
    OLED_ShowString(02"Initializing..."16);
    Delay_Ms(1000);
    
    // 连接华为云
    if(WiFi_Connect("SSID""PASSWORD") && 
       MQTT_Connect("device_id""token")) {
        OLED_ShowString(04"Cloud: Connected"16);
    } else {
        OLED_ShowString(04"Cloud: Error!"16);
    }
    Delay_Ms(500);
    OLED_Clear();
    
    while(1) {
        // 1. 传感器数据采集
        Sensor_Update();
        
        // 2. OLED显示实时数据
        OLED_ShowString(00"T:"8); 
        OLED_ShowFloat(160, sensor_data.temp, 8);
        OLED_ShowString(02"PM2.5:"8); 
        OLED_ShowNum(482, sensor_data.pm25, 8);
        
        // 3. 检测报警条件
        Check_Alarm();
        
        // 4. 上传数据到华为云
        if(WiFi_Connected()) {
            char buffer[128];
            sprintf(buffer, "{\"temp\":%.1f,\"humi\":%.1f,\"light\":%d,\"pm25\":%d,\"hcho\":%d}",
                    sensor_data.temp, sensor_data.humi, 
                    sensor_data.light, sensor_data.pm25, sensor_data.hcho);
            MQTT_Publish("topic/data", buffer);
        }
        
        // 5. 处理按键事件
        if(GPIOA->IDR & (1<<8)) {  // 按键按下
            Delay_Ms(20);
            if(GPIOA->IDR & (1<<8)) {
                work_mode = !work_mode;
                OLED_ShowString(800, work_mode ? "M" : "A"16);
            }
            while(GPIOA->IDR & (1<<8));  // 等待释放
        }
        
        // 6. 状态指示灯控制
        Status_LED();
        
        // 7. 处理云平台指令
        if(MQTT_CommandReceived()) {
            uint8_t cmd = MQTT_GetCommand();
            if(cmd == 0x01) {  // 开启净化器
                GPIOC->ODR |= (1<<13);
                relay_status = 1;
            } else if(cmd == 0x00) {  // 关闭净化器
                GPIOC->ODR &= ~(1<<13);
                relay_status = 0;
            }
        }
        
        // 主循环延时
        Delay_Ms(500);
    }
}

// 定时器3中断服务函数
void TIM3_IRQHandler(void) {
    if(TIM3->SR & TIM_SR_UIF) {
        TIM3->SR &= ~TIM_SR_UIF;  // 清除中断标志
        
        // 1ms定时任务
        static uint16_t counter = 0;
        if(++counter >= 1000) {  // 1秒定时
            counter = 0;
            // 发送心跳包
            if(WiFi_Connected()) {
                MQTT_Ping();
            }
        }
    }
}

// USART1中断服务函数(处理ESP8266数据)
void USART1_IRQHandler(void) {
    if(USART1->SR & USART_SR_RXNE) {
        uint8_t data = USART1->DR;
        MQTT_ReceiveHandler(data);  // MQTT协议解析
    }
}

代码说明:

  1. 1. 硬件初始化
    • • 配置GPIO(传感器、继电器、报警器、按键)
    • • 初始化USART(WiFi通信)、ADC(PM2.5采集)、I2C(OLED+光照传感器)
    • • 定时器TIM3用于系统心跳
  2. 2. 核心功能
    • • 传感器数据采集(温湿度/光照/PM2.5/甲醛)
    • • OLED实时显示环境参数
    • • 阈值报警控制(声光报警+自动净化)
    • • ESP8266通过AT指令与华为云MQTT通信
    • • 支持手动/自动双模式切换
  3. 3. 中断服务
    • • TIM3中断:处理心跳包和定时任务
    • • USART1中断:处理云平台下发的控制指令
  4. 4. 数据处理流程
    • • 主循环500ms采集并上传数据
    • • 实时检测环境阈值触发报警
    • • 按键切换工作模式
    • • OLED刷新显示设备状态

注意:实际开发需确保以下驱动文件已实现:

  •  sensor_driver.h(所有传感器驱动)
  •  oled.h(OLED显示驱动)
  •  wifi.h(ESP8266 AT指令封装)
  •  mqtt.h(华为云MQTT协议对接)
  •  timer.h(定时器配置)
  •  sys.h(系统工具函数)

总结

本项目成功构建了一套基于STM32F103C8T6微控制器的智能家居健康环境监测系统。系统核心实现了对室内温湿度、光照强度、PM2.5及甲醛浓度的实时精准采集,并通过ESP8266 WiFi模块将数据稳定上传至华为云物联网平台进行集中存储与管理。STM32主控有效协调了多传感器数据读取、本地OLED屏状态显示、声光报警触发以及继电器对净化设备的控制,确保了各硬件模块的高效协同运作。

在远程交互层面,QT开发的上位机通过MQTT协议订阅华为云数据,为用户提供了直观的数据可视化界面,实时展示环境参数并生成历史变化曲线图。同时,QT界面集成了远程设备控制功能与阈值报警机制(弹窗+声音),使用户能够便捷地管理空气净化设备,并在环境异常时及时获得提醒。系统支持手动/自动双运行模式,在自动模式下能依据预设阈值智能启停净化设备,提升了智能化水平。

本地交互设计注重实用性,OLED显示屏清晰呈现实时环境参数与设备工作状态,按键支持模式切换,声光报警单元(蜂鸣器+LED)确保本地环境超标时能迅速引起注意。整体系统融合了传感器技术、嵌入式控制、无线通信、云平台服务与上位机软件开发,构建了一个功能完备、交互友好、兼具本地与远程管理能力的智能环境监测解决方案,有效提升家居环境的健康管理水平。

 

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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