By: Catherine H., SW Developer at GradientOne
In the last post, we covered how to use the GradientOne CAN bus editor and the settings to acquire data by polling, as well as a brief introduction to PDO's and SDO's. In this post, we'll cover running the same test with the Copley controller's trace tool, which involves reading a multi-packet SDO. The Trace Tool The trace tool allows data to be captured at a regular interval and buffered within the Copley motor controller, then downloaded as a large SDO. The trace is set up by setting writing several SDO's. Like as before, we're going to collect the position and velocity: # set all channels to empty WRITE 0x0000 to trace_channel_1 on node 1 WRITE 0x0000 to trace_channel_2 on node 1 WRITE 0x0000 to trace_channel_3 on node 1 WRITE 0x0000 to trace_channel_4 on node 1 WRITE 0x0000 to trace_channel_5 on node 1 WRITE 0x0000 to trace_channel_5 on node 1 # set trace channel 1 to actual load position (0x001c) WRITE 0x1c00 to trace_channel_1 on node 1 # set trace channel 2 to actual motor velocity (0x0017) WRITE 0x1700 to trace_channel_2 on node 1
Next, configure the trace period and trigger. This trace period is defined in terms of reference periods, which is a factor of the smallest time interval and the total number of samples in the trace. The trace can be triggered off of several inputs, but in this example we will trigger off of a CAN packet:
# set the trace period to the 1.0 (1.0/6.7e-6 trace period *512 max samples*5) WRITE 0x1d00 to trace_period on node 1 # set the trace trigger configuration to a CAN packet trigger (0x000000000000) WRITE 0x000000000000 to trace_trigger_configuration on node 1
Like in the previous example, we'll tell the motor to move to 60,000 steps:
# Set position mode to target position (0x01) WRITE 0x01 to mode_of_operation on node 1 # Set target position to 60,000 (0xc0270900) WRITE 0xc0270900 to trajectory_generator_position_command on node 1 # Set control word bit 4 (address 0x6040) to move (0x3f00) WRITE 0x3f00 to control_word on node 1 # Set control word bit 4 to done (0x2f00) WRITE 0x2f00 to control_word on node 1
We next trigger the trace data collection:
# send the trace trigger packet to 0x0001 WRITE 0x0001 to trace_trigger on node 1
Now, we want to keep asking the controller for the number of samples created until we get the number of values required. We can accomplish this by the use of the GradientOne while shorthand:
# request the trace sample count QUERY trace_sample_count on node 1 # repeat this request while the trace sample count is less than 512 while frames[-1].frame_data < [0x03,0x25,0x00,0x00,0x02,0x00,0x00]: QUERY trace_sample_count on node 1
GradientOne provides an alternate shorthand for these command, as remembering it can be cumbersome. Instead of the five lines above, you simply put:
WAIT FOR TRACE
To aid in the data reconstruction, it is helpful to query the trace reference period. If the trace reference period is not in the CAN frames for this test run, GradientOne will assume that it is one, leading to an inaccurate time scale:
# read in the trace_reference_period QUERY trace_reference_period on node 1
Finally, stop the trace so that the data can be downloaded:
# send the trace trigger packet to off (0x0000) WRITE 0x0000 to trace_trigger on node 1
Downloading Large Data from an SDO
The total size of the trace data is be 2 properties * 4 bytes per property * 512 samples = 4096 bytes. Since the a single CAN packet can transmit up to 8 bytes, multiple bytes must be exchanged in order to recreate all of the data. CANopen handles the acknowledgement by sending packets with alternating the first byte between 0x70 or 0x60: # request the trace data (0x2509) WRITE to trace_data on node 1 while frames[-1].data[0] == 0x10 or frames[-1].data[0] == 0x00: 0x601,0x60 if frames[-1].data[0] == 0x10 0x601,0x70
GradientOne also provides a shorthand for downloading trace data. Instead of the four lines above, you can use:
DOWNLOAD
The advantage of using this DOWNLOAD command is that it is done at the client, thus the resulting frames are buffered and the download process is significantly faster than writing out a while loop.
GradientOne can stitch the downloaded byte into arrays of values and plot them. If we enter the full program into the editor like we did in part 1, GradientOne will automatically pick out the data:
Trace through the GradientOne Trace Tool
As like the poll in part 1, GradientOne also has simplified acquiring a trace of data from the EDS file. Like in part 1, fill out the config file, but this time select "trace" as the DAq method, and select "actual_load_position" and "actual_motor_velocity" as the parameters.
0 Comments
By: Catherine H., SW Developer at GradientOne
GradientOne supports cloud based data acquisition and visualization from devices using the CANopen protocol. CANopen is frequently used for embedded systems in automation. It is used in a wide range of industries including medical devices, automotive, heavy machinery, aerospace, and more. In this first of two blog posts, we'll cover how to acquire plotting data by repeatedly sending a polling message and storing the results. In the next post, we'll cover downloading plotting data from the trace tool. For access to our CANopen demo website, please fill out this form. A Brief introduction to CANopen CANopen is a OSI-Model compliant communication protocol at the network layer. Like with other packets at the network layer, such as IP packets, CANopen packets have an ID (11 bits long) and data (0-8 bytes). In linux, CAN devices will show up in ip and packets can be written and read to them using the socketcan kernel module. The python library python-can has a simple binding for sending and receiving can packets. Link with IP packets, the ID simply directs the packets to appropriate node in the network, as well as indicates the type of the message. The actual instructions are contained in the data, like TCP packets within IP packets. The motor controller's object dictionary, that is, the correspondence between a human-readable property, such as target position, and two hexadecimal bytes 0x6040, is required in order to issue commands. Dictionary objects come in two flavors: Service Dictionary Objects (SDOs) and Process Dictionary Objects (PDOs). They differ in the way they are communicated from the motor controller.
The following diagram shows the flow of CAN packets between a control computer and the motor controller in both data acquisition methods.
GradientOne's CANbus editor
GradientOne allows for sending and receiving CANbus packets through the web browser. To get there, go to https://gradientone-can.appspot.com/instruments. We have connected a CopleyControls AccelNet panel to the gateway for you to acquire live data. In the dropdown menu with "Settings", select "Editor".
You can enter frames in the text area either as:
For this demo, we're going to make the motor move to position 60,000 while collecting data on the motor's position and velocity. In order to map PDOs, we need to first set the CAN network to pre-operational mode: SET PREOP
The PDO's are mapped by sending a series of SDO's. SDO's can be generated in the editor using the WRITE GradientOne shorthand. Lines starting with # are ignored.
# Set Number of Mapped objects on PDO 1 to zero WRITE 0x00 to number_of_mapped_objects_0_tx on node 1 # set the COB-ID of PDO 1 to address + off (0x81010080) WRITE 0x81010080 to pdo_cob-id_0_tx on node 1 # set transmission type to every sync (0x01) WRITE 0x01 to pdo_type_0_tx on node 1 # map PDO 1 to the actual motor position (0x224000), expected data is 4 bytes long (0x20) WRITE 0x20,0x00,0x40,0x22 to pdo_mapping_0_1_tx on node 1 # set the COB-ID of PDO 1 to address + on (0x81010000) WRITE 0x81010000 to pdo_cob-id_0_tx node 1 # Set Number of total Mapped objects on PDO 1 to one WRITE 0x01 to number_of_mapped_objects_0_tx on node 1
Next, do the same for 0x6069 to PDO 2:
# Set Number of Mapped objects on PDO 2 to zero WRITE 0x00 to number_of_mapped_objects_1_tx on node 1 # set the COB-ID of PDO 2 to address + off (0x82010080) WRITE 0x82010080 to pdo_cob-id_1_tx on node 1 # set transmission type to every sync (0x01) WRITE 0x01 to pdo_type_1_tx on node 1 # map PDO 2 to the actual velocity (0x606900), expected data is 4 bytes long (0x20) WRITE 0x20,0x00,0x69,0x60 to pdo_mapping_1_1_tx on node 1 # set the COB-ID of PDO 2 to address + on (0x82010000) WRITE 0x82010000 to pdo_cob-id_0_tx on node 1 # Set Number of total Mapped objects on PDO 2 to one WRITE 0x01 to number_of_mapped_objects_1_tx on node 1
Finish mapping the PDO's by setting the CANopen network to operational:
SET OP
Next, send the command to move to position 60,000:
# Set position mode to target position (0x01) WRITE 0x01 to mode_of_operation on node 1 # Set target position to 60,000 (0xc0270900) WRITE 0xc0270900 to trajectory_generator_position_command on node 1 # Set control word bit 4 (address 0x6040) to move (0x3f00) WRITE 0x3f00 to control_word on node 1 # Set control word bit 4 to done (0x2f00) WRITE 0x2f00 to control_word on node 1
Finally, we want to send several SYNC messages to collect data. With GradientOne's shorthand, we can do this in one step, using a for loop:
SYNC for i in range(0, 20)
Copy and paste these packets into the text area of the CANbus and click add, then click run.
You should see the GradientOne shorthand get translated into the corresponding IDs, command codes and data in the table below.
Once SYNC has been run more than once, the data will be added to a plot:
GradientOne also can simplify this data acquisition process by pulling out values from the Electronic Data Sheet (EDS). To get a trace with this method, click on "Settings" under dropdown menu:
Enter a name Config Name, set the testination to 60,000, set the time window to 1, and select "poll" under DAq method:
The "properties" drop-down will then populate with all of the OD addresses that can be mapped to a PDO. From these properties, select "actual_load_position" and "actual_velocity". After clicking "Save", the config name will show up above the plot. To send this test run to the motor, click on "Run":
The plot should look something like this:
In part two, we'll go over how to use motor controller's trace tool to download data.
|