基于STM32的冷库智能监控与预警系统设计
基于STM32的冷库智能监控与预警系统设计
项目开发背景
冷链物流在食品、医药等领域至关重要,冷库作为核心存储节点,其内部温湿度稳定性直接关系产品质量与安全。传统冷库监控多依赖人工巡检或简易仪表,存在响应滞后、数据缺失、无法远程预警等问题。一旦温湿度失控,易导致货物腐败、疫苗失效等重大损失,亟需智能化、实时化的监控手段。
随着物联网技术发展,基于嵌入式系统的远程监控方案成为行业趋势。STM32微控制器凭借低功耗、高可靠性及丰富外设接口,为冷库监控终端提供了理想的硬件平台。结合高精度温湿度传感器、无线通信模块与云平台,可构建全天候自动化监控网络,实现从本地预警到远程管理的闭环控制。
本项目旨在设计一套集成环境感知、实时显示、云端交互及智能预警的冷库监控系统,通过华为云物联网平台实现数据汇聚与分析,并借助移动终端进行远程管理。系统将显著提升冷库运维效率,降低人工成本,为易腐物品存储提供精准可靠的技术保障,有效防范质量风险。
设计实现的功能
(1)实时检测冷库内部温湿度:通过SHT30传感器(I2C接口)持续采集温湿度数据。
(2)异常温湿度触发蜂鸣器报警:当温湿度超出预设阈值时,STM32驱动有源蜂鸣器(高电平触发)发出声光警报。
(3)数据上传至华为云物联网平台:通过ESP8266 WiFi模块(MQTT协议)将温湿度数据实时传输至华为云。
(4)OLED实时显示当前环境参数:0.96寸SPI OLED屏动态展示温度、湿度及报警状态。
(5)支持远程查看与报警提示推送:Qt开发手机APP可远程查看实时数据,并在云平台触发异常时接收推送告警。
项目硬件模块组成
(1)主控芯片:STM32F103C8T6
(2)温湿度检测模块:SHT30(I2C接口)
(3)显示模块:0.96寸SPI OLED显示屏
(4)联网模块:ESP8266 WiFi模块(支持MQTT协议)
(5)报警模块:高电平触发有源蜂鸣器
(6)供电模块:DC 5V电源 + AMS1117稳压芯片
设计意义
该冷库智能监控与预警系统的设计意义主要体现在以下几个方面:
该系统通过高精度SHT30传感器实时采集冷库温湿度数据,结合STM32主控芯片的稳定处理能力,实现了对储藏环境关键参数的精准监测。当温湿度超出预设安全阈值时,系统立即触发蜂鸣器本地声光报警,同时通过ESP8266模块将异常数据经MQTT协议上传至华为云物联网平台。这种双重响应机制大幅降低了因环境失控导致货物变质的风险,尤其对食品、药品等温敏物资的保质存储具有核心保障价值。
系统显著提升了冷库管理效率与响应速度。传统人工巡检方式存在监测盲区和时效滞后问题,而本设计通过OLED屏本地实时显示参数,结合华为云平台的远程数据同步功能,使管理人员可通过Qt开发的手机APP随时随地掌握冷库状态。自动化监控替代了高频次人工巡检,在降低人力成本的同时实现了24小时无间断监管,确保异常情况能在第一时间被发现和处理。
基于物联网架构的数据积累为优化运营提供了决策支持。系统持续上传至云端的历史温湿度数据,可通过华为云平台进行深度分析与可视化呈现。这些数据有助于管理人员识别冷库运行规律,优化制冷设备启停策略以降低能耗,同时为库存周转计划、设备维护周期等关键决策提供数据依据,从而实现冷库的精细化、智能化管理。
系统采用高性价比硬件方案增强了实用性与普适性。以广泛应用的STM32F103C8T6作为核心控制器,搭配成熟稳定的SPI OLED、I2C传感器和WiFi通信模块,在保证功能完整性的同时有效控制了硬件成本。本地报警与云端推送的双重保障机制显著提升了系统可靠性,其模块化设计也便于维护升级,特别适合中小型冷库的智能化改造需求,具有较高的工程推广价值。
设计思路
整个系统的设计思路围绕STM32F103C8T6主控芯片展开,通过模块化协作实现冷库环境监控。首先,系统通过I2C总线驱动SHT30温湿度传感器,实时采集冷库内部环境数据。采集频率设置为每2秒一次,确保数据的时效性,同时避免频繁操作导致的资源浪费。
采集到的温湿度数据通过SPI接口传输至0.96寸OLED显示屏,动态刷新显示当前参数值、系统状态及报警提示。显示内容采用分层设计,主界面展示实时温湿度,次级界面可查看历史报警记录。若温湿度超出预设安全阈值,STM32立即通过GPIO引脚输出高电平触发有源蜂鸣器,发出持续声光报警直至参数恢复正常。
为实现云端交互,STM32通过UART串口与ESP8266 WiFi模块通信。采用AT指令集建立WiFi连接后,系统将温湿度数据封装为JSON格式,基于MQTT协议定时上传至华为云物联网平台。平台预设规则引擎,当检测到异常数据时自动向远程APP推送报警信息,同时STM32本地记录异常事件时间戳。
远程监控功能由Qt开发的手机APP实现,APP订阅华为云MQTT主题,实时接收环境参数更新和报警推送。用户可通过APP界面查看冷库当前状态、历史数据曲线及报警日志,形成完整的远程监控闭环。
供电部分采用DC 5V输入,经AMS1117稳压芯片转换为3.3V系统电压,为STM32、传感器、OLED及ESP8266提供稳定电源。蜂鸣器单独由GPIO直接驱动,确保报警响应优先级。所有硬件模块通过PCB集成,布局时隔离数字与模拟电路,降低信号干扰风险。
框架图
系统框架图
+-----------------------------------------------------------------------------------------+
| 冷库智能监控与预警系统 |
| |
| +---------------------+ +-------------------+ +-----------------------------+ |
| | | | | | | |
| | STM32F103C8T6 |<----| SHT30传感器 | | 华为云物联网平台 | |
| | (主控制器) | I2C | (温湿度检测) | | (MQTT协议) | |
| | |---->| | | | |
| +----------+----------+ +-------------------+ +-------------+---------------+ |
| | ▲ |
| +----------v----------+ +-------------------+ | MQTT |
| | | SPI | | | 数据上传 |
| | 0.96寸OLED屏 |<----| 显示模块 | | |
| | (实时数据显示) |---->| | +----------+---------------+ |
| +---------------------+ +-------------------+ | | |
| | | Qt开发手机APP | |
| +----------v----------+ +-------------------+ | (远程查看/报警推送) | |
| | | GPIO| | | | |
| | 有源蜂鸣器 |<----| 报警模块 | +--------------------------+ |
| | (高电平触发报警) |---->| | | |
| +---------------------+ +-------------------+ | |
| ▲ | |
| +----------+----------+ +-------------------+ +---------------------+ | |
| | | UART| | | | | |
| | ESP8266 WiFi模块 |<----| 联网模块 |---->| 互联网 |----+ |
| | (MQTT连接华为云) |---->| | | | |
| +---------------------+ +-------------------+ +---------------------+ |
| |
| +-----------------------------------+ |
| | 供电模块 | |
| | DC 5V电源 → AMS1117稳压(3.3V) | |
| | (供电: STM32/传感器/模块) | |
| +-----------------------------------+ |
+-----------------------------------------------------------------------------------------+
核心交互说明:
-
主控中心
- STM32F103C8T6:协调所有模块,处理数据逻辑与报警判断。
-
数据采集与执行
- SHT30:通过I2C向STM32发送实时温湿度数据。
- 蜂鸣器:当温湿度异常时,STM32通过GPIO输出高电平触发报警。
- OLED屏:STM32通过SPI协议驱动,显示温湿度/报警状态。
-
云端通信
- ESP8266:通过UART接收STM32指令,以MQTT协议将数据上传至华为云。
- 华为云:存储数据并推送报警至手机APP。
-
远程交互
- Qt手机APP:订阅华为云数据,实时查看参数并接收报警推送。
-
供电系统
- 5V电源经AMS1117稳压至3.3V,为所有模块供电。
系统总体设计
系统总体设计
系统以STM32F103C8T6微控制器为核心,通过其丰富的外设接口协调各模块工作。温湿度检测由SHT30传感器实现,采用I2C通信协议与主控芯片连接,实时采集冷库环境数据。采集到的数据通过SPI接口驱动的0.96寸OLED显示屏进行本地可视化显示,直观呈现当前温湿度数值及系统状态。
异常处理机制通过GPIO控制实现:当温湿度超出预设阈值时,STM32触发高电平信号驱动有源蜂鸣器发出声光报警。数据上传功能依托ESP8266 WiFi模块完成,该模块通过UART串口与主控通信,基于MQTT协议将温湿度数据实时传输至华为云物联网平台,确保远程可访问性。
远程监控由Qt开发的手机APP实现,该APP对接华为云平台接口,可实时查看冷库环境参数。当云平台检测到异常数据时,主动向APP推送报警通知,实现跨地域预警。系统供电采用DC 5V外部电源输入,经AMS1117稳压芯片转换为3.3V稳定电压,为所有模块提供可靠电力支持。
系统功能总结
功能描述 | 实现方式(硬件/软件) |
---|---|
实时检测冷库内部温湿度 | SHT30传感器(I2C通信)采集数据,STM32F103C8T6主控处理 |
异常温湿度触发蜂鸣器报警 | STM32控制高电平触发有源蜂鸣器,设定阈值自动响应 |
数据上传至华为云物联网平台 | ESP8266 WiFi模块通过MQTT协议与华为云平台通信 |
OLED实时显示当前环境参数 | 0.96寸SPI OLED屏动态刷新温湿度等数据 |
支持远程查看与报警提示推送 | Qt开发手机APP接收华为云数据,实时监控并推送告警消息 |
设计的各个功能模块描述
主控芯片采用STM32F103C8T6微控制器,作为系统的核心处理单元,负责协调各模块的数据采集、逻辑控制和通信调度。通过其丰富的外设接口实现与其他功能模块的高效交互。
温湿度检测模块使用SHT30传感器,通过I2C总线与主控芯片连接。该传感器实时采集冷库内的温度和湿度数据,具有高精度和快速响应特性,为系统提供准确的环境参数监测基础。
显示模块采用0.96寸SPI接口OLED屏幕,直接与主控芯片连接。该模块实时显示当前温湿度数值、系统状态及报警信息,提供直观的本地监控界面,支持在低温环境下稳定工作。
联网模块基于ESP8266 WiFi模组,通过串口UART与主控芯片通信。该模块运行MQTT协议客户端,实现与华为云物联网平台的安全连接,定时上传温湿度数据并接收云端指令,同时支持远程报警状态推送。
报警模块采用高电平触发的有源蜂鸣器,由主控芯片的GPIO引脚直接驱动。当检测到温湿度超过预设阈值时,主控芯片输出高电平信号触发蜂鸣器鸣响,实现现场声光报警提示。
远程监控功能通过Qt开发的手机APP实现,该APP接入华为云物联网平台,可实时查看冷库温湿度数据曲线。当云端接收到异常报警信号时,APP自动弹出推送通知,确保管理人员及时获知告警信息。
供电模块由DC 5V外部电源输入,经AMS1117-3.3V稳压芯片转换后,为STM32主控芯片、传感器、显示屏及外围电路提供稳定的3.3V工作电压,保证系统在冷库环境中的持续可靠运行。
上位机代码设计
以下是一个基于Qt开发的冷库监控系统上位机代码设计,实现远程数据查看和报警推送功能:
#include <QApplication>
#include <QMainWindow>
#include <QChart>
#include <QChartView>
#include <QLineSeries>
#include <QValueAxis>
#include <QMqttClient>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QStatusBar>
#include <QMessageBox>
#include <QDateTime>
#include <QSystemTrayIcon>
using namespace QtCharts;
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
// MQTT客户端配置
m_client = new QMqttClient(this);
m_client->setHostname("你的华为云地址"); // 替换实际地址
m_client->setPort(1883);
m_client->setClientId("ColdStorageMonitor");
m_client->setUsername("用户名"); // 华为云用户名
m_client->setPassword("密码"); // 华为云密码
// UI初始化
initUI();
setupConnections();
// 系统托盘图标
m_trayIcon = new QSystemTrayIcon(QIcon(":/icons/app.png"), this);
m_trayIcon->show();
}
private slots:
void connectToBroker() {
if (m_client->state() == QMqttClient::Disconnected) {
m_client->connectToHost();
m_statusLabel->setText("正在连接云平台...");
} else {
m_client->disconnectFromHost();
}
}
void updateConnectionStatus() {
if (m_client->state() == QMqttClient::Connected) {
m_connectBtn->setText("断开连接");
m_statusLabel->setText("已连接 | 监听中");
subscribeTopics();
} else {
m_connectBtn->setText("连接云平台");
m_statusLabel->setText("连接已断开");
}
}
void messageReceived(const QByteArray &message, const QMqttTopicName &topic) {
const QString content = QString::fromUtf8(message);
const QString topicName = topic.name();
if (topicName.endsWith("/sensor/data")) {
updateSensorData(content);
} else if (topicName.endsWith("/alarm")) {
showAlarm(content);
}
}
private:
void initUI() {
// 主布局
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
// 传感器数据显示区
QHBoxLayout *dataLayout = new QHBoxLayout();
m_tempLabel = createDataLabel("温度: --°C");
m_humiLabel = createDataLabel("湿度: --%");
dataLayout->addWidget(m_tempLabel);
dataLayout->addWidget(m_humiLabel);
// 图表初始化
initChart();
// 控制按钮
m_connectBtn = new QPushButton("连接云平台", this);
QPushButton *historyBtn = new QPushButton("查看历史数据", this);
// 状态栏
m_statusLabel = new QLabel("未连接", this);
statusBar()->addPermanentWidget(m_statusLabel);
// 布局组装
mainLayout->addLayout(dataLayout);
mainLayout->addWidget(new QLabel("温湿度趋势图", this));
mainLayout->addWidget(m_chartView);
QHBoxLayout *btnLayout = new QHBoxLayout();
btnLayout->addWidget(m_connectBtn);
btnLayout->addWidget(historyBtn);
mainLayout->addLayout(btnLayout);
setCentralWidget(centralWidget);
resize(800, 600);
setWindowTitle("冷库智能监控系统");
}
void setupConnections() {
connect(m_connectBtn, &QPushButton::clicked, this, &MainWindow::connectToBroker);
connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateConnectionStatus);
connect(m_client, &QMqttClient::messageReceived, this, &MainWindow::messageReceived);
}
void subscribeTopics() {
auto subscription = m_client->subscribe("cold_storage/sensor/data");
if (!subscription) {
QMessageBox::critical(this, "错误", "订阅传感器数据失败!");
return;
}
subscription = m_client->subscribe("cold_storage/alarm");
if (!subscription) {
QMessageBox::critical(this, "错误", "订阅报警信息失败!");
}
}
void initChart() {
m_chart = new QChart();
m_tempSeries = new QLineSeries();
m_humiSeries = new QLineSeries();
m_tempSeries->setName("温度(°C)");
m_humiSeries->setName("湿度(%)");
m_chart->addSeries(m_tempSeries);
m_chart->addSeries(m_humiSeries);
QValueAxis *axisX = new QValueAxis();
axisX->setRange(0, 60);
axisX->setLabelFormat("%d");
axisX->setTitleText("时间(分钟)");
QValueAxis *axisY = new QValueAxis();
axisY->setRange(-20, 30);
axisY->setTitleText("数值");
m_chart->addAxis(axisX, Qt::AlignBottom);
m_chart->addAxis(axisY, Qt::AlignLeft);
m_tempSeries->attachAxis(axisX);
m_tempSeries->attachAxis(axisY);
m_humiSeries->attachAxis(axisX);
m_humiSeries->attachAxis(axisY);
m_chartView = new QChartView(m_chart);
m_chartView->setRenderHint(QPainter::Antialiasing);
}
QLabel* createDataLabel(const QString &text) {
QLabel *label = new QLabel(text, this);
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("font-size: 24px; font-weight: bold;");
label->setMinimumHeight(60);
return label;
}
void updateSensorData(const QString &data) {
// 数据格式: "23.5,45.2"
QStringList values = data.split(',');
if (values.size() == 2) {
float temp = values[0].toFloat();
float humi = values[1].toFloat();
m_tempLabel->setText(QString("温度: %1°C").arg(temp));
m_humiLabel->setText(QString("湿度: %1%").arg(humi));
// 更新图表
QDateTime now = QDateTime::currentDateTime();
qint64 secs = now.toSecsSinceEpoch();
m_tempSeries->append(secs, temp);
m_humiSeries->append(secs, humi);
// 保持最近60个数据点
if (m_tempSeries->count() > 60) {
m_tempSeries->removePoints(0, m_tempSeries->count() - 60);
m_humiSeries->removePoints(0, m_humiSeries->count() - 60);
}
}
}
void showAlarm(const QString &msg) {
QMessageBox::critical(this, "冷库异常报警", msg);
// 系统托盘通知
m_trayIcon->showMessage("冷库告警",
msg,
QSystemTrayIcon::Critical,
5000);
}
private:
QMqttClient *m_client;
QChart *m_chart;
QChartView *m_chartView;
QLineSeries *m_tempSeries;
QLineSeries *m_humiSeries;
QLabel *m_tempLabel;
QLabel *m_humiLabel;
QLabel *m_statusLabel;
QPushButton *m_connectBtn;
QSystemTrayIcon *m_trayIcon;
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
// 设置应用样式
a.setStyle("Fusion");
QPalette palette;
palette.setColor(QPalette::Window, QColor(240, 240, 240));
a.setPalette(palette);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
关键功能说明:
-
MQTT通信:
- 使用QtMqtt模块连接华为云物联网平台
- 订阅传感器数据主题(
cold_storage/sensor/data
)和报警主题(cold_storage/alarm
)
-
数据可视化:
- 实时显示温湿度数值(大字体标签)
- 动态折线图展示历史趋势(自动保留最近60个数据点)
-
报警处理:
- 弹出警告对话框显示报警详情
- 系统托盘通知(后台运行时仍可提醒)
-
用户界面:
- 连接状态实时显示
- 响应式布局适配移动设备
- 历史数据查看入口
使用说明:
-
配置华为云参数:
m_client->setHostname("your_iotda_instance_url"); // 华为云地址 m_client->setUsername("device_id"); // 设备ID m_client->setPassword("device_secret"); // 设备密钥
-
数据格式约定:
- 传感器数据:
"温度值,湿度值"
(如"-18.5,75.2"
) - 报警信息:纯文本报警描述(如
"温度异常! 当前:-2.5°C 阈值:-18°C"
)
- 传感器数据:
-
编译依赖:
- Qt 5.15+ (Core, MQTT, Charts)
- QtMqtt模块
- QtCharts模块
-
移动端适配:
- 使用响应式布局自动适应屏幕尺寸
- 触摸友好的控件尺寸
- 系统通知兼容Android/iOS
模块代码设计
STM32F103C8T6 设备端模块代码设计
#include "stm32f10x.h"
#include <string.h>
#include <math.h>
// OLED引脚定义 (SPI软件模拟)
#define OLED_SCK_PIN GPIO_Pin_13
#define OLED_SCK_PORT GPIOC
#define OLED_SDA_PIN GPIO_Pin_15
#define OLED_SDA_PORT GPIOC
#define OLED_RST_PIN GPIO_Pin_14
#define OLED_RST_PORT GPIOC
#define OLED_DC_PIN GPIO_Pin_12
#define OLED_DC_PORT GPIOC
// SHT30引脚定义 (I2C1)
#define SHT30_SCL_PIN GPIO_Pin_6
#define SHT30_SDA_PIN GPIO_Pin_7
#define SHT30_PORT GPIOB
#define SHT30_ADDR 0x44<<1
// 蜂鸣器引脚
#define BUZZER_PIN GPIO_Pin_0
#define BUZZER_PORT GPIOA
// ESP8266串口 (USART2)
#define ESP8266_USART USART2
// 温湿度阈值
#define TEMP_HIGH_ALARM 8.0f
#define TEMP_LOW_ALARM -5.0f
#define HUMI_HIGH_ALARM 90.0f
#define HUMI_LOW_ALARM 30.0f
// 函数声明
void SystemClock_Config(void);
void GPIO_Config(void);
void I2C_Config(void);
void USART_Config(void);
void OLED_Init(void);
void OLED_WriteCmd(uint8_t cmd);
void OLED_WriteData(uint8_t data);
void OLED_DisplayString(uint8_t x, uint8_t y, char *str);
void SHT30_Init(void);
uint8_t SHT30_ReadData(float *temp, float *humi);
void ESP8266_SendData(float temp, float humi);
void Buzzer_Alert(uint8_t state);
// OLED字体
const uint8_t OLED_FONT[][16] = {/* 字库数据省略 */};
int main(void) {
SystemClock_Config();
GPIO_Config();
I2C_Config();
USART_Config();
OLED_Init();
SHT30_Init();
float temperature, humidity;
char disp_buf[20];
while (1) {
if (SHT30_ReadData(&temperature, &humidity) == 0) {
// OLED显示
sprintf(disp_buf, "Temp:%.1fC", temperature);
OLED_DisplayString(0, 0, disp_buf);
sprintf(disp_buf, "Humi:%.1f%%", humidity);
OLED_DisplayString(0, 2, disp_buf);
// 异常报警判断
if (temperature > TEMP_HIGH_ALARM || temperature < TEMP_LOW_ALARM ||
humidity > HUMI_HIGH_ALARM || humidity < HUMI_LOW_ALARM) {
Buzzer_Alert(1); // 触发蜂鸣器
OLED_DisplayString(0, 4, "ALARM!!!");
} else {
Buzzer_Alert(0);
OLED_DisplayString(0, 4, "Normal ");
}
// 数据上传云端
ESP8266_SendData(temperature, humidity);
}
Delay(3000); // 3秒更新周期
}
}
// 系统时钟配置 (72MHz HSE)
void SystemClock_Config(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));
FLASH->ACR |= FLASH_ACR_LATENCY_2;
RCC->CFGR |= RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC_HSE;
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);
}
// GPIO初始化
void GPIO_Config(void) {
// 蜂鸣器(PA0)
GPIOA->CRL &= ~(0x0F << 0);
GPIOA->CRL |= 0x02 << 0; // 推挽输出
// OLED引脚(PC12-PC15)
GPIOC->CRH &= ~(0xFFFF << 0);
GPIOC->CRH |= 0x2222 << 0; // 推挽输出
// SHT30引脚(PB6/PB7)
GPIOB->CRL &= ~(0xFF << 24);
GPIOB->CRL |= 0x77 << 24; // 复用开漏
}
// I2C1初始化
void I2C_Config(void) {
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
I2C1->CR1 &= ~I2C_CR1_PE; // 禁用I2C
I2C1->CR2 = 36; // APB1时钟36MHz
I2C1->CCR = 180; // 100kHz: 36M/(2*100k)=180
I2C1->TRISE = 37; // 1000ns/28ns=35.7->37
I2C1->CR1 |= I2C_CR1_ACK;
I2C1->CR1 |= I2C_CR1_PE; // 启用I2C
}
// USART2初始化 (ESP8266)
void USART_Config(void) {
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
GPIOA->CRL |= 0x4B0; // PA2(TX)复用推挽, PA3(RX)浮空输入
USART2->BRR = 72000000 / 115200; // 波特率
USART2->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
}
// SHT30初始化
void SHT30_Init(void) {
uint8_t cmd[2] = {0x24, 0x00}; // 高精度测量命令
while (I2C1->SR2 & I2C_SR2_BUSY);
// 发送起始条件
I2C1->CR1 |= I2C_CR1_START;
while (!(I2C1->SR1 & I2C_SR1_SB));
I2C1->DR = SHT30_ADDR;
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;
}
// 读取SHT30数据
uint8_t SHT30_ReadData(float *temp, float *humi) {
uint8_t data[6];
uint16_t raw_temp, raw_humi;
// 发送读取请求
I2C1->CR1 |= I2C_CR1_START;
while (!(I2C1->SR1 & I2C_SR1_SB));
I2C1->DR = SHT30_ADDR | 0x01;
while (!(I2C1->SR1 & I2C_SR1_ADDR));
(void)I2C1->SR2;
// 接收数据
for (uint8_t i = 0; i < 5; i++) {
while (!(I2C1->SR1 & I2C_SR1_RXNE));
data[i] = I2C1->DR;
if (i < 4) I2C1->CR1 |= I2C_CR1_ACK;
else I2C1->CR1 &= ~I2C_CR1_ACK;
}
I2C1->CR1 |= I2C_CR1_STOP;
while (!(I2C1->SR1 & I2C_SR1_RXNE));
data[5] = I2C1->DR;
// 数据转换
raw_temp = (data[0] << 8) | data[1];
raw_humi = (data[3] << 8) | data[4];
*temp = -45.0f + 175.0f * (raw_temp / 65535.0f);
*humi = 100.0f * (raw_humi / 65535.0f);
// CRC校验省略
return 0;
}
// OLED写命令
void OLED_WriteCmd(uint8_t cmd) {
OLED_DC_PORT->BRR = OLED_DC_PIN; // DC=0
OLED_SDA_PORT->BRR = OLED_SDA_PIN;
for (uint8_t i = 0; i < 8; i++) {
OLED_SCK_PORT->BRR = OLED_SCK_PIN;
if (cmd & 0x80) OLED_SDA_PORT->BSRR = OLED_SDA_PIN;
else OLED_SDA_PORT->BRR = OLED_SDA_PIN;
OLED_SCK_PORT->BSRR = OLED_SCK_PIN;
cmd <<= 1;
}
}
// OLED显示字符串
void OLED_DisplayString(uint8_t x, uint8_t y, char *str) {
// 定位显示位置
OLED_WriteCmd(0xB0 + y);
OLED_WriteCmd(((x & 0xF0) >> 4) | 0x10);
OLED_WriteCmd(x & 0x0F);
while (*str) {
for (uint8_t i = 0; i < 16; i++) {
OLED_WriteData(OLED_FONT[*str - 32][i]);
}
str++;
}
}
// ESP8266发送数据到华为云
void ESP8266_SendData(float temp, float humi) {
char mqttMsg[50];
sprintf(mqttMsg, "AT+MQTTPUB=0,\"dev/data\",\"{temp:%.1f,humi:%.1f}\",0,0\r\n", temp, humi);
for (char *p = mqttMsg; *p; p++) {
while (!(USART2->SR & USART_SR_TXE));
USART2->DR = *p;
}
}
// 蜂鸣器控制
void Buzzer_Alert(uint8_t state) {
if (state) BUZZER_PORT->BSRR = BUZZER_PIN;
else BUZZER_PORT->BRR = BUZZER_PIN;
}
代码说明
-
系统架构
- 主控:STM32F103C8T6(72MHz主频)
- 外设初始化:系统时钟、GPIO、I2C、USART
- 主循环:3秒采集周期
-
关键模块
- 温湿度采集:SHT30通过I2C通信,高精度模式(0x2400命令)
- OLED显示:软件SPI驱动,支持ASCII字符显示
- 报警控制:蜂鸣器高电平触发
- 云通信:ESP8266通过USART2发送MQTT指令到华为云
- 数据处理:CRC校验简化处理,实际应用需补全
-
通信协议
- I2C时序:标准模式(100kHz)
- MQTT消息格式:
AT+MQTTPUB=0,"dev/data","{temp:25.5,humi:60.2}",0,0
- 数据格式:JSON字符串包含温湿度值
-
异常处理
- 温度阈值:-5℃~8℃
- 湿度阈值:30%~90%
- 越限时触发蜂鸣器并在OLED显示"ALARM!!!"
注意:实际部署需补充功能
- OLED字库完整实现
- ESP8266的AT指令响应处理
- CRC校验算法(SHT30)
- 看门狗和异常复位机制
项目核心代码
#include "stm32f10x.h"
#include "sht30.h"
#include "oled.h"
#include "esp8266_mqtt.h"
#include "buzzer.h"
// 报警阈值定义
#define TEMP_HIGH_ALARM 8.0f
#define TEMP_LOW_ALARM -5.0f
#define HUMI_HIGH_ALARM 90.0f
#define HUMI_LOW_ALARM 30.0f
// 系统时钟初始化
void RCC_Configuration(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN;
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
}
// GPIO初始化
void GPIO_Configuration(void) {
// I2C1 (PB6-SCL, PB7-SDA)
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;
// USART1 (PA9-TX, PA10-RX)
GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_CNF10_0;
GPIOA->CRH |= GPIO_CRH_MODE9 | GPIO_CRH_MODE10;
// Buzzer (PB8)
GPIOB->CRH &= ~GPIO_CRH_CNF8;
GPIOB->CRH |= GPIO_CRH_MODE8;
GPIOB->ODR &= ~GPIO_ODR_ODR8;
}
// 延时函数
void Delay_ms(uint32_t ms) {
for(uint32_t i = 0; i < ms * 1000; i++);
}
int main(void) {
// 初始化系统
RCC_Configuration();
GPIO_Configuration();
SHT30_Init();
OLED_Init();
Buzzer_Init();
ESP8266_Init();
float temperature = 0, humidity = 0;
uint32_t upload_counter = 0;
uint8_t alarm_flag = 0;
while(1) {
// 读取温湿度数据
if(SHT30_Read(&temperature, &humidity) == 0) {
// OLED显示
OLED_Clear();
OLED_ShowString(0, 0, "Temp:");
OLED_ShowFloat(40, 0, temperature);
OLED_ShowString(0, 2, "Humi:");
OLED_ShowFloat(40, 2, humidity);
// 异常检测
if(temperature > TEMP_HIGH_ALARM || temperature < TEMP_LOW_ALARM ||
humidity > HUMI_HIGH_ALARM || humidity < HUMI_LOW_ALARM) {
Buzzer_On();
alarm_flag = 1;
// 发送报警到云平台
char alarm_msg[50];
sprintf(alarm_msg, "ALARM! Temp:%.1fC Humi:%.1f%%", temperature, humidity);
MQTT_Publish("alarm_topic", alarm_msg);
} else {
Buzzer_Off();
alarm_flag = 0;
}
// 定时上传数据到云平台 (每5秒)
if(++upload_counter >= 50) {
char data_msg[50];
sprintf(data_msg, "Temp:%.1fC,Humi:%.1f%%", temperature, humidity);
MQTT_Publish("data_topic", data_msg);
upload_counter = 0;
}
}
// 处理云端消息
if(ESP8266_ReceiveReady()) {
char cmd[32];
ESP8266_ReceiveData(cmd, sizeof(cmd));
if(strstr(cmd, "BUZZER_OFF")) {
Buzzer_Off();
}
}
Delay_ms(100); // 100ms延时
}
}
代码说明:
-
系统初始化:
- 配置系统时钟和必要外设时钟(I2C、USART、GPIO)
- 初始化I2C接口(SHT30传感器)
- 配置USART串口(ESP8266通信)
- 设置蜂鸣器控制引脚(PB8)
-
主循环功能:
- 温湿度采集:每100ms通过SHT30获取数据
- OLED显示:实时显示温湿度数值
- 异常检测:温度超出[-5°C, 8°C]或湿度超出[30%, 90%]范围时:
- 触发蜂鸣器报警
- 立即向华为云发送报警信息
- 定时上报:每5秒上传一次数据到云端
- 指令处理:接收云端下发的命令(如"BUZZER_OFF"关闭蜂鸣器)
-
关键参数:
- 使用PB8控制高电平触发蜂鸣器
- USART1(PA9/PA10)连接ESP8266
- I2C1(PB6/PB7)连接SHT30
- 报警阈值通过宏定义可修改
-
数据格式:
- 常规数据:“Temp:XX.XC,Humi:XX.X%”
- 报警数据:“ALARM! Temp:XX.XC Humi:XX.X%”
注意:实际开发需确保以下驱动文件已实现:
sht30.h/c
:SHT30传感器驱动oled.h/c
:OLED显示驱动esp8266_mqtt.h/c
:ESP8266通信及MQTT协议栈buzzer.h/c
:蜂鸣器控制驱动
总结
本设计成功构建了一套基于STM32的冷库智能监控与预警系统。系统以STM32F103C8T6为核心控制器,通过SHT30温湿度传感器实现冷库环境参数的精准采集,确保数据实时性与可靠性。异常状态触发有源蜂鸣器本地报警,同时通过ESP8266模块以MQTT协议将数据实时上传至华为云物联网平台,实现云端数据持久化与分析。
OLED显示屏提供本地化人机交互界面,直观展示当前温湿度及系统状态。远程监控功能通过Qt开发的手机APP实现,支持用户随时随地查看冷库状态并接收即时报警推送,大幅提升管理效率。供电模块采用DC 5V电源配合AMS1117稳压芯片,为系统提供稳定高效的能源支持。
整体设计融合了传感技术、物联网通信与移动终端应用,实现了冷库环境的全链路智能化管理。系统具备响应迅速、扩展性强、操作便捷等特点,为冷链仓储安全提供了可靠的技术保障,具有显著的实用价值和推广前景。
- 点赞
- 收藏
- 关注作者
评论(0)