基于ESP32的桌面小型气象站制作教程:温湿度采集与Web显示
发布时间:2026/9/1 3:32:36 作者:尧图编辑部 阅读量:1,286

简介这是一套基于ESP32单片机开发的小型气象站嵌入式项目源码面向嵌入式初学者、物联网课程设计学生及单片机爱好者解决气象数据采集、本地显示与Wi-Fi上传等典型IoT实践问题。资源共22个文件包含6个C源文件如main.c、wifi.c、http.c实现核心逻辑、6个头文件含LCD.h、wifi.h等模块化接口定义、3份README文档含项目说明与搭建指引以及sdkconfig编译配置、platformio.ini开发环境适配、.gitignore等工程支撑文件结构清晰符合Git仓库规范便于学习工程组织与模块化开发思路。目前已有380人学习下载。读者可直接编译烧录运行完整掌握ESP32驱动DHT/BMP等传感器、SPI/I2C通信、FreeRTOS多任务调度、LCD界面显示及HTTP协议上传至服务器的全流程代码注释充分关键环节如Wi-Fi连接重试、传感器异常判据均体现实际调试经验。 手机天气App显示晴天23度实际坐在电脑前还得再套件外套——这种体感与预报的落差很多人可能都经历过。正好手上有一块ESP32单片机开发板我直接用它做了一台小型气象站放在办公桌上连续跑了两周温湿度变化曲线比手机天气的笼统数据准得多。这个项目原理其实不复杂一块ESP32做控制核心搭配温湿度传感器采集空气数据再用OLED屏实时显示同时开一个Web页面可以在手机浏览器里远程查看。整个过程下来涉及单片机GPIO操作、传感器通信协议、嵌入式Web服务、数据校准等多块内容做一遍相当于把嵌入式开发的常见套路都过了一遍。做这个小项目的初衷很简单了解自己所在小环境的实时气象数据。城市天气预报的粒度是按片区发布的覆盖范围可能是几公里甚至几十公里我住的区域和天气App预报参考站点之间温度和湿度差异其实很明显。尤其湿度这个参数靠体感判断很不可靠下雨前的闷热和普通湿热在数据上差别很大有了气象站就能直观看到差异。项目的适用人群也相当广。对于嵌入式新手这个项目难度友好不涉及复杂的操作系统和驱动移植用Arduino框架就能全部搞定对于有经验的开发者则可以用来验证传感器选型、数据校准、无线通信等技术点。很多学生也把它当毕业设计题目稍加扩展就能做成带云平台的完整系统。作为一台“气象站”它采集的数据项是温度、湿度这两个基础项。如果想要更完整的天气数据可以再加上气压传感器通过气压变化趋势辅助判断天气变化。不过先把温湿度两个核心数据做好做准比盲目堆传感器更有价值。1. 从天气预报的误差说起这个项目要解决什么问题1.1 手机天气App的粒度困境天气App给出的温度通常是气象站监测点附近的数据经过数值模式计算后发布。问题在于这个监测点离你可能相隔很远。城市热岛效应、小区绿化率、楼层高度、朝向都会让体感温度和App数据差出一大截。办公室朝西的窗户下午晒进来室内温度能比App预报高3-4度这时候“今天25度”对你来说意义不大你真正需要的是桌面上此刻的温度。空气湿度的感知更主观。北方夏天35%的湿度和南方夏天75%的湿度体感天差地别但手机App只显示一个笼统的城市级数据。我做了这个项目之后才直观感受到室外湿度从60%快速蹿到85%的时候大概率会在几小时内下雨这个规律比看云图还准。1.2 小型气象站的合理定位自己做一个气象站并不是要替代国家气象台的预报系统而是要解决“局部微气候监测”这个真实需求。它适合放在办公桌、阳台、婴儿房、花房或者地下室长期记录一个固定点位的数据变化。对于养花、养宠物、存茶叶、控制加湿器这些场景桌面气象站的实时数据比气象台数据有用得多。我一开始想过要不要做成气象站的“全家桶”把风速、雨量、光照全加上。后来想明白了微气候监测的核心就两个维度温度和湿度。先拿这两个数据练手把数据链路做扎实以后想加气压、光照、PM2.5都是模块化的事情。1.3 这个项目适合谁来复现如果你能写简单的Arduino代码看得懂GPIO和I2C这个项目两三天就能跑起来。如果你完全零基础跟着这篇内容走遇到问题多搜一下一周内也能搞定。它不像做无人机或机器人那样涉及复杂的控制算法核心就是把传感器数据读出来、显示出来、传出去每条链路都有大量现成资料可以参考。2. 硬件选型对比ESP32、传感器与屏显方案的取舍2.1 为什么是ESP32而不是51单片机或树莓派Pico网上搜“单片机 小型气象站”会出现一大堆基于51单片机的方案。51单片机确实便宜几块钱一片但它的短板非常明显没有内置WiFi模块你要联网就得外接ESP8266之类的模块还得自己处理串口通信协议整个系统复杂度立刻上来了。树莓派Pico又是另一个极端虽然支持MicroPython但它的WiFi能力同样需要外接模块。ESP32则完全不同芯片本身就集成了2.4GHz WiFi和蓝牙供电后直接可以联网省去了大量外设连接工作。它还有两个核心、520KB SRAM、多路ADC/DAC、丰富的GPIO算力和外设资源对于气象站这种轻量级应用绰绰有余。最关键的一点是ESP32的价格做到了很低。现在一片ESP32-S3模组的单价能压到十几块钱和51单片机加ESP8266组合方案的价格差距已经小到可以忽略。社区庞大遇到问题能搜到大量现成解决方案这在实际开发中比硬件参数本身更重要。2.2 温湿度传感器的三选一小型气象站的核心传感器常见的有三种DHT11、DHT22和BME280。我用表格列一下它们的实测差异传感器DHT11DHT22BME280温度精度±2℃±0.5℃±0.5℃典型±0.1℃湿度精度±5%RH±2%RH±3%RH采样频率1Hz0.5Hz最高可到100Hz以上通信方式单总线单总线I2C/SPI附加数据无无气压价格2-4元8-12元8-15元抗干扰能力一般较好好DHT11只能算“体验装”适合入门搞明白单总线协议数据精度当个玩具正好但要做正经气象测量它给出的温度和体感温度能差出好几度。DHT22的精度提升明显单总线通信方式和DHT11一样代码迁移成本低。BME280则是“完全体”除了温湿度还能测气压I2C接口连接也更简单只需要两根数据线更多时候我推荐直接用BME280。选传感器的核心逻辑是看你做项目的目的。如果是学习通信协议和基本开发流程DHT11够用如果是想摆在家里长期监测数据并追求可靠性选BME280一步到位。2.3 显示与交互OLED优先Web页面兜底数据采集出来之后需要一个直观的呈现方式。我当时选了0.96寸的SSD1306 OLED屏分辨率128x64用I2C接口连接只需占用两个引脚。OLED自发光对比度高放在桌面上很有科技感。但OLED屏只能显示当前实时数据视角有限。为了让数据在不同设备上都能访问我同时开了ESP32的Web服务器这样手机、平板甚至办公室的电脑只要在同一局域网内打开浏览器就能看到数据。两种方式互为补充屏幕看实时网页看趋势实际使用下来很顺手。OLED和Web这样的双通道方案也是我推荐的组合方式在采集数据之外还能练习一下Web Server的搭建。3. Arduino IDE下的ESP32开发环境在线安装失败与离线救场3.1 开发框架选什么ESP32官方支持框架主要有三个ESP-IDF、Arduino框架和MicroPython。ESP-IDF功能最全是官方提供的完整开发套件但其工程结构复杂、编译时间偏长对刚入门的朋友并不友好。Arduino框架把底层大部分细节封装掉了写代码时直接调用digitalWrite、analogRead这些API就行开发效率很高。MicroPython则是偏脚本化的方案适合快速验证但对硬件资源的精细控制不如前两者。我这个项目用的是Arduino框架。理由很简单相关库最成熟DHT传感器、SSD1306 OLED、WebServer都有现成的库网上能找到大量示例代码整个项目两三百行C代码足够搞定。3.2 在线安装ESP32板卡支持包在Arduino IDE里安装ESP32支持正常流程是打开“文件-首选项”在“附加开发板管理器网址”里填上乐鑫的JSON地址然后在“开发板管理器”里搜索esp32安装。这个JSON地址很长建议直接从乐鑫官方GitHub获取不要用网上转载的旧地址因为旧版本经常出现安装到一半失败的情况。实际安装时最常见的坑就是下载太慢甚至直接失败。原因是该JSON和后续要下载的工具链文件都在国外服务器上网络高峰期几乎动不了。遇到这种情况我建议分两步走先单独下载JSON内容确认地址有效然后把附加开发板管理器网址换成国内镜像地址再用镜像源安装。镜像下载速度能到几兆每秒几分钟就能装完。3.3 离线安装包作为兜底方案如果你试过各种方法仍然失败备选方案是使用离线安装包。很多开发者会把ESP32板卡支持包连同工具链一起打包放到网盘下载后解压到Arduino IDE的hardware目录下重启IDE就能识别无需走开发板管理器。这种离线包的好处是一步到位坏处是版本可能不是最新如果你的项目用到了较新的库函数可能需要检查版本兼容性。我在搭建环境时是先用在线方式装了一部分剩下载不动的工具链改用手动下载压缩包放进指定目录的办法解决的。具体路径在你的用户目录下Arduino15/staging/packages目录把下载好的工具压缩包放进去再回到IDE里重试安装IDE就会直接从本地读取而不是重新下载。这个方法比找完整离线包更灵活版本也能自己控制。3.4 板型和烧录参数设置板卡支持包装好后在“工具-开发板”里选择正确的ESP32型号。我的是ESP32 DevKit V1主控芯片是ESP32-WROOM-32在列表里选“ESP32 Dev Module”即可。接下来是烧录参数USB线用数据线不要用充电线充电线连上后电脑根本识别不到串口开发板选择ESP32 Dev Module端口选择设备管理器里识别出来的COM口Flash Size4MB一般的ESP32模组都是4MBPartition Scheme默认的Default 4MB with spiffs除非你用了LVGL等大体积图形库才需要考虑调整波特率默认921600就行个别电脑不稳定时改到115200这些参数大部分保持默认就可以唯一需要特别留意的是Partition Scheme。热搜词里频繁出现的“esp32 spiffs插件”其实就是关于分区表的——你需要在文件系统方案里预留出File System大小SPIFFS才能存得下网页文件和历史数据。默认分区表通常会划分出1.4MB左右的SPIFFS空间完全够用。3.5 烧录失败的及时止损如果你点了烧录按钮串口输出卡在“Connecting…”超过20秒别傻等。直接按住开发板上的BOOT键再点一次烧录看到连接中的提示时松开BOOT键。这个操作能解决90%的ESP32首次烧录问题。如果按住BOOT还是不行大概率是USB转串口芯片驱动没装好去官方下载CP2102或CH340的驱动重装一遍。4. 传感器接线与采集原理单总线与I2C两条路4.1 DHT系列单总线协议DHT22和DHT11使用单总线通信也就是通过一根数据线完成双向通信。单片机先拉低数据线超过18ms然后释放并拉高等待传感器响应。传感器收到起始信号后会拉低80us表示应答然后连续发送40bit数据包含湿度整数部分、湿度小数部分、温度整数部分、温度小数部分和校验和。数据编码方式并不复杂每一位的起始都是低电平50us随后如果高电平持续26-28us表示0持续70us表示1。所谓“单总线”本质上就是对高低电平的时序测量。ESP32读取时需要用微秒级延时来采样脉宽Arduino框架中可以用pulseIn函数来做我在项目里则是直接读GPIO电平变化并计时更可控。接线部分DHT22是四针插座VCC接3.3V或5VGND接GNDDATA接任意一个GPIO我用了GPIO4。数据线上通常需要接一个4.7k-10k的上拉电阻。ESP32的GPIO内部可选择使能上拉但在长线下还是建议外接电阻更稳定。4.2 BME280的I2C方案如果换成BME280通信协议就变成了I2C。接线更简单一共四根线VCC、GND、SCL、SDA。ESP32的I2C引脚在Arduino默认配置下通常是GPIO21SDA和GPIO22SCL在代码里也可以自定义引脚灵活度很高。I2C本身是总线协议一条总线上可以挂多个设备每个设备有唯一地址。BME280的I2C默认地址是0x76如果SDO引脚接地则变成0x77。我最初没注意到这个问题把地址写成了0x77结果一直读不到数据后来加上地址扫描代码才发现实际地址是0x76。这里也顺带提一句如果遇到外设读不到的问题先在代码里跑一个I2C扫描程序把总线上所有设备地址列出来基本能定位问题。BME280读取数据时需要先读取校准寄存器把芯片出厂时烧录的校准参数加载进来然后触发一次温压湿测量等数据就绪后再从对应寄存器读出原始值最后用官方公式换算成实际物理量。Arduino环境下有Adafruit_BME280库和SparkFun BME280库可以直接调用前者更常用。如果不想依赖库官方也能下载到BME280的计算驱动移植也很快。4.3 供电与电平问题ESP32是3.3V逻辑电平而DHT22支持3.3V-5V供电逻辑电平是兼容的所以可以直接用GPIO驱动。OLED屏SSD1306同样是3.3V逻辑但有些模块板上带了稳压和电平转换接5V供电也行。供电的基本原则是所有模块的VCC接同一个电源轨避免地线环路导致的数据异常。我的项目中用电脑USB口供电的。要注意的是部分廉价USB线线阻较大会导致ESP32的3.3V稳压器输入电压不足进而引发传感器读数异常或WiFi反复重启。如果遇到这种情况尝试换一根粗短的USB线或者直接用5V/2A的手机充电器供电问题通常立刻解决。5. 核心代码架构数据读取、滤波与异常值剔除5.1 主循环的设计思路我按照状态机的思路设计了主程序结构而不是简单地把所有代码堆进loop函数。主循环大概分四步从传感器读取原始温湿度数据对数据进行滤波和异常值剔除更新OLED显示处理Web请求因为DHT22单总线读取消耗时间偏长如果每次都在loop里同步读取会导致Web响应明显卡顿。我采用的方案是传感器读取放在时间戳控制的分支里5秒读一次两个读数之间做Web服务器的事件循环处理。这样Web响应始终流畅传感器数据也不会因为读取频率太高而失败。5.2 数据滤波与异常剔除传感器数据偶尔会出现突跳值DHT22尤其容易在电压波动时冒出离谱数据。如果不加处理Web页面上的曲线会突然出现一个尖峰还容易误导对天气的判断。我写了一个滑动窗口滤波函数保留最近5次读数取中间三个值的平均值。这样既不会像单纯算术平均那样被极端值拉偏又能平滑轻微噪声。异常剔除的规则很简单如果新读数和上一次读数差值超过3度或10%湿度认为这是一次异常读丢弃并且计数一次。如果连续10次都是异常说明传感器大概率真的故障或者接线松了这时在OLED上显示错误标识。这套逻辑在项目实测里表现得非常稳定再也没有出现过尖峰。5.3 核心代码示例下面是项目里读取BME280数据并进行滑动滤波的核心片段使用Arduino框架#include Wire.h #include Adafruit_Sensor.h #include Adafruit_BME280.h #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; const int WINDOW_SIZE 5; float tempWindow[WINDOW_SIZE]; float humiWindow[WINDOW_SIZE]; int windowIndex 0; int windowCount 0; float currentTemp 0.0; float currentHumi 0.0; bool initSensor() { if (!bme.begin(0x76)) { return false; } return true; } float readFiltered(float* values, int size) { float sorted[size]; memcpy(sorted, values, sizeof(float) * size); for (int i 0; i size - 1; i) { for (int j i 1; j size; j) { if (sorted[j] sorted[i]) { float tmp sorted[i]; sorted[i] sorted[j]; sorted[j] tmp; } } } return sorted[size / 2]; // 取中值 } void readBME() { float t bme.readTemperature(); float h bme.readHumidity(); if (isnan(t) || isnan(h)) { return; } tempWindow[windowIndex] t; humiWindow[windowIndex] h; windowIndex (windowIndex 1) % WINDOW_SIZE; if (windowCount WINDOW_SIZE) windowCount; if (windowCount 3) { currentTemp readFiltered(tempWindow, windowCount); currentHumi readFiltered(humiWindow, windowCount); } }注意代码里的isnan判断很重要。BME280在初始化失败或读取异常时库函数可能返回NaN不做判断的话这个NaN会一路传到Web页面显示成“nan℃”排查起来很费劲。我在项目里也遇到过这种“偶发性NaN”基本都是没加这个判断导致的。5.4 代码组织与小技巧我把传感器读取、OLED更新、Web服务这三块各自封装成独立函数主文件里只保留setup和loop逻辑一目了然。调试时用宏开关控制调试信息的输出比如定义#define DEBUG_ENABLE 1就开启串口打印传感器的原始值和滤波后的值这样后续调试数据时能快速定位是哪一层出了问题。6. 本地OLED与Web远程展示双通道各司其职6.1 SSD1306 OLED屏幕的接入OLED屏的驱动使用Adafruit_SSD1306库配合Adafruit_GFX图形库使用。初始化代码如下#include Wire.h #include Adafruit_GFX.h #include Adafruit_SSD1306.h #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, Wire, OLED_RESET); void initOLED() { if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(OLED init failed); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); }初始化时地址是0x3C如果你的模块地址不同也是先扫描确认。屏幕刷新时我会先调用display.clearDisplay()清屏再绘制防止上一帧的文字残影。绘制内容按行划分上方两行显示温度中间两行显示湿度底部留白显示最近一次数据采集的时间距离视觉上比较直观但代码量不大。6.2 Web Server实现远程查看ESP32的Arduino库自带WebServer类用起来非常直观。我注册了一个根路径的handler访问时返回一个简单的HTML页面。HTML里直接用JavaScript定时器每隔3秒向/data接口发一次请求拿回JSON格式的温湿度数据并更新页面数值。服务端代码大概长这样#include WebServer.h WebServer server(80); void handleRoot() { String html htmlbodyh1ESP32 Weather/h1; html pTemperature: span idt/span/p; html pHumidity: span idh/span/p; html scriptsetInterval((){; html fetch(/data).then(rr.json()).then(d{; html document.getElementById(t).innerTextd.temp;; html document.getElementById(h).innerTextd.humi;; html });}, 3000);/script/body/html; server.send(200, text/html, html); } void handleData() { String json {\temp\: String(currentTemp, 1) ,\humi\: String(currentHumi, 1) }; server.send(200, application/json, json); } void setupServer() { server.on(/, handleRoot); server.on(/data, handleData); server.begin(); }这块代码看起来简单但在实际使用时要注意ESP32的WebServer默认是单线程的一个请求没处理完不会转到下一个。如果你在loop里做耗时操作Web页面就会超时。所以我在主循环里严格控制耗时逻辑让WebServer.loop()每次都能及时处理请求。6.3 SPIFFS存储网页与历史数据如果你的网页比较复杂不想把HTML字符串硬编码在源码里可以把HTML文件放到存储中再用SPIFFS读取。热搜词里的“esp32 spiffs插件”指的就是这个用途。在Arduino IDE中安装ESP32插件后会提供一个“ESP32 Sketch Data Upload”选项把data目录下的文件直接上传到开发板的SPIFFS分区。我在项目里用SPIFFS保存了一个config.json文件记录最近1000条采样记录的摘要以追加方式写入。写入策略是每小时写一条粗略记录避免频繁擦写Flash导致寿命问题。ESP32的Flash擦写寿命是10万次级别如果你每隔几秒就写一次一年下来擦写次数可能非常可观存储芯片容易提前报废。所以再强调一次写存储一定要控频30秒以上写一次比较稳妥。6.4 进阶LVGL界面热搜词里出现“eezstudio lvgl 9.x ui设计教程_基于esp32”。如果想把OLED屏幕替换成彩屏如ST7789或ILI9341可以做一套LVGL图形界面把温湿度曲线、历史柱状图都画上去。LVGL配合SquareLine Studio或EEZ Studio这类拖拽式UI工具开发效率比手写图形代码高很多。不过LVGL的代价是Flash体积和RAM占用明显变大需要把分区表改成大App分区。默认的Default 4MB with spiffs分区表在LVGL工程里有时不够用要用“Default 4MB with app3MB fatfs”或自定义分区表。这也是为什么很多人装LVGL项目时卡在编译或烧录阶段——不是代码写错了而是分区表没配好。7. 与标准仪器对比误差来源和一次性校准方法7.1 实测对比结果项目完成后我把它和房间里的水银温度计、米家温湿度计并排放了48小时每2小时记录一次数据。实测下来BME280温度和米家温湿度计的最大偏差在0.6℃以内湿度偏差最大4%在可接受范围内。DHT22对比测试中温差最大到1.2℃湿度最大偏差6%精度确实比BME280低一档。偏差来源主要有几个一是传感器本身出厂校准精度不同BME280出厂前做了更精细的标定二是摆放位置造成辐射热差异传感器靠墙近墙面温度和空气温度不同会产生局部微环境三是米家传感器本身也未必是精确参考只能做相对比较。7.2 自查流程如果你想校准自己的气象站按下面这个流程走把气象站和标准温度计放在同一位置避免阳光直射和空调风口连续记录至少24小时数据统计分析差值的平均值和最大偏差如果平均值偏离超过1℃在软件里加偏移补偿如果偏差随机性大检查探头位置、电源稳定性、是否靠近发热元件7.3 传感器放置的经验这部分属于“不实际接个项目很难意识到”的坑。传感器和ESP32尽量分开一些距离如果传感器紧挨着主板主板元器件发热会让读数整体偏高1-2℃。我的做法是用杜邦线把BME280模块单独引到距离主板10厘米开外的地方读数立刻降了下来。另外传感器不要放在塑料外壳的正中心外壳内部空气不流通温度会越积越高。8. 调试过程中的典型故障与排查日志8.1 烧录失败经典排查链路烧录失败是ESP32项目中最容易遇到的一类问题。我总结的排查顺序是电脑认不到COM口——先换USB线确认是数据线而不是充电线手动选择端口失败——检查CP2102或CH340串口芯片驱动是否安装能认到端口但连接失败——按住开发板上的BOOT键然后点烧录看到“Connecting…”提示时松开BOOT烧录到一半中断——Flash Size选错或者波特率太高改115200重试烧录完成但板子没反应——检查开发板型号选择WROOM-32选择ESP32 Dev ModuleS3芯片则选择ESP32S3 Dev Module8.2 传感器读不到数据的排查读不到DHT22或BME280数据时先看串口打印。我遇到的情况中80%的根源是接线问题线序接反DHT22是有方向的插反了完全没有响应I2C上拉电阻问题某些ESP32开发板内部上拉电阻较弱需要外部加10k电阻地址错误BME280的地址和网上示例不一致供电不足传感器模块的VCC接到了3.3V稳压能力较差的引脚排查时先跑一个I2C扫描程序把总线上所有设备地址打印出来。如果扫描到设备但读不到数据再检查代码中的寄存器配置如果扫描不到设备八成是硬件连接问题。#include Wire.h void setup() { Serial.begin(115200); Wire.begin(21, 22); Serial.println(\nI2C Scanner); } void loop() { byte error, address; int nDevices 0; for (address 1; address 127; address) { Wire.beginTransmission(address); error Wire.endTransmission(); if (error 0) { Serial.print(I2C device found at address 0x); if (address 16) Serial.print(0); Serial.print(address, HEX); Serial.println( !); nDevices; } } if (nDevices 0) { Serial.println(No I2C devices found); } delay(5000); }这段代码实测定位过两次接线问题一次是SCL和SDA接反一次是模块供电脚松了。扫描程序本身虽然简单但确实是排查I2C外设问题的第一利器。8.3 数据不断的尖峰DHT22数据偶发尖峰排查后确认是USB供电电压不稳。电脑的前置USB口供电较弱ESP32 WiFi发射时电流波动大导致传感器供电瞬间跌落。解决方法是换独立电源或者在5V电源和传感器VCC之间并联一个100uF电解电容和一个0.1uF陶瓷电容实测尖峰几乎消失。8.4 Web访问不稳定的处理Web页面打不开先ping一下ESP32的IP地址能通说明网络层OK。再检查端口WebServer默认监听80端口如果路由器和其他服务占了80端口需要换端口号。如果网页能打开但是数据不刷新检查前端代码里的API路径是否和服务端注册的路径一致路径问题在前端不容易报错。我在调试中踩过一个典型的坑在浏览器里直接打开IP地址能显示页面但数据一直是0原因是服务端注册的是/api/data而HTML代码里请求的是/data漏了/api前缀看起来像是后端JSON有问题实际是前端路径不匹配。这种问题用浏览器开发者工具看一下网络请求就能发现。9. 做完基础版之后值得再做的扩展方向这个项目做完之后我只是把它当成一台“桌面温度计”用了一段时间但它完全可以继续往下延伸。比如把数据上报到MQTT服务器配合智能家居做温度联动或者在Web页面上加一个指数平滑预测根据最近半小时的温度变化趋势预估下一步走向再或者加一个雨水传感器、风杯式风速计做成真正意义上的户外小型气象站。我个人的建议是先把这个基础版跑稳把精度校准做到心里有数再考虑扩展。传感器堆得多不难难的是每个数据都可靠。我在实际使用中发现气象站最有用的数据反而不是当下温度而是温度变化趋势和温湿度联动关系比如湿度快速上升往往预示着后续天气变化这些规律需要长期可靠的数据积累才能总结出来。等你的ESP32气象站连续稳定运行一个月再回头看这些数据和体感之间的对应关系会发现原来天气预报里很多细节完全可以通过自己的小设备捕捉到。按照我的经验做这类项目最重要的是把数据链路打通——传感器到主控、主控到显示、主控到Web中间任何一环断了都会让整个系统变得不可用。这个项目麻雀虽小五脏俱全做完之后嵌入式开发的很多核心思路都会有直观的理解。如果你也想上手做一个建议按文中顺序分模块调试每调通一块再往下走成功率会高很多。本文还有配套的精品资源点击获取