跳到主要内容

排错专题:怎样整理抓包与串口日志

CANopen 报文多起来后,最容易出现的问题不是没有日志,而是日志太多,关键请求和响应被淹没。排错时需要把一次操作整理成可以复查的时间线。

先写清实验条件

每份记录开头至少包含:

项目示例
日期和时间2026-08-11 14:30 CST
工程examples/lab_19_canopennode_sdo_client
ESP-IDFv5.5.4
CANopenNode0.1.0
本地节点ESP32 0x20
远程节点IG35EC020 0x01
位速率500 kbit/s
引脚TX GPIO19,RX GPIO18
本次动作只读 0x6064:00

没有这些条件,同一段 0x581 数据很难在几周后复现。

原始帧统一格式

建议每帧至少保存:

[时间戳] RX/TX CAN-ID DLC DATA

例如:

[12.345678] TX 0x601 8 40 64 60 00 00 00 00 00
[12.347201] RX 0x581 8 43 64 60 00 AB 16 01 00

格式规则:

  • 标准 CAN-ID 使用三位十六进制;
  • DATA 每字节两位十六进制;
  • 十进制解释放在另一列或下一行;
  • TX/RX 以本地 ESP32 视角标注;
  • 时间戳单位在文件开头说明。

从大量报文中找一次 SDO

一次 SDO 读取可以按以下条件筛选:

  1. 找请求 CAN-ID 0x601
  2. 在其后寻找响应 CAN-ID 0x581
  3. 核对两帧中的 Index 和 Sub-index 相同;
  4. 查看响应命令字是成功还是 0x80
  5. 计算请求到响应的时间;
  6. 成功时按数据类型解释,失败时按小端序组合 Abort Code。

示例请求:

40 64 60 00 00 00 00 00

示例响应:

43 64 60 00 AB 16 01 00

共同的 64 60 00 说明它们都指向 0x6064:00。最后四字节:

AB 16 01 00 -> 0x000116AB -> 71339

Heartbeat 不要和 SDO 混在一起解释

0x701 [1] 05

这是电机主动发送的 Heartbeat,没有与它配对的 0x601 请求。看到它只能说明节点在发送 NMT 状态,不能说“读取对象字典成功”。

常见 CAN-ID 可以先按用途分组:

范围/示例当前用途
0x000NMT 命令
0x181 / 0x1A0Node 1 / Node 0x20 的 TPDO1
0x201 / 0x220Node 1 / Node 0x20 的 RPDO1
0x581电机 SDO 响应
0x601发给电机的 SDO 请求
0x701电机 Boot-up/Heartbeat
0x720ESP32 Boot-up/Heartbeat

串口输入被周期日志打断怎么办

终端显示上,日志可能出现在正在输入的命令中间,但不应让每个字符自动变成一条命令。为了便于操作:

  • 先执行 diag off 关闭应用的周期 SDO 日志;
  • 一次粘贴完整命令,再按回车;
  • 使用 status 主动获取一组状态;
  • 抓包工具和交互串口分开显示时更容易观察;
  • 若一个字符就触发命令,检查行结束配置和逐字符解析代码。

最终 Demo 的命令模块只在收到回车或换行后提交缓冲区中的完整一行。

保存原始记录,不只保存结论

课程硬件验证记录存放在 docs/images/sources/。例如第 11 课的记录:

第 11 课只读 SDO 上板记录

从课程仓库根目录打开的相对路径是:

docs/images/sources/lab_11_sdo_read_hardware_validation_2026-08-11.txt

记录文件应同时保留:

  • 实际执行命令;
  • 构建和烧录结果;
  • 关键原始 CAN 帧;
  • 串口解释日志;
  • 观察到的硬件行为;
  • 最终结论和仍未验证的内容。

一次运动怎样形成完整证据

位置运动至少串起下面的时间线:

  1. 运动前读取 0x60410x60610x6064
  2. 写入 0x607A,保存目标十进制和原始字节;
  3. 改变 0x6040 set-point,保存成功响应;
  4. 周期读取状态和实际位置;
  5. 记录 target reached 的时刻;
  6. 比较最终 0x6064 与目标;
  7. 写下实物方向、角度和 LED 现象。

“电机动了”只能证明发生了动作;把这些信息连起来,才能判断动作由哪次命令触发、单位是否正确、反馈是否达到目标。