小型气象站上报网页

💡 划重点

  • 芯片选择:ESP32,自带Wi-Fi与蓝牙,主频240MHz,性价比高,内置Web Server能力避免了外接网络模块的开销。
  • 环境感知:BME280单芯片集成温度、湿度、气压三要素,I2C总线仅占用两个GPIO口,为系统留出充裕扩展空间。
  • 主动通风:PWM控制风扇按湿度阈值自动启停,避免传感器因长期潮湿环境导致读数漂移,延长器件寿命。
  • 本地网页上报:通过ESP32的Web Server在局域网内生成实时数据看板,减轻传感器待机功耗。
  • 整机成本控制在70元内,低于市售同功能成品的三分之一。

需求洞察

目标用户是阳台种植爱好者、小花园主以及户外设备DIY玩家。这类用户购买市售气象站常遇到误报率高、显示模块光看数据却无法接入自己的控制逻辑、电池续航短等问题。阳台和花园的微气候与城市气象站播报的宏观数据经常严重不符,而主流成品气象站无法按局部环境控制通风散热设备。本项目80元以下即可搭建一个“感知-控制-上报”闭环系统,可自定义逻辑且数据完全私有,痛点在于市售产品贵又不开放。

方案设计

物料清单

物料 数量 用途 估算单价(元)
ESP32 DevKitC 开发板 1 主控核心 28
BME280 模块(I2C) 1 温湿度气压测量 18
5V 涡轮风扇 1 通风执行器 7
NPN三极管(S8050) 1 风扇功率开关 0.5
1N5819 肖特基二极管 1 风扇反向电动势保护 0.5
面包板 + 跳线 若干 快速原型布线 8
5V/1A USB电源 1 供电(手机旧电源可替代) 0(闲置)
合计 62

接线与结构

核心代码

以下是PlatformIO(Arduino框架)编写的可运行骨架,采用非阻塞式任务轮询:


#include <Wire.h>
#include <Adafruit_BME280.h>
#include <WebServer.h>
#include <WiFi.h>

#define SEALEVELPRESSURE_HPA (1013.25)
#define PWM_PIN 25
#define LED_PIN 2
#define HUMID_THRESHOLD 65.0

Adafruit_BME280 bme;
WebServer server(80);

const char* ssid = "你的WiFi名";
const char* password = "你的密码";

bool fanState = false;
float tempC, humi, presPa;

void handleRoot() {
  String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>";
  html += "<meta http-equiv='refresh' content='5'></head><body>";
  html += "<h2>阳台小型气象站</h2>";
  html += "<p>温度: " + String(tempC) + " ℃</p>";
  html += "<p>湿度: " + String(humi) + " %</p>";
  html += "<p>气压: " + String(presPa / 100.0) + " hPa</p>";
  html += "<p>风扇: " + String(fanState ? "ON" : "OFF") + "</p>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void updateActuator() {
  int duty = 0;
  if (humi > HUMID_THRESHOLD) {
    float ratio = (humi - HUMID_THRESHOLD) / 20.0;
    duty = (int)(ratio * 255);
    duty = constrain(duty, 40, 255); // 最小占空比防止风扇堵转
    fanState = true;
  } else {
    fanState = false;
  }
  analogWrite(PWM_PIN, duty);
}

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  pinMode(LED_PIN, OUTPUT);
  pinMode(PWM_PIN, OUTPUT);

  if (!bme.begin(0x76)) {
    Serial.println("BME280 not found!");
    while (1) delay(10);
  }

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(200);
  }
  server.on("/", handleRoot);
  server.begin();
}

void loop() {
  static uint32_t lastSensor = 0;
  server.handleClient();

  if (millis() - lastSensor > 2000) {
    lastSensor = millis();
    tempC = bme.readTemperature();
    humi = bme.readHumidity();
    presPa = bme.readPressure();
    updateActuator();
    digitalWrite(LED_PIN, HIGH);
    delay(30);
    digitalWrite(LED_PIN, LOW);
  }
}

调试步骤

  1. 模块验证:先单独运行I2C扫描程序,确认BME280设备地址为0x76(部分模块为0x77)并出现在总线上。
  2. Wi-Fi 连接排障:注意ESP32开发板只能连接2.4GHz频段。若长时间连不上,用手机热点做A/B测试确认。
  3. PWM驱动波形验证:用万用表测量GPIO25在湿度阈值上下变化时是否有电平跳变,听风扇是否均匀转动、有无啸叫。
  4. 网页访问测试:打开串口监视器查看分配的IP地址,交叉验证weather.local是否能正确解析。若不行则清除浏览器DNS缓存。
  5. 长时间稳定性观察:持续运行12小时,检查温度读数较手持温湿度计的偏差,以及Web Server是否有内存泄漏导致拒绝服务的现象。

设计图

小型气象站上报网页结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报