文档 / 平台设计
固件与烧录
三种开发板的 PlatformIO 烧录环境、config.h 配置项逐项说明,以及设备从出厂到上线的完整流程。
固件代码在 firmware/esp32,基于 Arduino 框架 + PlatformIO 构建。同一份源码通过编译环境区分板型,新增设备只需改 src/config.h 对应分支。
开发板与烧录环境
platformio.ini 定义了三个环境,分别对应三种硬件:
| 环境 | 板型 | 传感器接线 | 其他引脚 |
|---|---|---|---|
esp32dev |
经典 ESP32 磁吸板 | 干簧管(磁吸) | 灯环 GPIO23、反馈灯 GPIO25、复位键 GPIO0 |
esp32-c3 |
ESP32-C3 按钮板 | 微动开关接 GPIO4–GND(内部上拉) | 无灯环/反馈灯,复位键为 GPIO9(BOOT) |
esp32-c3-reed |
ESP32-C3 磁吸板 | 干簧管接 GPIO5–GND | 同上,复位键 GPIO9(BOOT) |
烧录与串口监视:
cd firmware/esp32
# 按板型选一个环境烧录
pio run -e esp32dev --target upload
pio run -e esp32-c3 --target upload
pio run -e esp32-c3-reed --target upload
# 串口日志(115200)
pio device monitor -b 115200
注意事项:
- 固件启用 BLE + Wi-Fi + HTTPS 后超过默认 1MB 应用分区,三个环境都使用
huge_app.csv分区表。 - 唯一第三方依赖:
Adafruit NeoPixel(灯环)。 - ESP32-C3 的串口日志走原生 USB(
/dev/cu.usbmodem*),ARDUINO_USB_CDC_ON_BOOT=1与ARDUINO_USB_MODE=1两个 flag 必须同时定义,否则编译报'Serial' was not declared。 - 烧录成功的标志:串口打印
[Fanglian] ESP32 hub starting...。
config.h 配置详解
src/config.h 是设备的身份与网络配置,从 config.h.template 复制而来:
#define WIFI_SSID "" // 留空:全新设备,进蓝牙配网模式(正式出货方式)
#define WIFI_PASSWORD "" // 填入真实凭证仅用于开发调试板
#define API_BASE_URL "https://your-backend.example.com" // 含协议、无尾斜杠
#define HUB_ID "YOUR_HUB_ID_HERE" // 每台设备唯一,如 fl_reed_a3m8n1
#define HOUSEHOLD_ID "YOUR_HOUSEHOLD_ID_HERE" // 须与后端白名单一致
// 传感器类型三选一(取消注释恰好一个)
// #define SENSOR_TYPE_REED
// #define SENSOR_TYPE_FSR
// #define SENSOR_TYPE_BUTTON
// FSR402B 压力传感器 ADC 阈值(GPIO34,12 位 0-4095)
#define ADC_EMPTY_THRESHOLD 500
#define ADC_WITH_WATER_THRESHOLD 2500
关键规则:
- Wi-Fi / API / Hub 凭证一律从
config.h读取,不要在platformio.ini的build_flags里覆盖(覆盖了config.h会被排除编译,行为出乎意料)。 API_BASE_URL的协议决定 HTTP 客户端:http://用WiFiClient,https://用WiFiClientSecure,混用会 SSL 握手失败并重启。HUB_ID格式fl_<类型缩写>_<6位随机>,HOUSEHOLD_ID格式fl_hh_<6位随机>,每台设备全局唯一。config.h内部按ARDUINO_ESP32C3_DEV宏自动切换 C3 与经典 ESP32 的配置分支。
FSR 压力传感器校准
FSR402B 压阻传感器需要 10K(或更大)下拉电阻,否则 ADC 读数抖动。判定逻辑:
| ADC 读数 | 判定 |
|---|---|
< ADC_EMPTY_THRESHOLD |
无杯 |
| 介于两个阈值之间 | 杯子被拿起(触发上报) |
> ADC_WITH_WATER_THRESHOLD |
有杯有水 |
阈值只是初始值,必须用实际硬件校准:固件每 500ms 向串口打印一次 ADC 值,观察空杯/有杯读数后调整,保证 EMPTY_THRESHOLD < LIFTED_THRESHOLD。空闲值偏高(>2500)的传感器要相应上调阈值,避免误报「杯子被拿起」。
设备从出厂到上线
烧录固件(写入 HUB_ID/HOUSEHOLD_ID)
→ 服务器跑 seed-device-inventory.ts 录入白名单
→ 用户小程序蓝牙配网(下发家中 Wi-Fi)
→ 设备重启后自激活(拿 hub_token + 8 位配对码)
→ 用户在小程序输入配对码完成绑定
- 配网模式:无 Wi-Fi 凭证的全新设备,或长按 BOOT 键 5 秒的设备,进入配网模式——蓝灯闪烁,蓝牙广播名
FLAN-XXXX(MAC 后两位)。 - 蓝牙通道:自定义 GATT 服务
6c69616e-…,特征0001写 SSID、0002写密码(触发连接)、0003回传状态(ok:<ip>/fail),固件侧重试 3 次 × 15 秒。 - 自激活:联网后固件请求
POST /api/v1/devices/activate,后端校验白名单、签发hub_token(存 NVS)并生成 8 位数字配对码。 - 事件上报:激活后每 60 秒一次心跳,传感器触发即时上报,请求头携带
X-Hub-ID/X-Hub-Token;云端返回 403(未开通会员)时自动暂停业务事件上报。
用户侧操作详见新用户上手指南。