💡 划重点
- 面向野钓、水库钓和夜钓场景,用 ESP32-S3 同时监测气压趋势与近岸水位。
- BMP280 走 I2C,SDA=GPIO8、SCL=GPIO9;水位传感器模拟输出接 GPIO1,占用 ADC1 通道,联网时更稳。
- 气压骤降、水位越限时,蜂鸣器间歇提示,LED 同步闪烁,串口输出本地日志。
- 18650 锂电加 5V 太阳能板,经 TP4056 充电、MT3608 升压到 5V 给开发板,适合户外连续值守。
- 整机物料估算 106 元,控制在 110 元目标内。
需求洞察
目标用户是经常去野钓、水库钓的户外爱好者。真实痛点有三个:一是气压变化和鱼口关系密切,但手机天气软件更新慢、位置粗,到了钓点往往无法判断未来一两小时气压是升是降;二是水库、河道夜钓时水位可能因上游放水或降雨上涨,人离钓箱稍远就有风险;三是户外插座少,普通提醒器要么续航短,要么怕雨淋。
这个项目值得做,是因为它把“气压趋势”和“近岸水位”两个低成本传感器放在一起,用一块 ESP32-S3 做本地判断,不依赖手机信号也能报警。成本低、结构简单,钓友可以装在钓箱侧壁或插在岸边支架上,属于能实际带出门的小设备。
方案设计
感知层由 BMP280 和水位传感器组成。BMP280 读取温度、气压,代码用慢速平均跟踪长期气压,当前气压低于慢速平均一定值即视为骤降趋势;水位传感器读取模拟量,现场校准干、湿两点后设置高位阈值。控制层用 ESP32-S3,负责采样、滤波、阈值判断和低功耗管理。执行层用有源蜂鸣器和 LED,报警时蜂鸣器短鸣、LED 闪烁,不报警时保持静默。日志/联网层默认把数据打印到串口并保留最近趋势;有 WiFi 的钓点可扩展 MQTT 上报,无网时完全本地运行。
电源层是 5V 太阳能板经 TP4056 给 18650 充电,TP4056 输出再经 MT3608 升压到 5V 供开发板。结构上做分层防水:电池与板卡在内层,BMP280 靠近带防水透气膜的透气孔,水位探头外置并做热缩密封。
物料清单
| 物料 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|
| ESP32-S3 开发板 | 1 | 主控、采样与判断 | 30 |
| BMP280 模块 | 1 | 气压、温度 | 8 |
| 水位传感器 | 1 | 近岸水位模拟量 | 10 |
| TP4056 充电模块 | 1 | 锂电充电保护 | 4 |
| 18650 锂电 | 1 | 储能 | 15 |
| 5V 2W 太阳能板 | 1 | 户外补电 | 18 |
| MT3608 升压模块 | 1 | 3.7V 升 5V | 3 |
| 有源蜂鸣器 | 1 | 声音报警 | 2 |
| LED 与电阻 | 1 套 | 状态指示 | 1 |
| 防水盒 | 1 | 防雨收纳 | 8 |
| 杜邦线、热缩管、密封胶 | 1 套 | 接线与密封 | 5 |
| 小开关 | 1 | 总电源 | 2 |
| 合计 | 106 |
接线与结构
BMP280:VCC 接 3.3V,GND 接 GND,SDA 接 GPIO8,SCL 接 GPIO9。水位传感器:VCC 接 3.3V,GND 接 GND,AO 接 GPIO1。蜂鸣器信号接 GPIO4,LED 串电阻接 GPIO5。TP4056 的 IN 接太阳能板 5V,BAT 接 18650,OUT 接 MT3608 输入,升压输出 5V 接开发板 5V 与 GND。GPIO1 属于 ADC1,适合模拟采样;GPIO8/9 作 I2C 不占启动 Strapping 关键脚。水位探头只测趋势,不泡在强腐蚀水体中长期使用,接头处用密封胶和热缩管处理。
核心代码
#include <Wire.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;
const int SDA_PIN = 8, SCL_PIN = 9;
const int WATER_PIN = 1, BUZZER_PIN = 4, LED_PIN = 5;
const int WATER_HIGH = 2200; // 现场校准后调整
const float PRESSURE_DROP = -1.2; // hPa,相对慢速平均
float pressureSlow = 0;
bool firstRun = true;
unsigned long lastRead = 0, lastLog = 0;
void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Wire.begin(SDA_PIN, SCL_PIN);
if (!bmp.begin(0x76)) {
while (1) delay(10);
}
analogReadResolution(12);
}
void loop() {
if (millis() - lastRead < 2000) return;
lastRead = millis();
int water = analogRead(WATER_PIN);
float pressure = bmp.readPressure() / 100.0;
float temp = bmp.readTemperature();
if (firstRun) { pressureSlow = pressure; firstRun = false; }
pressureSlow = pressureSlow * 0.995 + pressure * 0.005;
float trend = pressure - pressureSlow;
bool waterAlarm = water > WATER_HIGH;
bool pressureAlarm = trend < PRESSURE_DROP;
bool alarm = waterAlarm || pressureAlarm;
digitalWrite(LED_PIN, alarm ? HIGH : LOW);
if (alarm) {
delay(120);
digitalWrite(BUZZER_PIN, LOW);
}
if (millis() - lastLog > 30000) {
lastLog = millis();
Serial.printf("P=%.2f hPa T=%.1f C trend=%.2f water=%d alarm=%d\n",
}
}
实际部署可把采样间隔改为 30 秒,并关闭不必要的外设以降低功耗;需要联网时再在日志处追加 WiFi/MQTT 上报。
调试步骤
- 先只接 USB 供电,测开发板 3.3V、5V 是否正常,确认无短路。
- 运行 I2C 扫描,确认 BMP280 地址为 0x76 或 0x77,串口能读到气压和温度。
- 水位传感器分别置于空气、浅水中,记录干点和湿点模拟值,把 WATER_HIGH 设在湿点下方约 100 至 200。
- 用手机气压计或天气站对比 BMP280,静置十分钟观察趋势是否稳定。
- 吹气或轻微改变气压模拟骤降,确认蜂鸣器和 LED 能触发;再调 PRESSURE_DROP 阈值。
- 接太阳能和电池,遮光与强光下测充电电流,检查 TP4056 是否发热。
- 最后做淋水测试,重点检查水位探头引线、透气孔和盒盖密封。