资讯动态

ESP32环境监测桌面站实战:从传感器到数据可视化完整教程

发布时间:2026/9/10 0:44:42 来源:尧图企业网站定制
1. 项目概述与定位这个趣味项目到底解决什么问题说实话每次看到“趣味项目”这四个字我第一反应都不是“好玩”而是“这玩意能不能让我学到点真东西”。做了这么多年开发我见过太多号称趣味项目的教程要么是简单到一眼看穿的小玩具要么是上来就抛一堆概念、连环境都配不明白的半成品。这个“趣味项目与综合实战”的标题乍一看很笼统但它真正想表达的核心其实是把多个零散的技术点串起来做一个能跑、能看、能玩、还能拿得出手的完整作品。这不是单一的知识点学习而是一次小型的“全流程演练”。我选择做一个基于ESP32的环境监测桌面站作为实战载体。你别急着觉得“又是这种东西”我之所以选它是因为它天然具备“趣味综合”的属性硬件上要接传感器、做电路连接软件上要写嵌入式代码、做数据解析上层还要配合上位机界面、云端可视化甚至能接入语音播报、微信推送这类常见应用。一次项目做下来数电、编程、网络通信、前端展示全都覆盖了这才是“综合实战”四个字该有的分量。这个项目适合谁我个人认为有三类人特别适合拿来练手一是刚学完单片机基础、想找一个完整项目把零散知识点串起来的学生二是做嵌入式或物联网开发的工程师想快速验证一些想法、搭建原型工具三是单纯喜欢折腾的DIY爱好者做完放桌面上也很有成就感。无论你是哪一类这个项目都能让你在几个小时内获得一个看得见摸得着的成果。另外我提前说一句如果你本身对硬件完全不感兴趣只想要纯软件的实战项目那后面关于前端和可视化的部分也可以单独抽取出来用。我尽量把每一块拆开讲方便你按需取用。2. 整体设计与方案选型为什么是ESP32而不是树莓派或者纯前端2.1 核心需求解析一个桌面站需要哪些能力在设计之前我先把需求拆了一下。一个环境监测桌面站最终要做的无非是这几件事采集数据至少能测温度、湿度最好再加一个光照强度这才有“环境监测”的感觉。显示和交互本地要有一个小屏幕实时显示数据不能每次想看都得开电脑翻日志。联网上传数据要能发到云端或局域网服务器这样手机、电脑上才能远程查看。告警提醒当温度过高、湿度过大时能主动推一条消息到手机上。数据存储与回看不能只看实时值还得能查看历史趋势曲线否则就只是“玩具”而不是“工具”。这五个需求列出来方案选型就清晰了。树莓派虽然性能强但对于一个桌面站来说有点“杀鸡用牛刀”而且体积大、功耗高、启动慢作为桌面摆件并不合适。纯前端方案又解决不了数据采集的问题你总不能让浏览器直接读传感器。权衡下来ESP32几乎是这个场景下的最优解。2.2 为什么ESP32是当前阶段的最佳选择我选ESP32的原因其实很朴素就三条便宜、省电、自带网络。便宜这一点不用多说一块开发板十几二十块钱烧了也不心疼。省电是因为它支持深度睡眠如果你不需要实时刷新可以设定每隔几分钟醒来采一次数据、发完就睡实测下来一节18650电池能撑很久。最关键的第三点ESP32原生自带Wi-Fi和蓝牙不用外接模块直接就能联网。对比一下其他方案你就明白差距了用STM32的话你得另配ESP8266模块才能联网多一层通信就多一层排查难度用Arduino Uno的话性能太弱处理JSON解析和HTTP请求会比较吃力而且同样要外接网络模块。ESP32的核心是双核240MHz的处理器内置520KB的SRAM跑一个简单的HTTP客户端、做JSON解析完全绰绰有余。有一点我要特别提醒ESP32的型号很多如果你照着我的方案买建议选ESP32 DevKitC V4这种带USB串口芯片的经典版不要选那种极简裸片。因为我们要频繁烧录、看串口日志带USB转串口芯片的板子插上电脑就能用省去外接USB-TTL的麻烦。市面上有些超低价板子用的是CH340芯片驱动稍微麻烦一点不过胜在便宜看个人习惯吧。2.3 数据链路整体架构从传感器到手机屏幕整个系统的数据流向我从上到下理了一遍你在动手之前最好也在脑子里过一遍这条链路传感器DHT22 BH1750→ ESP32 GPIO读取 → 本地OLED屏即时显示 → ESP32通过Wi-Fi把数据POST到本地服务器 → 服务器写入SQLite数据库 → 前端页面通过API读取并绘制曲线 → 告警逻辑触发时调用企业微信Webhook推送消息。这条链路里每一个箭头都是一个技术点。传感器读取是硬件层面的I2C和单总线协议ESP32端是嵌入式开发服务器端是Python后端逻辑前端是数据可视化告警推送又涉及第三方API的调用。你单独看任何一个环节网上的教程都一大堆但能把它们串成一个完整闭环的才算真正的“综合实战”。3. 核心细节解析传感器、通信协议与关键参数3.1 传感器的选择DHT22与BH1750的实测对比传感器是数据源头选错了后面全白搭。市面上常见的温湿度传感器有DHT11、DHT22、SHT30、BME280这几款。我直接说结论这个项目用DHT22和BH1750的组合最合适。DHT11虽然便宜但精度实在太感人温度误差±2°C湿度误差±5%RH放桌面上测个大概还行想拿来对比数据趋势就力不从心了。DHT22精度高一个量级温度误差±0.5°C湿度误差±2%RH价格也就十块出头是性价比之选。SHT30和BME280精度更高但在我看来属于“性能溢出”而且BME280能测气压如果你没有气压需求多花的钱就是浪费。BH1750是数字光照传感器走I2C接口量程0到65535勒克斯室内室外都能覆盖。它的优势在于内置了光电二极管和ADC输出直接就是数字量不需要做模拟电压到光照强度的换算写代码时省很多事。我试过用光敏电阻ADC的方案且不说需要自己算分压和标定曲线光是不同批次光敏电阻的一致性就够让人头疼的所以强烈建议直接用BH1750。3.2 通信协议要点单总线与I2C的差异这里我展开讲讲两种通信协议因为很多新手卡就卡在“为什么这个传感器要这样接”。DHT22用的是单总线协议也就意味着数据只靠一根线传输。它的时序比较讲究主机先拉低总线至少18ms发出起始信号然后释放总线传感器响应后会拉低80us再拉高80us之后就是40bit的数据。读每一位的时候低电平时间相同高电平时间的长短决定这一位是0还是1。这套时序用代码实现不难但如果你用的是Arduino的delayMicroseconds函数精度必须注意。BH1750用的是I2C协议天生就是为多设备共享总线设计的。它只有两个信号线SCL时钟和SDA数据通过器件地址区分不同设备。BH1750的地址是固定的0x23ADDR引脚接低电平或0x5C接高电平。我在接线时习惯把ADDR引脚直接接地用默认地址0x23省得代码里还要改。注意I2C总线上拉电阻很重要。大多数开发板模块上已经自带了4.7K上拉电阻但如果你的传感器模块是裸板记得在SCL和SDA上各接一个4.7K到VCC否则通信会时好时坏特别折磨人。3.3 采样策略与数据精度处理数据采集不是越频繁越好。我这里说的“频率”包含两个层面传感器采样频率和网络上报频率。传感器方面DHT22的官方数据手册写得清楚采样间隔不得小于2秒否则读出来的数据会不准。这不是理论说法我实测过连续读间隔缩短到1秒时湿度值会明显偏高因为传感器内部的感湿元件还没来得及完成一次完整的响应循环。所以代码里最少要加2秒的延时我习惯用3秒留点余量。网络上报方面我的建议是本地显示可以2秒刷新一次但云端上报不要这么频繁。原因有三个一是高频上报会产生大量数据库记录时间长了查询会变慢二是如果用的是免费的云服务或API很可能有请求频率限制三是数据本身变化没这么快频繁上报属于浪费资源。我最终设置的是每30秒上报一次一天2880条记录画小时级和天级曲线都足够平滑。这个值你可以根据实际场景调但最好不要低于10秒。数据处理上还有一个容易忽略的点传感器读到的是原始值直接存库虽然没问题但展示时最好做一下平滑。我用的是一阶低通滤波公式很简单current current * 0.8 new_value * 0.2也就是当前显示值80%依赖历史值20%依赖新采样值。这样做的好处是当有人从旁边走过或者空调风突然吹到传感器上时曲线不会出现突兀的尖刺。0.8和0.2这两个系数你可以根据喜好调系数越小响应越快但平滑效果越差越大则相反。3.4 OLED屏幕显示SSD1306驱动的踩坑记录本地显示我用的是0.96寸的OLED屏驱动芯片是SSD1306分辨率128x64。这块屏幕本身没什么神秘的走I2C接口和BH1750可以挂在同一组I2C总线上地址是0x3C不冲突。真正要提的是字库问题。SSD1306本身不带字库只能以点阵方式显示。如果你只需要显示英文和数字用Adafruit SSD1306 Adafruit GFX库就够了现成的字体随便选。但如果你想让屏幕显示中文就得自己准备字模或者使用内置中文字库的屏幕变体。我后来图省事直接用了U8g2库它内置了多套中文字体比如u8g2_font_wqy12_t_gb2312调用简单内存占用也还能接受。屏幕刷新的时候有一点要注意OLED的寿命和残影问题主要出现在“静态画面长时间不变”的场景。虽然我们这个桌面站显示的数据每几秒就会变一次但如果某一项数值长时间不变那部分像素可能会“记住”那个图案。所以我每隔一分钟会做一次全屏清理重绘代价是有轻微闪屏不过面板上影响不大。这个也算经验之谈很多教程都不会提。4. 实操过程与核心环节实现从接线到部署的完整记录4.1 硬件清单与接线表先给出完整清单照着买就行组件型号/规格数量备注主控ESP32 DevKitC V41带USB串口芯片方便烧录调试温湿度传感器DHT221单总线协议DATA引脚接GPIO4光照传感器BH17501I2C协议地址0x23显示屏0.96寸OLED SSD13061I2C协议地址0x3C电源5V/2A USB电源或18650电池1建议用带开关的电源线连接线杜邦线公对母若干预留长度方便调整布局接线表如下ESP32引脚连接目标说明3V3DHT22 VCC / BH1750 VCC / OLED VCC统一供3.3V不要接5VGND所有模块GND共地必须接好否则通信飘忽不定GPIO4DHT22 DATA单总线数据引脚需接4.7K上拉GPIO21BH1750 SDA / OLED SDAI2C数据线GPIO22BH1750 SCL / OLED SCLI2C时钟线接线图上有个关键点DHT22的DATA引脚需要接一个4.7K到10K的上拉电阻到VCC。虽然有些模块板子上已经集成上拉电阻但如果你买的是裸传感器千万别省这一步。没有上拉电阻的话单总线通信时引脚会处于高阻态读回来的数据就会一直报错。4.2 嵌入式端代码采集、显示与上报的实现要点代码我直接给出核心框架你照着改自己的服务器地址和Wi-Fi信息就能跑。先把需要的库装好Adafruit Unified Sensor、Adafruit DHT、Adafruit SSD1306、Adafruit GFX还有ArduinoJson在库管理器里直接搜名字就能装。#include WiFi.h #include DHT.h #include Wire.h #include Adafruit_SSD1306.h #include BH1750.h #include ArduinoJson.h #define DHTPIN 4 #define DHTTYPE DHT22 #define OLED_ADDR 0x3C #define BH1750_ADDR 0x23 const char* ssid 你的Wi-Fi名; const char* password 你的Wi-Fi密码; const char* serverHost 192.168.1.100; // 改成你服务器IP const int serverPort 5000; DHT dht(DHTPIN, DHTTYPE); BH1750 lightMeter; Adafruit_SSD1306 display(128, 64, Wire, -1); float smoothTemp 0; float smoothHumi 0; float smoothLux 0; const float alpha 0.2; unsigned long lastUploadTime 0; const unsigned long uploadInterval 30000; // 30秒上报一次 unsigned long lastDisplayTime 0; const unsigned long displayInterval 2000; // 2秒刷新一次屏幕 void setup() { Serial.begin(115200); dht.begin(); Wire.begin(); lightMeter.begin(BH1750_ADDR); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.clearDisplay(); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(WiFi connected); } void loop() { unsigned long now millis(); // 读取传感器注意DHT22采样间隔至少2秒 float temp dht.readTemperature(); float humi dht.readHumidity(); float lux lightMeter.readLightLevel(); if (!isnan(temp) !isnan(humi)) { // 一阶低通滤波平滑处理 smoothTemp smoothTemp * (1 - alpha) temp * alpha; smoothHumi smoothHumi * (1 - alpha) humi * alpha; smoothLux smoothLux * (1 - alpha) lux * alpha; } if (now - lastDisplayTime displayInterval) { displayData(smoothTemp, smoothHumi, smoothLux); lastDisplayTime now; } if (now - lastUploadTime uploadInterval) { uploadData(smoothTemp, smoothHumi, smoothLux); lastUploadTime now; } }这段代码有几个地方我说明一下。第一dht.readTemperature()和readHumidity()有可能返回NaN尤其是传感器刚上电或引脚接触不良的时候。所以我在使用前用isnan做了判断防止NaN值一路传到屏幕上显示“nan°C”。第二我把“读取传感器”放在loop()每次循环里但DHT22的读取间隔是通过外部逻辑控制的判断时间差而不是简单加delay(2000)。这样做的好处是loop()不会因为在等待传感器而阻塞显示屏刷新和网络上报都能各自按自己的节奏运行。如果你用多个模块记住一个原则不要在循环体里用长延时用时间戳判断来实现非阻塞轮询。4.3 服务端与数据库用Flask五分钟搭一个数据接收接口服务端我选了Python的Flask框架原因很简单轻量、好写、文档多。你不需要用Django那种重型框架来干这点活杀鸡焉用牛刀。数据库选了SQLite文件型数据库零配置对于桌面站几千上万条记录的量级完全够用。from flask import Flask, request, jsonify from flask_cors import CORS import sqlite3 import time app Flask(__name__) CORS(app) DB_PATH sensor_data.db def init_db(): conn sqlite3.connect(DB_PATH) c conn.cursor() c.execute( CREATE TABLE IF NOT EXISTS readings ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, temperature REAL NOT NULL, humidity REAL NOT NULL, lux REAL NOT NULL ) ) conn.commit() conn.close() app.route(/api/data, methods[POST]) def receive_data(): data request.get_json() timestamp int(time.time()) conn sqlite3.connect(DB_PATH) c conn.cursor() c.execute( INSERT INTO readings (timestamp, temperature, humidity, lux) VALUES (?, ?, ?, ?), (timestamp, data[temperature], data[humidity], data[lux]) ) conn.commit() conn.close() return jsonify({status: ok}) app.route(/api/history, methods[GET]) def get_history(): hours request.args.get(hours, default24, typeint) start_time int(time.time()) - hours * 3600 conn sqlite3.connect(DB_PATH) c conn.cursor() c.execute( SELECT timestamp, temperature, humidity, lux FROM readings WHERE timestamp ? ORDER BY timestamp, (start_time,) ) rows c.fetchall() conn.close() result [ {timestamp: row[0], temperature: row[1], humidity: row[2], lux: row[3]} for row in rows ] return jsonify(result) if __name__ __main__: init_db() app.run(host0.0.0.0, port5000, debugFalse)接口设计就两个一个POST用来接收硬件上报的数据一个GET用来给前端取历史数据。POST接口里我故意没做认证因为是内网环境。但如果你要把这个服务暴露到公网哪怕只是测试也一定要加一层简单的Token认证否则任何人往你的接口POST垃圾数据数据库很快就变成垃圾场。启动服务后用浏览器访问http://你的IP:5000/api/history?hours1如果能看到JSON数据说明接口正常。ESP32上传失败时大多数情况是服务器地址填错了或者Wi-Fi和服务器不在同一个网段。排查顺序是先ping通服务器IP再用浏览器直接访问接口最后看ESP32串口日志。4.4 前端可视化绘制实时曲线与历史趋势可视化部分我用的是Hightcharts库选它的原因是文档全、支持时间序列图表而且上手门槛低。如果用ECharts当然也行但在时间轴处理和tooltip展示上Highcharts的个人体验略胜一筹。前端页面核心逻辑不复杂页面加载时请求后端历史接口绘制过去的曲线然后每隔10秒轮询一次最新数据。因为数据量不大我就没上WebSocket定时轮询在这个场景下完全够用重点是实现简单、好理解。!DOCTYPE html html head meta charsetutf-8 script srchttps://code.highcharts.com/highcharts.js/script title桌面环境监测站/title /head body div idcontainer stylewidth:100%; height:400px;/div script function fetchDataAndRender() { fetch(/api/history?hours24) .then(res res.json()) .then(data { const tempData data.map(item [item.timestamp * 1000, item.temperature]); const humiData data.map(item [item.timestamp * 1000, item.humidity]); const luxData data.map(item [item.timestamp * 1000, item.lux]); Highcharts.chart(container, { title: { text: 桌面环境数据24小时 }, xAxis: { type: datetime }, yAxis: [ { title: { text: 温度(°C) } }, { title: { text: 湿度(%) }, opposite: true }, { title: { text: 光照(lx) }, opposite: true } ], series: [ { name: 温度, data: tempData, yAxis: 0 }, { name: 湿度, data: humiData, yAxis: 1 }, { name: 光照, data: luxData, yAxis: 2 } ] }); }); } fetchDataAndRender(); setInterval(fetchDataAndRender, 30000); /script /body /html这个页面会每30秒自动刷新一次图表。你可能会问刚才说数据上报是30秒一次这里又是30秒轮询一次时间会不会对不上没关系图表请求的是“最近24小时的历史数据”即使最新一条数据稍有延迟也不影响整体趋势的展示。有一个小细节图表里x轴数据我乘了1000。因为JavaScript的时间戳单位是毫秒而后端返回的是秒级Unix时间戳。这个坑太常见了新手经常画出来的曲线时间对不上最后发现是单位问题。4.5 告警推送企业微信Webhook的接入流程告警功能我用的是企业微信的群机器人Webhook。这个方案的优点是免费、不需要申请企业认证、也不用搭建邮件服务器注册一个企业微信之后建一个群添加群机器人就能拿到Webhook地址。触发逻辑我放在ESP32端而不是服务端。原因也很简单ESP32本地直接判断传感器数值超过阈值立刻发请求到Webhook响应最快如果放在服务端判断就要依赖上报的周期30秒一次时效性差一些。当然更合理的做法是ESP32只管上报服务端做所有逻辑判断这样阈值修改不用重新烧录固件。我这里为了演示简便阈值写在ESP32代码里你要做产品级方案的话还是建议挪到服务端。void checkThresholdAndAlert(float temp, float humi, float lux) { String alertMsg ; if (temp 30.0) { alertMsg 温度过高: String(temp) °C\n; } if (humi 70.0) { alertMsg 湿度过大: String(humi) %\n; } if (alertMsg.length() 0) { sendWebhook(alertMsg); } } void sendWebhook(String msg) { HTTPClient http; http.begin(https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key你的key); http.addHeader(Content-Type, application/json); String jsonStr {\msgtype\: \text\, \text\: {\content\: \ msg \}}; int httpCode http.POST(jsonStr); if (httpCode ! 200) { Serial.printf(Webhook发送失败, HTTP code: %d\n, httpCode); } http.end(); }这里有个经验一定要做防抖处理否则告警会变成“鸣笛式”轰炸。比如温度超过了30°C阈值又恰好处于临界值附近震荡每次上报都会触发告警一分钟你能收到几十条消息。我的做法是同一类型告警10分钟内只发一次用一个变量记录上次发送时间。5. 常见问题与排查技巧实录5.1 传感器读数为NaN或0遇到NaN绝大多数情况是接线问题。先用万用表确认传感器VCC和GND有没有3.3V电压再检查DATA引脚有没有接对。DHT22数据传输时示波器上能看到明显的脉冲波形没有示波器的话用串口打印的方式快速验证Serial.println(dht.readTemperature())能正确输出数值就说明接线OK。如果是BH1750读数为0大概率是I2C地址不对或者地址线悬空导致的。你可以在代码里加一个I2C扫描函数把总线上所有设备的地址打印出来这样一眼就能看到BH1750实际在哪个地址上。一个容易忽略的点DHT22刚上电的几百毫秒内读取会失败。我一般会在setup()里先等1秒再初始化传感器有时候不写这个延时开机后第一次读取几乎必失败容易被误判成硬件故障。5.2 ESP32联网失败联网失败先看串口日志。如果一直是.....点号刷屏说明连接不上路由器。常见原因有三个Wi-Fi密码输错、路由器开了AP隔离、2.4G频段被关闭。第三个原因在现在特别常见很多新款路由器默认开启双频合一5G和2.4G用同一个SSID。ESP32只能连2.4G频段如果手机连接的是5G频段那和ESP32看到的就不是同一个“网络”。解决方法是登录路由器管理后台把双频合一关掉或者给2.4G频段单独设置一个SSID比如MyWiFi_2.4G。5.3 上报数据服务端收不到ESP32上报失败先用Chrome或者Postman手动模拟POST请求确认服务端接口本身是通的。如果Postman能成功但ESP32总超时注意检查代码里的serverHost是否填成了localhost或127.0.0.1。这两个地址在ESP32里指向它自己而不是你的电脑或服务器这是新手很容易踩的坑。5.4 SQLite数据库被写坏SQLite在极端情况下比如服务端突然断电、磁盘写满会出现database disk image is malformed的报错。我的习惯是定期备份数据库文件并且开启WAL模式。只需要在初始化数据库时执行一行SQLPRAGMA journal_modeWAL;WAL模式在并发读写时表现更好也能降低数据库文件被写坏的概率。不过如果你的服务端环境不太稳定定期用.backup命令备份数据库才是最终的保命手段。5.5 告警消息重复轰炸前面提到了防抖逻辑代码实现上就是记录上次告警时间戳。我贴一下核心代码unsigned long lastTempAlertTime 0; const unsigned long alertCooldown 600000; // 10分钟 void checkThresholdAndAlert(float temp, float humi, float lux) { unsigned long now millis(); if (temp 30.0 now - lastTempAlertTime alertCooldown) { sendWebhook(温度过高: String(temp) °C); lastTempAlertTime now; } }另一个同行踩过的坑是millis()在ESP32运行约49天后会溢出归零。如果你打算长期运行不清零重启判断时间差时要格外小心。好在桌面站一般不会连续运行两个月这个坑我也就是顺带提醒一下。5.6 常见问题速查表问题现象可能原因排查/解决方式温度显示NaNDHT22接线错误或上拉电阻缺失检查3.3V供电和DATA引脚的4.7K上拉电阻光照一直为0BH1750地址不对用I2C扫描代码打印实际地址OLED无显示I2C地址冲突或屏幕参数错误确认地址是0x3C确认是128x64分辨率ESP32连不上Wi-Fi路由器5G/2.4G双频合一关闭双频合一或给2.4G单独设SSID浏览器能打开接口但ESP32不行IP地址填错或端口没开用ping和curl从ESP32侧测试图表时间轴不对时间戳单位搞错JS里秒级时间戳要乘1000变成毫秒告警消息太多缺少防抖逻辑增加同类型告警10分钟冷却时间6. 从“跑通”到“好用”的进阶心得项目做到这里核心流程已经全部打通了。但“能跑”和“好用”之间还有一段距离。我把自己实操过程中积累的几个“后来才懂”的经验放在这你可以根据实际需求选择是否采纳。增加历史数据保留策略。SQLite库会越来越大尤其是当你把上报间隔缩短到10秒以后一天的记录就有8640条一个月就是25万条。我后来在初始化时加了一条定期清理逻辑保留最近30天的数据更早的自动删除。这样既能保证有足够的数据看趋势又不会让数据库无限膨胀。你也可以用服务器的cron定时任务来做效果是一样的。断电自动恢复。ESP32上电后会自动运行setup()函数所以只要代码里没有不可恢复的状态断电重启后它自己就能恢复工作。这一点是ESP32这类单片机方案比树莓派方案强的地方——没有操作系统启动流程上电到运行只要一两秒。不过要注意如果服务端没有自动启动断电恢复后前端会请求不到数据。我建议把Flask服务配置成系统服务systemd开机自启。网上有很多现成的systemd service模板照着改一下路径就行。云端部署。如果你不满足于只在局域网里看数据可以考虑把这个Flask服务部署到云服务器上。这样你在外面也能通过公网IP访问页面。但一定要记得加Token认证并且用HTTPS协议否则数据裸奔在公网上安全性堪忧。这也是我认为这个项目最值得扩展的方向之一——从“本地工具”升级为“远程服务”。低功耗改造。我后来做了一个便携版用18650电池供电ESP32每5分钟醒来一次采集数据、上报、然后进入深度睡眠。深度睡眠模式下电流只有10uA左右一颗3000mAh的电池能跑几个月。如果你对省电感兴趣关键就是esp_sleep_enable_timer_wakeup()和esp_deep_sleep_start()这两个API配合RTC GPIO或者定时器唤醒代码量不大但续航提升非常明显。最后再分享一个我自己挺喜欢的扩展我在前端页面上加了一个“当前状态”卡片除了显示实时数值还会根据温度、湿度、光照做一个综合舒适度评分用一个简单的规则引擎判断“舒适”“偏热”“偏冷”“干燥”等状态。虽然逻辑很简单但每天上班前瞄一眼桌面上这个小屏幕就能知道今天室内环境适不适合长时间工作这种“用起来了”的感觉才是做趣味项目最大的满足感。这个项目后续还能怎么扩展你可以在动手做完基础版本之后再慢慢琢磨。等你也把自己做的东西用起来我们会有更多可以交流的共同话题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价