柔性振动工程的面包板联调曾遇到一个反直觉现象:旧版可以采样,新加的保护反复触发。ESP32-C3 能与 MPU6050 通信,但诊断读到 FIFO 计数为 14、41、62、74 字节。每个三轴样本是 6 字节,这些数都不能整除,程序于是认定数据已经异常。
当时观察到 FIFO 字节数并非完整样本长度的整数倍。不能仅凭这一计数判定前面的完整样本损坏;非整帧计数的具体形成原因仍需结合器件资料和进一步测量确认。
消费者按完整样本工作。
修正把可读长度向下取整到 6 的倍数,只读取这部分数据,尾部留在 FIFO 等下一轮。14 字节可以先取走两个样本、留下 2 字节;41 字节取走六个样本、留下 5 字节。消费边界明确后,写入方和读取方不必在同一个瞬间完成。
下面是长度计算的整理示意,不是原样 ESP-IDF 驱动,不能直接烧录。它没有实现总线事务、FIFO 容量检查和故障恢复,只把“可处理部分”和“尚未完整部分”分开。真实工程仍需要核对设备配置与帧格式。
// 整理示意:当前采集格式为每样本 6 字节。
function readableBytes(count) {
if (!Number.isInteger(count) || count < 0) {
throw new RangeError('FIFO count must be a non-negative integer');
}
return Math.floor(count / 6) * 6;
}
readableBytes(14); // 12,末尾 2 字节留到下一轮
readableBytes(41); // 36,末尾 5 字节留到下一轮放过尾部,不是撤掉保护。
接近满容量、I²C 失败和长时间没有样本,仍然需要独立处理。当前实现保留这些检查,采集失效时清除滤波与检测历史,恢复后重新测率。否则断点两侧的数据会被拼进同一个窗口,旧结果还可能看起来像最新测量。
保护条件应该拒绝真正的异常,也应该容得下正常的中间状态。
写给实践时的自己
批量读取还有时间轴问题。一批样本被 CPU 很快处理完,不代表它们在这段处理时间里同时产生。工程用实测采样率与连续序号组织样本时间,保留小数周期累积,让算法看到的是传感器节奏,而不是任务循环的忙闲。
把成功和异常,写在同一份记录里。
2026-10-13 的记录中,两个新增回归用例先在旧实现上失败,修正后共 28 项主机检查通过,C3 构建与烧录校验也通过。初始化成功后的启动测率为 997.8 Hz,475 行非零三轴数据跨越 41.110 秒。这些是一次具体联调的历史结果。
随后几分钟统计仍出现 2 次 FIFO 接近满容量并自动恢复,启动也有一次瞬时复位写失败。关闭详细打印的短时比较没有新增异常,却不足以确认打印是唯一原因。面包板使用另一颗 C3,也不能用它证明此前柔性 PCB 已经修好。
- 已经记录:完整帧修正、主机回归与短时实物采样。
- 继续定位:启动瞬时失败与长期 FIFO 异常。
- 仍待验收:真实振动源的频率精度和长期稳定性。
下一轮,先选对要观察的数据。
现有 20 Hz 串口输出是检测统计,不能用来重建 80–180 Hz 原始振动。接下来需要原始 XYZ 数据与明确输入条件,才能分别检查采集连续性和算法判断。本文只核对源码与历史记录,没有重新采样;一次成功留下起点,尚未解释的异常则指出下一步。
写下来,是为了下一次更快找到线索。
返回文章列表