跳转至

传感器驱动与数据质量

传感器驱动的职责不只是“读出几个寄存器”。它必须把硬件产生的字节转换成带有正确单位、方向、时间和健康状态的数据,并在总线或器件异常时给上层明确结果。

传感器驱动数据管线

驱动的数据管线

典型过程包括:

  1. 识别总线和器件实例;
  2. 读取身份寄存器;
  3. 复位器件并等待规定时间;
  4. 写入量程、滤波、输出速率和中断配置;
  5. 验证关键寄存器是否生效;
  6. 在数据就绪事件或计划周期读取样本;
  7. 检查传输状态和样本完整性;
  8. 解析字节序和有符号数;
  9. 换算为统一物理单位;
  10. 应用传感器方向与校准;
  11. 记录采样时间、实例和错误状态;
  12. 发布给状态估计或其他消费者。

任何一步失败都不能静默地把零值或旧值伪装成新样本。

总线操作需要事务边界

SPI设备

串行外设接口(SPI,Serial Peripheral Interface)设备通常共享时钟和数据线,通过独立片选区分。

核对:

  • SPI模式;
  • 最大时钟;
  • 读写位定义;
  • 寄存器地址宽度;
  • 片选建立和保持时间;
  • 连续读取规则;
  • 多字节顺序;
  • 总线锁和DMA缓冲区。

错误片选可能让两个设备同时驱动总线。提高总线频率也可能只在短线或特定温度下工作。

I²C设备

内部集成电路总线(I²C,Inter-Integrated Circuit)通过地址区分设备。

核对:

  • 7位或其他地址形式;
  • 上拉电阻与总线电压;
  • 时钟速率;
  • 时钟延展;
  • 重复起始;
  • 超时;
  • 总线被设备拉低后的恢复。

扫描到地址只证明某个设备响应,不能证明型号、配置和数据正确。

从原始码到物理量

以三轴角速度为例:

物理角速度 =
原始有符号计数 × 量程比例
→ 传感器坐标系
→ 板级方向变换
→ 机体坐标系
→ 偏置和温度补偿

必须明确:

  • 原始位宽和符号;
  • 每位对应的量值;
  • 度每秒还是弧度每秒;
  • 右手系还是其他约定;
  • 轴交换和正负号;
  • 饱和值;
  • 无效值。

单位错误可能让数值看起来“在变化”,却完全无法进入正确控制计算。

时间戳放在哪里

常见时间点包括:

  • 物理采样时刻;
  • 数据就绪中断时刻;
  • 总线读取开始或结束时刻;
  • 驱动发布时刻;
  • 上层消费时刻。

状态估计更关心测量实际对应的物理时刻,而不是消息最终发布的时刻。若器件内部存在先入先出缓冲区(FIFO,First In First Out),还要根据样本顺序、输出速率和读取延迟重建每个样本的时间。

数据就绪与轮询

数据就绪中断可以减少无效轮询并提供更稳定的采样时刻,但需要验证:

  • 引脚和边沿配置;
  • 中断是否丢失或重复;
  • 中断频率;
  • 读取能否在下一批数据到达前完成;
  • FIFO溢出行为;
  • 中断故障后的降级策略。

没有数据就绪信号时可以轮询,但必须检测重复样本和样本年龄。

校准不是驱动常数

应区分:

  • 器件固定比例和寄存器定义;
  • 板级方向;
  • 单台设备的偏置和比例校准;
  • 温度补偿;
  • 运行时估计的偏差。

把单台设备的校准值写死在通用驱动里,会让同型号其他设备继承错误参数。校准数据应绑定设备实例、硬件版本和有效条件。

滤波边界

传感器内部、驱动、状态估计器和控制器都可能有滤波。每级都要记录:

  • 类型;
  • 截止频率;
  • 采样率;
  • 相位或群延迟;
  • 初始化状态;
  • 参数变化时的状态处理;
  • 是否影响故障检测。

重复滤波可能显著增加延迟。不能只根据曲线更平滑判断滤波更好。

健康状态不能只有“在线”

建议至少统计:

指标 用途
通信错误数 识别总线或连接问题
连续失败数 触发超时或重启
样本年龄 识别旧数据
更新率 识别降频和丢样
FIFO溢出 识别处理不及时
饱和次数 识别量程不足
温度范围 识别超出补偿边界
一致性检查 比较冗余传感器或物理约束
重置次数 识别器件反复失效

“设备能返回身份值”只表示通信的第一步成功。

冗余传感器

多传感器系统还需要明确:

  • 实例编号是否稳定;
  • 谁是主传感器;
  • 切换条件;
  • 切换时坐标和校准是否一致;
  • 故障隔离是否会来回抖动;
  • 日志能否看出当前数据来源;
  • 一个总线故障是否会同时影响多个实例。

两颗传感器共用同一供电或总线,并不构成完整独立冗余。

驱动验证顺序

  1. 主机端测试解析、缩放和边界;
  2. 用记录数据或虚拟总线重放;
  3. 在开发板上读取身份和配置寄存器;
  4. 验证静止偏置、六面方向和时间戳;
  5. 制造断线、超时、错误身份和饱和;
  6. 测量更新率、抖动和CPU占用;
  7. 验证重启、重新探测和故障上报;
  8. 与参考仪器或已知输入比较;
  9. 再接入状态估计器;
  10. 最后进入拆桨整机测试。

PX4 v1.17.0的驱动追踪示例

以FMUv5板级目标中的一个惯性传感器分支为例:

  1. 打开boards/px4/fmu-v5/init/rc.board_sensors
  2. 找到ver hwtypecmp对硬件版本的判断;
  3. 其中一个分支启动icm42688p -s -R 2 -q start,另一个分支启动icm20602
  4. -s-R 2-q的具体含义必须回到该版本驱动的命令帮助与源码确认;
  5. 进入src/drivers/imu/invensense/icm42688p/
  6. 从模块入口找到总线对象、设备标识检查、寄存器配置、FIFO读取和发布对象;
  7. src/drivers/imu/invensense/icm42688p/CMakeLists.txt和相关Kconfig中确认驱动进入构建;
  8. 再从发布的sensor_accelsensor_gyro或FIFO主题追踪到sensors模块与估计器。

可使用:

rg "icm42688p" boards/px4/fmu-v5 src/drivers/imu
rg "sensor_accel|sensor_gyro" src/drivers/imu/invensense/icm42688p

在真实FMUv5兼容硬件上验证时必须拆除螺旋桨,并先确认该硬件版本确实使用对应器件。控制台中的典型只读检查为:

icm42688p status
listener sensor_accel 5
listener sensor_gyro 5

通过标准不是“命令有输出”,而是设备实例、更新率、错误计数、温度、轴方向和静止量级符合该板卡与安装条件。若目标硬件走icm20602分支,则不能强行启动icm42688p完成示例。

检查理解

  1. 为什么读取到寄存器值不等于驱动完成?
  2. 传感器时间戳为什么不能简单使用消息发布时间?
  3. 为什么单台设备校准值不应写进通用驱动?
  4. 两颗同总线传感器为什么不构成完整独立冗余?
  5. “在线”状态为什么不足以描述传感器健康?

主要参考