跳到主要内容

12. SDO 查询与 PDO 传输

学习形式概念课
硬件要求不需要
配套 Demo
本课动作不写电机对象

上一课中,ESP32 已经能够通过 SDO 读取电机参数。SDO 请求中写有 Index 和 Sub-index,电机会用这个对象地址找到参数并返回它的值;这个过程也叫“访问电机的对象字典”。

例如,读取当前位置参数 0x6064:00 时,总线上实际出现过下面两帧报文:

方向CAN-IDDATA
ESP32 → 电机0x60140 64 60 00 00 00 00 00
电机 → ESP320x58143 64 60 00 AA 16 00 00

第一帧是请求,第二帧是响应。程序把响应中的四个数据字节 AA 16 00 00 按小端序组合,得到位置值 5802

注意:接收 0x701 Heartbeat 不属于读取对象字典。Heartbeat 是电机按周期主动发送的在线状态报文,ESP32 没有在报文中指定 Index 和 Sub-index,也没有向电机发起 SDO 请求。

这种方式很适合“现在查一次位置”。接下来先考虑一个实际需求:如果程序运行时每秒要知道 10 次当前位置,还继续使用同样的方法,会发生什么?

再看一次已经读懂的 SDO

请求中的前四个字节告诉电机“读取对象 0x6064:00”:

请求中的字节含义
40发起一次 SDO 读取
64 60Index,按小端序表示 0x6064
00Sub-index 0x00

响应中再次带回相同地址:

响应中的字节含义
43读取成功,返回 4 字节数据
64 60Index 0x6064
00Sub-index 0x00
AA 16 00 00电机返回的位置值

这样做的好处是,请求和响应都明确写着正在访问哪个对象。程序可以先读 0x1000:00,下一次再读 0x6064:00,电机也能区分它们。

但这也意味着,每读取一次位置,都必须完成三个步骤:

  1. ESP32 发送请求:说明要读取 0x6064:00
  2. 电机查找数据:在自己的对象字典中找到当前位置。
  3. 电机返回响应:把对象地址和当前位置一起发回 ESP32。

一次读取至少产生一帧请求和一帧响应。

连续查询时,总线上会重复什么

假设程序每秒读取 10 次 0x6064:00

查询频率请求帧响应帧每秒合计
读取 1 次1 帧1 帧2 帧
每秒读取 10 次10 帧10 帧20 帧

这 20 帧中,下面这些内容会不断重复:

每次查询都会重复的内容数值
请求 CAN-ID0x601
响应 CAN-ID0x581
对象 Index0x6064
对象 Sub-index0x00
请求命令字0x40
响应命令字0x43

真正不断变化、程序最关心的,通常只有响应中的位置值。

这里不是说 20 帧一定会让 500 kbit/s 的总线立即拥堵。重点是通信方式:控制器每想知道一次数据,都要先提问,然后等待回答。读取对象越多、读取频率越高,重复的请求和地址字段就越多。

SDO 的优点没有因此消失。读取设备类型、序列号、配置参数,或者修改一个对象时,一问一答仍然很合适,因为程序需要知道这次访问成功了还是返回了 Abort。

运行数据需要另一种传输方式

电机运行时,控制器经常反复读取当前位置、当前速度和状态字,也可能周期发送目标位置或控制字。

如果发送方和接收方事先知道一帧 DATA 中放哪些值,就不必每次都把对象地址装进报文。

CANopen 把这种报文称为 Process Data Object,缩写为 PDO,中文常称“过程数据对象”。

先看图中两条通信过程。SDO 在下方,需要请求和响应;PDO 在上方,由发送节点直接发出一帧已经约定好内容的报文:

SDO 与 PDO 的传输过程对比

两种方式可以先这样区分:

通信方式对象地址放在哪里报文过程
SDO写在每次请求中ESP32 请求,电机响应
PDO预先保存在 PDO 配置中发送节点直接发送数据

“已经配置好”具体是什么意思

假设某台电机的一条 PDO 使用 CAN-ID 0x181,并采用下面的 DATA 排列:

DATA 范围保存的值长度
DATA[0..1]Statusword2 字节
DATA[2..5]Position Actual Value4 字节

接收程序看到 0x181 后,就会按照这张表读取前 2 字节和后 4 字节。

这一帧 DATA 中不会再出现 0x60410x6064。对象地址保存在设备的 PDO 配置中,不需要每一帧重复发送。

上面的排列只是解释通信方式的示例,不是本电机的实际配置。本教程不会根据常见用法猜测 IG35EC020 的 PDO 内容。第 14 课会用只读 SDO 从电机中读取真实配置。

SDO 和 PDO 分别适合做什么

要完成的事通常使用原因
读取设备类型SDO请求中可以指定 0x1000:00
修改一个配置参数SDO能收到成功响应或 Abort
周期获得当前位置PDO配置确定后,一帧直接携带数据
周期发送控制量PDO不必每次重复对象地址

PDO 不是更高级的 SDO,也不会取代 SDO。调试和配置阶段通常使用 SDO 访问对象字典;正常运行阶段再使用 PDO 传输频繁变化的数据。

用真实报文做一次检查

回到开头的响应:

43 64 60 00 AA 16 00 00

请先自己指出:

  1. 哪一个字节是响应命令字;
  2. 哪两个字节组成 Index;
  3. 哪一个字节是 Sub-index;
  4. 哪四个字节才是位置值。

答案是:

字节解释
43响应命令字
64 60Index 0x6064,小端序
00Sub-index 0x00
AA 16 00 00位置值,小端序

现在把前四个字节想象成不再随每次报文重复出现,只保留最后四个位置数据,就能看到 PDO 想解决的问题。

本课使用的原始电机通信记录保存在:

docs/images/sources/ig35ec020_sdo_read_2026-08-05.txt

这一课学会了什么

这一课只需要得到一个结论:

SDO 通过请求和响应访问指定对象,适合查询和配置。
PDO 按预先确定的排列直接传输数据,适合反复交换运行数据。

现在还没有解释谁发送 PDO、谁接收 PDO,也没有假定电机已经启用 PDO。下一课先把发送方向和 CAN-ID 讲清楚,再去读取配置。

资料链接