
这次我们来看一个基于STM32的温湿度在线监测系统开源项目。对于嵌入式开发者、物联网爱好者或者任何需要在本地环境中部署一个稳定、可实时查看温湿度数据系统的朋友来说这个项目提供了一个从硬件到软件、从数据采集到Web界面展示的完整参考方案。它的核心价值在于“在线”与“系统化”——不仅完成了传感器数据的采集更实现了数据的网络上传、服务器存储以及可视化展示构成了一个完整的监测闭环。本文将带你快速梳理这个项目的核心能力、硬件门槛并重点演示如何从零开始搭建这套系统。我们会涵盖环境准备、STM32程序烧录、服务器端部署、Web界面访问以及数据验证的全流程。如果你关心如何将STM32采集的数据实时展示在网页上如何设计一个简单的后端API来接收和存储数据以及整个系统在运行时的资源占用情况那么这篇文章可以直接作为你的实践指南。1. 核心能力速览这个项目是一个典型的物联网IoT应用原型其核心在于打通了从物理传感器到网络云端的完整链路。下表概括了其主要技术特征能力项说明核心控制器STM32系列微控制器如STM32F103C8T6传感器DHT11或DHT22温湿度传感器网络通信通常通过ESP8266 WiFi模块实现AT指令集数据传输协议HTTP/HTTPS POST请求将数据上报至指定服务器服务器端可使用Flask、Django、Node.js等框架搭建接收并存储数据数据存储数据库可选SQLite、MySQL等用于历史数据记录前端展示Web页面通过图表如ECharts实时展示温湿度曲线系统特点低功耗、实时性、成本低、代码开源可定制适合场景实验室环境监测、小型仓库温湿度监控、智能家居数据采集、嵌入式学习项目从表格可以看出该项目并非一个单一的软件包而是一个由嵌入式端STM32ESP8266、服务器端和Web前端三部分组成的系统。硬件门槛主要集中在STM32开发板和WiFi模块的获取与连接上。2. 适用场景与使用边界这个开源项目最适合以下几类开发者和应用场景嵌入式与物联网学习者作为从单片机编程到网络通信再到全栈开发的综合实践案例。原型验证与课程设计适用于高校电子、计算机相关专业的课程设计或毕业设计功能完整且资料丰富。小型环境监测如家庭花房、小型实验室、档案室、服务器机柜等场景的温湿度定点监测。数据采集与上报演示需要验证传感器数据通过无线网络稳定上报至云端服务器的场景。需要注意的使用边界非高精度工业级应用DHT11/DHT22传感器精度和响应速度适用于一般环境监测不适用于对温湿度变化极为敏感或要求极高精度的工业控制场景。网络依赖性强系统正常运行依赖于稳定的WiFi网络。在网络中断期间数据将无法上传需要考虑本地缓存或断线重连机制本项目基础版本可能未实现。数据安全与隐私基础版本HTTP通信可能未加密传输的数据容易被截获。若用于涉及隐私或重要数据的场景需自行增加TLS加密HTTPS等安全措施。并发能力有限基于STM32和简单服务器框架设计初衷是单点或少量设备的数据上报无法直接承受海量设备的高并发访问。3. 环境准备与前置条件在开始部署之前请确保你已准备好以下软硬件环境。这是整个系统能够跑起来的基础。硬件清单STM32最小系统板如STM32F103C8T6核心板1个。温湿度传感器DHT11或DHT22模块1个。WiFi模块ESP8266如ESP-01S1个。USB转TTL串口模块用于给STM32烧录程序以及调试1个。杜邦线若干用于连接各模块。微型USB数据线用于给开发板供电。电脑用于开发、烧录和部署服务器。软件与环境清单STM32开发环境Keil MDK-ARM或STM32CubeIDE用于编译和下载STM32端的固件。STM32CubeMX用于生成初始化代码可选但推荐。服务器端开发环境Python 3.8或Node.js根据你选择的服务器语言。代码编辑器如VS Code、PyCharm等。网络环境一个可用的2.4GHz WiFi网络ESP8266需要连接至此网络。一台作为服务器的电脑可以是你的开发机需要有一个在局域网内可访问的IP地址。4. 系统架构与连接示意理解系统各部分的连接关系是成功部署的第一步。整个系统的数据流如下[DHT11/22传感器] --(单总线数据)-- [STM32 MCU] --(UART串口AT指令)-- [ESP8266 WiFi模块] | (WiFi网络) | V [后端服务器 API接口] | (存储/查询) V [前端Web页面] --(HTTP请求)-- [用户浏览器]硬件连接参考以STM32F103C8T6为例DHT11 连接 STM32VCC-3.3VGND-GNDDATA- 连接到STM32的某个GPIO口如PA1ESP8266 连接 STM32ESP8266 VCC-3.3V(注意必须接3.3V接5V可能烧毁)ESP8266 GND-GNDESP8266 TX- STM32的某个USART的RX引脚如PA3对应USART2_RXESP8266 RX- STM32的某个USART的TX引脚如PA2对应USART2_TXESP8266 CH_PD/EN-3.3V(使能引脚)请务必根据你实际使用的STM32型号和引脚定义在代码中修改相应的GPIO和USART配置。5. 嵌入式端STM32程序部署STM32端的核心任务是周期性读取DHT传感器数据并通过串口控制ESP8266模块将数据以HTTP POST请求的形式发送到服务器。步骤 5.1获取并准备工程代码从开源仓库如GitHub下载项目源码。找到STM32相关的工程目录。使用STM32CubeMX打开项目中的.ioc文件如果有检查并确认引脚配置特别是连接DHT和ESP8266的GPIO和USART与你的硬件连接一致。如果不一致需重新生成代码。如果没有.ioc文件则直接使用Keil或STM32CubeIDE打开已有工程。步骤 5.2修改关键配置参数在工程中通常有一个config.h或main.c文件的开头部分需要修改以下信息以匹配你的环境// 示例WiFi和服务器配置 #define WIFI_SSID \Your_WiFi_SSID\ // 你的WiFi名称 #define WIFI_PASSWORD \Your_WiFi_Password\ // 你的WiFi密码 #define SERVER_IP \192.168.1.100\ // 你的后端服务器IP地址 #define SERVER_PORT \5000\ // 你的后端服务端口 #define API_PATH \/api/sensor_data\ // 接收数据的API路径注意SERVER_IP应填写你运行后端服务的电脑在局域网中的IP地址而不是127.0.0.1。步骤 5.3编译与烧录在Keil或STM32CubeIDE中编译工程确保0错误0警告。使用USB转TTL模块连接STM32的串口1烧录口通过FlyMcu、STM32CubeProgrammer等工具将生成的.hex或.bin文件烧录到单片机中。烧录完成后将STM32通过USB线连接到电脑或电源适配器上供电。步骤 5.4初步调试打开一个串口调试助手如XCOM、Putty等连接到STM32与电脑通信的另一个串口用于打印日志的串口通常不是连接ESP8266的那个。观察串口输出。正常情况下你应该能看到STM32初始化、连接WiFi、获取传感器数据并尝试发送HTTP请求的日志信息。如果出现“WiFi连接失败”或“服务器连接失败”需要根据日志排查网络配置。6. 服务器端部署与API搭建服务器端负责提供一个HTTP API来接收STM32上报的数据并将其存入数据库同时为前端页面提供数据查询接口。这里以Python Flask框架 SQLite数据库为例因为它轻量且易于部署。步骤 6.1创建项目目录与文件mkdir temperature_humidity_server cd temperature_humidity_server步骤 6.2编写服务器主程序 (app.py)from flask import Flask, request, jsonify, render_template from flask_sqlalchemy import SQLAlchemy from datetime import datetime import os app Flask(__name__) # 配置SQLite数据库文件名为sensor.db basedir os.path.abspath(os.path.dirname(__file__)) app.config[SQLALCHEMY_DATABASE_URI] sqlite:/// os.path.join(basedir, sensor.db) app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False db SQLAlchemy(app) # 定义数据模型 class SensorData(db.Model): id db.Column(db.Integer, primary_keyTrue) temperature db.Column(db.Float, nullableFalse) # 温度 humidity db.Column(db.Float, nullableFalse) # 湿度 timestamp db.Column(db.DateTime, defaultdatetime.utcnow) # 时间戳 def __repr__(self): return fSensorData {self.temperature}C, {self.humidity}% # 创建数据库表首次运行 with app.app_context(): db.create_all() # API接口接收STM32上报的数据 app.route(/api/sensor_data, methods[POST]) def receive_sensor_data(): try: data request.get_json() if not data or temperature not in data or humidity not in data: return jsonify({error: Invalid data format}), 400 new_record SensorData( temperaturefloat(data[temperature]), humidityfloat(data[humidity]) ) db.session.add(new_record) db.session.commit() return jsonify({message: Data saved successfully, id: new_record.id}), 201 except Exception as e: db.session.rollback() return jsonify({error: str(e)}), 500 # API接口前端获取最新数据或历史数据 app.route(/api/get_data, methods[GET]) def get_sensor_data(): limit request.args.get(limit, default100, typeint) # 默认返回最近100条 data SensorData.query.order_by(SensorData.timestamp.desc()).limit(limit).all() result [{ temperature: d.temperature, humidity: d.humidity, timestamp: d.timestamp.isoformat() } for d in data] return jsonify(result) # 提供一个简单的测试页面 app.route(/) def index(): return render_template(index.html) # 需要创建 templates/index.html if __name__ __main__: # host0.0.0.0 允许局域网内其他设备访问 app.run(host0.0.0.0, port5000, debugTrue)步骤 6.3安装Python依赖在项目目录下创建requirements.txt文件Flask2.3.3 Flask-SQLAlchemy3.0.5然后安装pip install -r requirements.txt步骤 6.4创建前端页面 (templates/index.html)在项目目录下创建templates文件夹并在其中创建index.html。这里使用ECharts进行简单绘图。!DOCTYPE html html head meta charsetutf-8 title温湿度监测看板/title script srchttps://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js/script style #chart { width: 100%; height: 600px; } /style /head body h2STM32温湿度实时监测/h2 div idchart/div script const chartDom document.getElementById(chart); const myChart echarts.init(chartDom); let option { title: { text: 温湿度历史曲线 }, tooltip: { trigger: axis }, legend: { data: [温度(°C), 湿度(%)] }, xAxis: { type: time }, yAxis: [ { type: value, name: 温度(°C), position: left }, { type: value, name: 湿度(%), position: right } ], series: [ { name: 温度(°C), type: line, yAxisIndex: 0, data: [] }, { name: 湿度(%), type: line, yAxisIndex: 1, data: [] } ] }; myChart.setOption(option); // 定时从后端获取数据 function fetchData() { fetch(/api/get_data?limit50) .then(response response.json()) .then(data { const tempData []; const humiData []; data.reverse().forEach(item { // 反转以使时间正序 tempData.push([item.timestamp, item.temperature]); humiData.push([item.timestamp, item.humidity]); }); option.series[0].data tempData; option.series[1].data humiData; myChart.setOption(option); }); } // 初始加载并每5秒更新一次 fetchData(); setInterval(fetchData, 5000); /script /body /html步骤 6.5启动服务器在项目根目录下运行python app.py如果看到类似* Running on http://0.0.0.0:5000的输出说明服务器启动成功。7. 功能测试与全链路验证现在STM32设备、服务器和Web前端都已就绪我们需要验证整个数据链路是否通畅。测试 7.1验证服务器API在启动服务器后首先测试API接口是否可用。使用浏览器或curl命令访问http://你的服务器IP:5000/应该能看到一个带有空白图表的网页。使用curl或Postman模拟STM32发送一个POST请求curl -X POST http://你的服务器IP:5000/api/sensor_data \ -H Content-Type: application/json \ -d {temperature: 25.5, humidity: 60.2}如果返回{message: Data saved successfully, id: 1}说明接收接口正常。访问http://你的服务器IP:5000/api/get_data应该能看到一个包含你刚发送数据的JSON数组。测试 7.2验证STM32数据上报确保STM32已上电并且串口日志显示WiFi连接成功。观察串口日志看是否有“POST /api/sensor_data”相关的发送请求和服务器响应。正常的响应应该是HTTP状态码201或200。同时在服务器运行的命令行窗口中你应该能看到Flask处理POST请求的访问日志。测试 7.3验证Web页面数据展示在浏览器中刷新http://你的服务器IP:5000/页面。等待几秒页面每5秒自动请求一次数据图表上应该会显示出STM32上报的温湿度数据点并形成曲线。用手靠近或向DHT传感器哈气观察温湿度变化。稍等片刻刷新页面图表曲线应能体现最新的变化趋势。成功标准Web页面上的图表能够动态展示出从STM32传感器实时上报并存储到数据库中的温湿度数据且数据变化与实际环境相符。8. 资源占用与性能观察作为一个本地部署的监测系统其资源占用主要集中在服务器端和网络稳定性上。STM32端资源CPU与内存STM32F103的资源和功耗完全足以处理DHT数据读取和串口通信几乎无压力。网络流量每次上报的数据包很小几百字节即使按每秒1次的频率上报对网络带宽的影响也微乎其微。服务器端资源CPU与内存一个简单的Flask应用配合SQLite在数据量不大如每秒几条记录的情况下对现代电脑的CPU和内存占用可以忽略不计通常1% CPU几十MB内存。磁盘空间SQLite数据库文件大小增长缓慢。100万条温湿度记录每条约20字节大约占用20MB空间。关键观察点需要观察的是服务器的网络连接数和数据库写入性能。如果未来接入多个设备需要考虑使用更高效的WSGI服务器如Gunicorn和数据库如PostgreSQL/MySQL。网络性能稳定性这是系统中最脆弱的环节。ESP8266的WiFi连接稳定性、家庭路由器的性能、服务器所在电脑的网络状况都会影响数据上报的连续性。排查方法在服务器日志和STM32串口日志中观察连接超时、发送失败的记录。可以增加STM32端的重试机制和心跳包来增强鲁棒性。9. 常见问题与排查方法在部署和运行过程中你可能会遇到以下问题问题现象可能原因排查方式解决方案STM32串口无任何输出1. 电源未接通或电压不对。2. 串口线连接错误RX/TX反接。3. 烧录的程序未运行Boot模式不对。1. 检查电源指示灯。2. 用万用表测量电压。3. 检查USB转TTL模块与STM32的接线。1. 确保供电稳定3.3V/5V。2. 交换RX/TX线序试试。3. 确认BOOT0/BOOT1引脚配置正确重新烧录程序。ESP8266连接WiFi失败1. WiFi SSID/密码错误。2. ESP8266供电不足必须3.3V。3. 路由器屏蔽了新设备或设置了MAC过滤。1. 检查STM32代码中的WIFI_SSID和WIFI_PASSWORD。2. 单独测试ESP8266模块的AT指令。3. 查看路由器后台设备列表。1. 修正代码中的WiFi信息。2. 确保ESP8266的VCC接3.3V且电流足够建议单独供电测试。3. 关闭路由器的MAC过滤或添加ESP8266的MAC地址到白名单。HTTP POST请求失败 (服务器无响应)1. 服务器IP或端口错误。2. 服务器防火墙阻止了端口访问。3. 服务器程序未运行或崩溃。1. 在STM32串口日志中查看它尝试连接的完整URL。2. 在服务器电脑上用netstat -an | findstr :5000(Win) 或lsof -i:5000(Linux/Mac) 检查端口监听状态。3. 在服务器电脑本地用curl测试API是否可用。1. 修正代码中的SERVER_IP和SERVER_PORT。2. 关闭服务器电脑的防火墙或添加5000端口的入站规则。3. 确保在正确的目录下运行了python app.py且无报错。Web页面能打开但无数据1. 前端JS请求的API地址错误。2. 数据库中没有数据。3. 浏览器跨域问题如果前端和后端不同源。1. 按F12打开浏览器开发者工具查看“网络(Network)”标签页中JS发起的请求是否成功。2. 直接访问http://服务器IP:5000/api/get_data看是否有JSON数据返回。1. 检查index.html中fetch请求的URL。2. 确保STM32已成功上报过数据。3. 如果是跨域需要在Flask后端启用CORS支持安装flask-cors。数据上报不连续时有时无1. WiFi信号不稳定。2. ESP8266模块进入休眠或异常状态。3. STM32程序逻辑有bug未处理网络异常。1. 查看STM32串口日志中是否有频繁的“连接断开/重连”信息。2. 将ESP8266靠近路由器测试。1. 优化STM32代码增加网络状态检测和自动重连机制。2. 在HTTP请求失败时加入延时重试。10. 最佳实践与扩展建议在成功运行基础版本后可以考虑以下优化和扩展方向让系统更健壮、更实用增加数据本地缓存与断线续传在STM32的Flash或外置EEPROM中缓存一定量的历史数据。当网络恢复后优先上传缓存的数据防止数据丢失。使用HTTPS与简单认证为/api/sensor_data接口增加一个API Key验证并在服务器端配置SSL证书使用HTTPS协议提升数据传输安全性。# Flask中简单的Token验证示例 API_KEY \your_secret_key_here\ app.route(/api/sensor_data, methods[POST]) def receive_sensor_data(): if request.headers.get(X-API-Key) ! API_KEY: return jsonify({error: Unauthorized}), 401 # ... 其余处理逻辑优化前端体验使用Vue.js或React等框架重构前端增加实时数据刷新、数据导出、阈值报警、多设备切换等功能。部署到云服务器或内网穿透将Flask后端部署到云服务器如阿里云、腾讯云ECS或者使用花生壳、frp等工具进行内网穿透从而实现真正的“远程”在线监测。接入更多传感器STM32通常有多个IO口和通信接口可以同时接入光照强度传感器BH1750、大气压传感器BMP280等丰富监测维度。实现反向控制除了数据上报可以让服务器下发指令如通过Web页面点击按钮控制STM32连接的电灯、继电器等设备实现完整的物联网控制回路。这个基于STM32的温湿度在线监测系统开源项目其最大的价值在于提供了一个清晰、可运行的物联网全栈原型。它直观地展示了如何将物理世界的模拟量温湿度通过微控制器数字化再经由无线网络送入互联网最终通过Web技术进行可视化呈现。对于学习者它是一个绝佳的动手项目对于开发者它是一个可以快速修改和扩展的基础框架。建议先从最基础的版本跑通理解每一部分的代码和数据流然后再逐步尝试上述的扩展建议最终打造一个属于你自己的、功能完善的物联网监测应用。