Introduction
CANOpen is a widely used communication protocol for embedded systems. It is based on the Controller Area Network (CAN) protocol which is a standard in automotive and industrial applications.
The script provided in this article reads 8 values from the controller(Battery volts, Drive stage volts, Motor Command, Motor Amps , Power, Speed, Loop Error, Fault flags) every [X] milliseconds, and then saves them on the User Variables. This is useful when the user wants a supervisory computer to keep track of certain values, possibly for safety reasons.
The user variables in RoboteQ controllers, are by default the objects that are being transmitted with TPDO messages, as described in the CAN networking manual v2.1a. For Gen4 controllers, please refer to CAN EtherCAT networking manual v3.0
Note that TPDOs 5-8 are by default disabled in Roborun+. For this simple example we will use TPDOs 1-4 to transfer up to 8 variables.
Configurations in Roborun+
- Set Script Auto-start to Enabled
- Can Mode : CANOpen (MiniCAN would also work, just select it in CAN Mode setting)
- Bit rate / Node ID / Listen Node / Heartbeat depend on the user’s application
Now check that the send rates for TPDOs 1-4 are configured, and the mapping is correct.
Example : Object ID 0x2106h with sub-index 1 refers to user VAR 1.
TPDO1 contains both :
0x2106h-01h | size : 4 bytes (Signed 32 bit variable)
0x2106h-02h | size : 4 bytes (Signed 32 bit variable)
Microbasic script
DISCLAIMER :
'The script is tested and validated by RoboteQ and is believed to be fault-free.
'The possibility always exists, however, that the specific configuration and/or
'use condition uncovers a fault that escaped our validation test coverage. Always
test extensively the script under your use conditions prior to deploying it in the field.
'Channel 1 used for the queries. Similar queries can be added for channel 2
'--------------- VARIABLES -------------
'The user can add/remove variables according to his needs
option explicit
dim sample_period as integer ' in milliseconds. This should be equal to the configured send rate of TPDOs
dim battery_volts as integer
dim driver_volts as integer
dim mot_command as integer
dim mot_amps as integer
dim power as integer
dim speed as integer
dim loop_error as integer
dim fault_flags as integer
'############### MAIN ########################
sample_period = 10
start :
battery_volts = getvalue(_V , 2)
driver_volts = getvalue(_V , 1)
mot_command = getvalue(_M , 1)
mot_amps = getvalue(_A , 1)
power = getvalue(_P , 1)
speed = getvalue(_S , 1) 'USE THIS WHEN ENCODER IS USED FOR CLOSED LOOP FEEDBACK
'speed = getvalue(_BS , 1) 'USE THIS WHEN INTERNAL SENSOR IS USED FOR FOR CLOSED LOOP FEEDBACK
loop_error = getvalue(_E , 1) 'USED ONLY FOR CLOSED LOOP MODES
fault_flags = getvalue(_FF)
setcommand(_VAR , 1 , battery_volts) 'supply volts x10
setcommand(_VAR , 2 , driver_volts) 'driver internal volts x10
setcommand(_VAR , 3 , mot_command) 'range : -1000....+1000 for open loop, and
min....max speed in Closed loop speed
setcommand(_VAR , 4 , mot_amps) 'motor amps x10
setcommand(_VAR , 5 , power) 'range : -1000.....+1000
setcommand(_VAR , 6 , speed) 'Actual RPM
setcommand(_VAR , 7 , loop_error) 'loop_error = ramped motor command - feedback = desired speed - reported speed
setcommand(_VAR , 8 , fault_flags) 'FF=0 if everything is normal
wait(sample_period)
goto start
Using a CAN sniffer connected to the PC via USB, we can debug and make sure that data are being sent correctly. Keep in mind that the order of the data is reversed (left-most byte is LSB, right-most byte is MSB)