The English object dictionary is called Object Dictionary, or OD for short, which is the core concept in CANopen. Every CANopen device will have an OD.
OD is mainly used for device configuration and communication. Different devices have different ODs. By reading their ODs, users can know the information of these devices, how to communicate with the devices, and configure the devices.
This is similar to going to a restaurant to eat. The restaurant’s menu is OD. When the customer reads the menu, he knows what dishes the restaurant can do, and then he can make the correct ordering operation.
A conceptual understanding
The structure of the object dictionary is similar to the dict in python. The following is a partial display of the OD content of the device.
At first glance, it is a bit embarrassing. Here, the dictionary in python is used to describe the above picture, which is easier to understand.
myOD = {
}
myOD[0x1000] = {
0x00:0x12345678} # Device Type, UNSIGNED32
myOD[0x1001] = {
0x00: 0x12} # Error Register, UNSIGNED8
myOD[0x1008] = {
0x00: "hello"} # Device Name, VIS_STRING
myOD[0x1017] = {
0x00: 0x1234} # Heartbeat Prod. Time, UNSIGNED16
myOD[0x1018] = {
0x00: 0x04, # number of subindexes, UNSIGNED8
0x01: 0x12345678, # Vendor ID, UNSIGNED32
0x02: 0x12345678, # Product Code, UNSIGNED32
0x03: 0x12345678, # Revision Number, UNSIGNED32
0x04: 0x12345678 # Serial Number, UNSIGNED32
}
Many objects are stored in the OD, and each object has a unique Index corresponding to it, which occupies 2 bytes. If you want to address the internal elements of the object, you need to use SubIndex, which occupies 1 byte, so the combination of Index and SubIndex totals Occupies 3 bytes.
For example, the object corresponding to 0x1018 contains 4 elements, namely Vendor ID, Product Code, Revision Number and Serial Number, and SubIndex is 1, 2, 3, and 4 respectively. The value stored in SubIndex 0 represents the number of elements contained in the object. If there is only one element in the object, then the element value will be directly stored on the element corresponding to SubIndex 0.
The OD structure specified by CANopen is as shown in the figure below, and
here is a bit simplified, as shown in the following table,
Index | Object |
---|---|
0x0000 | Unused |
0x0001 ~ 0x009F | Data type area, storing conventional data types and user-defined data types |
0x00A0 ~ 0x0FFF | Keep |
0x1000 ~ 0x0FFF | Communication profile area, including device type, error register and communication related objects |
0x2000 ~ 0x5FFF | User-defined area to store user-defined objects |
0x6000 ~ 0x9FFF | Standard equipment profile area, storing objects defined in standard profiles |
0xA000 ~ 0xFFFF | Keep |
In actual use, not all indexes are used up, and some indexes are selected to use according to needs. For example, in the standard equipment profile area, the user-developed product may be used in a certain industry, then only the objects defined by the industry’s standard profile are needed, such as DS-402 corresponding to motion control.
Two OD file format
OD is generally saved as EDS file or DCF file. In the previous article, we have used an EDS file, namely CANopenSocket.eds
The DCF file format is basically the same as EDS, except that DCF can save the ID information of the device, and only part of the OD can be saved. What is the significance? Sometimes we want to update the OD in the device, but only part of it, so that DCF can be used.
For the specific format of EDS and DCF files, please refer to the official document of CANopen, namely DS-306
Three-code combat
Let’s experience the OD through pythonCANopen. Let’s take a look at the content of the OD from the perspective of the Client (that is, guests who go to a restaurant for dinner).
First, create a virtual CAN device vcan0.
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
Then execute the following python code,
import time
import canopen
# 创建一个网络用来表示CAN总线
network = canopen.Network()
# 添加slave节点,其id是6,对象字典为CANopenSocket.eds
node = canopen.RemoteNode(6, 'CANopenSocket.eds')
network.add_node(node)
# 连接到CAN总线
network.connect(bustype='socketcan', channel='vcan0')
for obj in node.object_dictionary.values():
# 打印对象的Index和名称
print('0x{:X}: {}'.format(obj.index, obj.name))
'''
如果对象类型是Record,即内部包含多个元素的对象,
就把其内部元素的SubIndex和名称打印出来
'''
if isinstance(obj, canopen.objectdictionary.Record):
for subobj in obj.values():
print(' {}: {}'.format(subobj.subindex, subobj.name))
In this way, you can see the object information in the OD.
If you want to access a single OD object, you can use ParameterName or Index/SubIndex combination. For example, if you want to access the value corresponding to Index of 0x2301 and SubIndex of 01 in CANopenSocket.eds, the
code is as follows,
obj_element = node.object_dictionary[0x2301][1]
print(obj_element.default)
obj_element = node.object_dictionary['Trace config']['Size']
print(obj_element.default)
Can print its default value
Four summary
This article briefly describes the object dictionary in CANopen, which is a very important concept in CANopen, and its meaning can be well understood through python code.
If there is something wrong with the writing, I hope to leave a message to correct it, thank you for reading.