说明¶
概述¶
在线传感模块提供连续的传感器数据采集和传输功能。它支持可配置的采样频率和多个输出通道(MQTT、串口,以及可选的LCD),实现传感器数据的实时监控。
功能特性¶
- ✅ 可配置采样频率(默认:1.0 Hz,范围:0.1 - 300 Hz,实测上限:~200 Hz)
- ✅ MQTT传输(开启/关闭)
- ✅ 串口输出(开启/关闭)
- ✅ 可选LCD显示(当定义
TINY_MEASUREMENT_ENABLE_LCD时) - ✅ 使用ESP定时器进行固定频率数据采集
- ✅ 自动数据格式化
- ✅ 线程安全操作
- ✅ 运行时配置更新
架构¶
基于定时器的采样¶
模块使用ESP定时器进行精确的周期性采样:
- 定时器创建:创建周期定时器,周期 = 1 / 采样频率
- 定时器回调:在每个定时器滴答时执行,读取传感器数据
- 数据输出:格式化数据并输出到配置的通道(MQTT、串口、LCD)
数据流¶
实现原理¶
架构概述¶
在线感知模块采用**基于定时器的事件驱动架构**,使用ESP-IDF的高精度定时器系统。设计优先考虑实时数据流传输,最小化延迟。
核心组件¶
-
ESP定时器(esp_timer)
- 高精度硬件定时器,微秒级精度
- 周期定时器模式:以固定间隔触发回调
- 定时器周期:
period_us = 1,000,000 / 采样频率_hz - 定时器回调在定时器上下文中执行(高优先级,类似中断)
-
定时器回调函数
- 在每个定时器滴答时同步执行
- 执行传感器读取操作(非阻塞SPI)
- 立即格式化数据(字符串格式化)
- 发布到输出通道(MQTT、串口、LCD)
- 最小化处理时间,避免错过定时器滴答
-
输出通道
- MQTT:通过
esp_mqtt_client_publish()非阻塞发布(QoS 0) - 串口:阻塞式
printf()并立即fflush() - LCD:同步显示更新(高频率时可能影响时序)
- MQTT:通过
编程工具与API¶
-
ESP-IDF定时器API:
esp_timer_create()、esp_timer_start_periodic() -
ESP-IDF MQTT客户端:
esp_mqtt_client_publish()用于网络传输 -
标准C I/O:
printf()、snprintf()用于数据格式化 -
FreeRTOS:状态管理和线程安全(无需显式任务)
执行流程¶
- 初始化:创建周期定时器,计算周期
- 启动:执行立即首次采样,然后启动周期定时器
- 运行时:定时器回调以固定间隔触发
- 读取传感器(SPI通信)
- 格式化数据(字符串转换)
- 输出到启用的通道(尽可能非阻塞)
- 停止:删除定时器,清理资源
关键设计决策¶
- 立即首次采样:确保数据采集从t=0开始
- 非阻塞MQTT:防止定时器回调在网络操作上阻塞
- 最小回调处理:保持回调执行时间短,以维持时序精度
- 状态标志保护:使用
s_is_running标志防止停止后回调执行
配置¶
默认配置¶
默认值在 tiny_measurement_config.h 中定义:
#define TINY_MEASUREMENT_ONLINE_SENSING_DEFAULT_FREQ_HZ 1.0f
#define TINY_MEASUREMENT_ONLINE_SENSING_DEFAULT_ENABLE_MQTT true
#define TINY_MEASUREMENT_ONLINE_SENSING_DEFAULT_ENABLE_SERIAL true
配置结构¶
typedef struct
{
float sampling_frequency_hz; // 采样频率(Hz)
bool enable_mqtt; // 启用MQTT传输
bool enable_serial; // 启用串口输出
bool enable_lcd; // 启用LCD显示(可选)
const char *mqtt_topic; // MQTT主题(NULL使用默认)
} online_sensing_config_t;
数据格式¶
MQTT格式¶
紧凑格式,6位小数精度,支持完整的20位精度:
示例:
串口格式¶
与MQTT格式相同,带换行符:
LCD格式¶
每行一个轴:
-
第1行:
X:0.012345 -
第2行:
Y:-0.045678 -
第3行:
Z:0.987654 -
第4行:
T:25.50C
使用流程¶
- 初始化传感器:初始化ADXL355传感器
- 设置传感器句柄:调用
online_sensing_set_sensor_handle() - 初始化模块:调用
online_sensing_init()并传入配置(或NULL使用默认值) - 启动传感:调用
online_sensing_start() - 运行时更新:可选地更新频率或启用/禁用通道
- 停止传感:完成后调用
online_sensing_stop() - 反初始化:调用
online_sensing_deinit()清理资源
性能考虑¶
采样频率限制¶
- 最小值:0.1 Hz(10秒周期)
- 最大值:300 Hz(3333微秒周期)- 代码层面的限制
- 实测上限:~200 Hz - 实际硬件测试中的稳定运行上限
- 推荐值:大多数应用使用 1 - 200 Hz
实际限制
虽然代码接受高达300 Hz的频率,但实际硬件测试表明,稳定运行的上限约为200 Hz。此限制主要是由于MQTT传输的约束。 在更高频率下,MQTT发布无法跟上数据生成速率,导致缓冲区溢出、消息队列饱和和潜在的数据丢失。为确保可靠运行,特别是在启用MQTT传输时,请将采样频率保持在200 Hz或以下。
资源使用¶
- CPU:定时器回调以采样频率执行
- 内存:回调中最小栈使用
- 网络:MQTT带宽取决于频率和负载大小。MQTT传输是限制实测最大采样率至~200 Hz的主要瓶颈。 在更高频率下,MQTT发布操作无法足够快地完成,导致消息队列堆积和潜在的数据丢失。
- 串口:高频率可能导致串口缓冲区溢出
提高采样频率
要实现更高的采样频率,建议关闭不必要的输出通道:
- 禁用串口输出:串口打印(
printf())是阻塞式的,会显著减慢定时器回调的执行速度,特别是在高频率(>100 Hz)时 - 禁用LCD显示:LCD更新是同步的且相对较慢,不适合用于10 Hz以上的频率
- 仅保留MQTT:如果需要网络传输,仅保留MQTT启用,禁用串口/LCD输出
通过禁用串口和LCD输出,可以减少定时器回调的执行时间,从而可能实现更高的稳定采样率。
优化建议¶
- 禁用串口输出:对于高频率(>100 Hz),禁用串口输出
- MQTT QoS:对高频数据使用QoS 0(默认)
- LCD更新:LCD更新相对较慢,仅用于低频率(<10 Hz)
- 保持在实测限制内:为确保稳定运行,特别是在启用MQTT时,将采样频率保持在200 Hz或以下。200 Hz的限制主要是由于MQTT传输带宽约束。
- 代码层面限制:代码强制最大300 Hz,但实际测试表明~200 Hz是可靠的上限
错误处理¶
常见错误¶
ESP_ERR_INVALID_ARG:无效频率(超出范围:0.1 - 300 Hz)ESP_ERR_INVALID_STATE:已在运行或未初始化ESP_FAIL:定时器创建或启动失败
错误恢复¶
- 在启动前检查传感器句柄是否已设置
- 在初始化前验证频率范围
- 使用新配置重启前先停止
线程安全¶
- 定时器回调在定时器上下文中执行(高优先级)
- 配置更改需要停止并重新启动
- 状态检查防止并发操作
集成注意事项¶
MQTT集成¶
- 需要MQTT客户端已连接
- 发布前检查
s_is_mqtt_connected - 如果
mqtt_topic为NULL,使用默认主题
传感器集成¶
- 需要ADXL355传感器句柄
- 必须在设置句柄前初始化
- 传感器读取操作是非阻塞的
LCD集成¶
- 仅在定义
TINY_MEASUREMENT_ENABLE_LCD时可用 - 启动时清除LCD屏幕
- 更新是同步的(高频率时可能影响时序)