排错专题:怎样整理抓包与串口日志
CANopen 报文多起来后,最容易出现的问题不是没有日志,而是日志太多,关键请求和响应被淹没。排错时需要把一次操作整理成可以复查的时间线。
先写清实验条件
每份记录开头至少包含:
| 项目 | 示例 |
|---|---|
| 日期和时间 | 2026-08-11 14:30 CST |
| 工程 | examples/lab_19_canopennode_sdo_client |
| ESP-IDF | v5.5.4 |
| CANopenNode | 0.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 读取可以按以下条件筛选:
- 找请求 CAN-ID
0x601; - 在其后寻找响应 CAN-ID
0x581; - 核对两帧中的 Index 和 Sub-index 相同;
- 查看响应命令字是成功还是
0x80; - 计算请求到响应的时间;
- 成功时按数据类型解释,失败时按小端序组合 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 可以先按用途分组:
| 范围/示例 | 当前用途 |
|---|---|
0x000 | NMT 命令 |
0x181 / 0x1A0 | Node 1 / Node 0x20 的 TPDO1 |
0x201 / 0x220 | Node 1 / Node 0x20 的 RPDO1 |
0x581 | 电机 SDO 响应 |
0x601 | 发给电机的 SDO 请求 |
0x701 | 电机 Boot-up/Heartbeat |
0x720 | ESP32 Boot-up/Heartbeat |
串口输入被周期日志打断怎么办
终端显示上,日志可能出现在正在输入的命令中间,但不应让每个字符自动变成一条命令。为了便于操作:
- 先执行
diag off关闭应用的周期 SDO 日志; - 一次粘贴完整命令,再按回车;
- 使用
status主动获取一组状态; - 抓包工具和交互串口分开显示时更容易观察;
- 若一个字符就触发命令,检查行结束配置和逐字符解析代码。
最终 Demo 的命令模块只在收到回车或换行后提交缓冲区中的完整一行。
保存原始记录,不只保存结论
课程硬件验证记录存放在 docs/images/sources/。例如第 11 课的记录:
从课程仓库根目录打开的相对路径是:
docs/images/sources/lab_11_sdo_read_hardware_validation_2026-08-11.txt
记录文件应同时保留:
- 实际执行命令;
- 构建和烧录结果;
- 关键原始 CAN 帧;
- 串口解释日志;
- 观察到的硬件行为;
- 最终结论和仍未验证的内容。
一次运动怎样形成完整证据
位置运动至少串起下面的时间线:
- 运动前读取
0x6041、0x6061、0x6064; - 写入
0x607A,保存目标十进制和原始字节; - 改变
0x6040set-point,保存成功响应; - 周期读取状态和实际位置;
- 记录 target reached 的时刻;
- 比较最终
0x6064与目标; - 写下实物方向、角度和 LED 现象。
“电机动了”只能证明发生了动作;把这些信息连起来,才能判断动作由哪次命令触发、单位是否正确、反馈是否达到目标。