CANopen for Python(一)+https://developer.aliyun.com/article/1585385
六、同步对象 (SYNC)
同步生产者(Sync-Producer)为同步消费者(Sync-Consumer)提供同步信号。同步消费者收到信号后,就开始执行同步任务。
一般来说,同步 PDO 信息传输时间的固定和同步对象传输的周期性保证了传感器设备可以安排对过程变量进行采样,执行器设备可以以协调的方式执行动作。
同步对象的标识符位于索引 1005h。
6.1 示例
使用 canopen.Network.sync 属性启动和停止 SYNC 消息:
# Transmit every 10 ms network.sync.start(0.01) network.sync.stop()
七、紧急对象 (EMCY)
紧急信息由设备内部发生致命错误时触发,以高优先级从相关应用设备传输到其他设备。因此,它们适用于中断类型的错误警报。每个 "错误事件 "只能发送一次紧急报文,即紧急报文不得重复发送。只要设备没有发生新的错误,就不能再发送紧急报文。通过 CANopen 通信配置文件定义的紧急错误代码、错误寄存器和设备配置文件中指定的设备特定附加信息。
7.1 示例
要列出某个节点当前激活的紧急事件,可以使用 .active 属性,该属性是 canopen.emcy.EmcyError 对象的列表:
active_codes = [emcy.code for emcy in node.emcy.active] all_codes = [emcy.code for emcy in node.emcy.log]
canopen.emcy.EmcyError 对象实际上是异常,因此如果您需要,可以很容易地引发异常:
if node.emcy.active: raise node.emcy.active[-1]
八、时间戳对象(TIME)
通常,时间戳对象表示午夜后以毫秒为单位的绝对时间和自 1984 年 1 月 1 日以来的天数。这是一个长度为 48(6 字节)的位序列。
九、层设置服务 (LSS)
LSS 协议用于更改 CANOpen 目标设备(从站)的节点 ID 和波特率。要更改这些值,主站应首先设置配置状态。然后修改节点 ID 和波特率。从等待状态切换到配置状态有两种选择。一种是一次性切换所有从属设备,另一种是只切换一个从属设备。前者可用于设置所有从属设备的波特率。后者可用于逐个更改节点 ID。
完成设置后,应将数值保存到非易失性存储器中。最后,可以切换到 LSS 等待状态。
注意 某些方法和常量名称有所更改:
send_switch_mode_global() ==> send_switch_state_global() network.lss.CONFIGURATION_MODE ==> network.lss.CONFIGURATION_STATE network.lss.NORMAL_MODE ==> network.lss.WAITING_STATE
您仍可使用旧名称,但请使用新名称。
注意 从 v0.8.0 开始支持 Fastscan。未实施 LSS 识别从属服务。
9.1 示例
将所有从属设备切换到 CONFIGURATION(配置)状态。信息无响应。
network.lss.send_switch_state_global(network.lss.CONFIGURATION_STATE)
如果只想切换一个从属设备,也可以使用 4 个 ID 调用此方法:
vendorId = 0x00000022 productCode = 0x12345678 revisionNumber = 0x0000555 serialNumber = 0x00abcdef ret_bool = network.lss.send_switch_state_selective(vendorId, productCode, revisionNumber, serialNumber)
或者,可以运行 fastscan 程序
ret_bool, lss_id_list = network.lss.fast_scan()
一旦其中一个传感器进入 "配置 "状态,就可以读取 LSS 从站的当前节点 ID:
node_id = network.lss.inquire_node_id()
更改节点 ID 和波特率:
network.lss.configure_node_id(node_id+1) network.lss.configure_bit_timing(2)
这是将比特定时的参数索引转换为波特率的表格。
idx |
Baud rate |
0 |
1 MBit/sec |
1 |
800 kBit/sec |
2 |
500 kBit/sec |
3 |
250 kBit/sec |
4 |
125 kBit/sec |
5 |
100 kBit/sec |
6 |
50 kBit/sec |
7 |
20 kBit/sec |
8 |
10 kBit/sec |
保存配置:
network.lss.store_configuration()
最后,可以将从属设备的状态从 "配置 "状态切换到 "等待 "状态:
network.lss.send_switch_state_global(network.lss.WAITING_STATE)
十、与现有代码集成
有时,您需要将该库与某些现有代码库结合使用,或者您有 Python-can 不支持的 CAN 驱动程序。本章将介绍一些使用案例。
10.1 重新使用总线
如果您需要与本库之外的 CAN 总线进行交互,并希望使用相同的 python-can 总线实例,您需要告诉网络使用哪条总线,并将 canopen.network.MessageListener 添加到现有的 can.Notifier 中。
下面是一个简短的示例:
import canopen import can # A Bus instance created outside bus = can.interface.Bus() network = canopen.Network() # Associate the bus with the network network.bus = bus # Add your list of can.Listener with the network's listeners = [can.Printer()] + network.listeners # Start the notifier notifier = can.Notifier(bus, listeners, 0.5)
10.2 使用自定义后端
如果 python-can 软件包不支持您的 CAN 接口,您就需要创建 canopen.Network 的子类,并提供自己的消息发送方式。您还需要在后台线程中向 canopen.Network.notify() 发送接收到的消息。
下面是一个示例:
import canopen class CustomNetwork(canopen.Network): def connect(self, *args, **kwargs): # Optionally use this to start communication with CAN pass def disconnect(self): # Optionally use this to stop communincation pass def send_message(self, can_id, data, remote=False): # Send the message with the 11-bit can_id and data which might be # a bytearray or list of integers. # if remote is True then it should be sent as an RTR. pass network = CustomNetwork() # Should be done in a thread but here we notify the network for # demonstration purposes only network.notify(0x701, bytearray([0x05]), time.time())
十一、设备配置文件
在包括 DS301 应用层在内的标准 CANopen 功能基础上,还可以为某些应用提供专门的附加配置文件。
11.1 用于运动控制器和驱动器的 CiA 402 CANopen 设备配置文件
该设备配置文件具有用于控制驱动器行为的控制状态机。因此,需要使用 BaseNode402 类实例化一个节点
使用 BaseNode402 创建一个节点:
import canopen from canopen.profiles.p402 import BaseNode402 some_node = BaseNode402(3, 'someprofile.eds') network = canopen.Network() network.add_node(some_node)
11.2 电源状态机
PowerStateMachine 类提供了控制该状态机状态的方法。静态方法 on_PDO1_callback() 被添加到 TPDO1 回调中。
通过向寄存器 0x6040 写入特定值(称为 "控制字"),可以控制状态变化。当前状态可通过读取寄存器 0x6041(称为 "Statusword")来读取。只有在 NmtMaster 的 "运行 "状态下才能更改状态。
需要正确设置映射了控制字和状态字的 PDO,这是大多数 DS402 兼容驱动器的默认配置。要使状态机实现可以访问它们,请运行 BaseNode402.setup_402_state_machine() 方法。请注意,该设置例程默认会读取当前的 PDO 配置,从而导致一些 SDO 流量。这仅在 NmtMaster 的 "OPERATIONAL(运行)"或 "PRE-OPERATIONAL(预运行)"状态下有效:
# run the setup routine for TPDO1 and it's callback some_node.setup_402_state_machine()
写入 Controlword 并读取 Statusword:
# command to go to 'READY TO SWITCH ON' from 'NOT READY TO SWITCH ON' or 'SWITCHED ON' some_node.sdo[0x6040].raw = 0x06 # Read the state of the Statusword some_node.sdo[0x6041].raw
在运行过程中,状态可能会变为控制字无法命令的状态,例如 "故障 "状态。因此,BaseNode402 类(与 NmtMaster 类似)会自动监控由 TPDO 发送的状态字的状态变化。然后,TPDO 上的可用回调将提取信息并在 BaseNode402.state 属性中反映状态变化。
与 NmtMaster 类类似,BaseNode402 类状态属性的状态可以通过字符串读取和设置(命令):
# command a state (an SDO message will be called) some_node.state = 'SWITCHED ON' # read the current state some_node.state
可用状态:
- 未准备好开启
- 已禁用
- 准备开启
- 已开启
- 已启用操作
- 故障
- 故障反应激活
- 快速停止激活
可用命令
- 禁用开关
- 禁用电压
- 准备开启
- 已开启
- 启用操作
- 快速停止激活