Interpreter commands for SDO transfer

(only available for certain terminals with CANopen transfer protocols)

This document describes how to read and write values through an SDO channel, without using a variable connected to a certain CANopen object (index and subindex).

Note: Not all terminalls support these functions - only devices with CANopen since 2004 (see Feature Matrix) !

Contents

See also:



Basic SDO read/write access using an interpreter function

Programmable terminals with CANopen protocol (since 2004) can read or write simple values in a remote device via SDO channel, without the need to use a specially configured variable for it.
The following explanation applies only to the display interpreter.
For devices with the newer script language (which uses a compiler, not an interpreter), similar commands/function may be available, but they must be prefixed by 'cop.' (short for 'CANopen') to avoid namespace pollution.

Syntax:
sdo( [ #SDO-client-index , ] < index >.< subindex> [ , data type ] [ , default value ]  )
Examples:
@X = sdo(0x6000.1, U8) : rem READ a value from a remote device
sdo(0x6200.1, U8)= X+1 : rem WRITE a value to a remote device

The specification of the SDO client index is optional. When not specified, the first SDO client will be used (with index zero). Thus the following commands have the same effect:

  sdo(#0,0x6411.04,I16) = 29490 : REM set 4th analog output to +9 V
  sdo( 0x6411.04 , I16) = 29490 : REM set the same output, using the same SDO client

You should specify the data type of the object in the remote device, otherwise the value may be misinterpreted (especially for floating point or 4-byte-integer). Available data types are:

BOOLEAN, BOOL
Only "True" or "False" (not exactly defined in CANopen, we guess it's a single-bit-variable)
INTEGER8, I8
signed 8 bit integer
INTEGER16, INT16, I16
signed 16 bit integer
INTEGER32, INT32, I32, LONG
signed 32 bit integer
UNSIGNED8, U8, BYTE
unsigned 8 bit integer
UNSIGNED16, U16, WORD
unsigned 16 bit integer
UNSIGNED32, U32, DWORD
unsigned 32 bit integer ("double word")
FLOAT32, F32, FLT
32 bit floating point as specified by CANopen

Note: The first name is the offical name by CiA, the second is a short form which can be used alternatively.

For very special cases, you can also specify a default value, which will be returned by the function if the access fails.

Example:
@Temp = sdo(0x6000.1, Temp)

Here, the value of 'Temp' won't change if the SDO-read-access fails (otherwise 'Temp' would be set to 0x8001EEEE, which is the internal 32-bit code for "illegal value").


back to top


SDO timeouts

In 2011-07-13, yet another problem with CANopen occurred when the firmware in a certain CANopen device (slave) had terribly slow SDO accesses.
To avoid problems with hard-coded SDO timeout values (on the SDO client side), the following interpreter command was implemented in the display terminal firmware.

Syntax:

sdo.timeout_ms = new_timeout_in_milliseconds
Modifies the maximum "waiting time" in the SDO client.
If the response (SDO read- or write-response) doesn't arrive within the specified time (measured in milliseconds), the SDO access function will abort, and return with an error code.
If the display application doesn't use the sdo.timeout command, the firmware will use the default timeout value, which used to be 1000 milliseconds.
Note:
Do not modify the CANopen timeout value before the CANopen protocol stack is initialized, otherwise the configured timeout value will be overwritten during initialisation.
For that reason, the following example

    sdo.timeout_ms = 5000 : REM set SDO timeout to 5 seconds

will not work in the page-enter event on page zero, because page zero is displayed before the CANopen protocol is initialized !
Furthermore, certain 'special functions' (like the CANopen node scanner implemented in a certain device) will overwrite the SDO client's timeout value.


Error handling for SDO access functions

In a well-behaving terminal application, you should check if the SDO transfers are successfull, and inform the user if there is a problem.

The reason for such an SDO communication problem may be as simple as an unplugged CAN bus cable, but it may be more complicated. CANopen defines so-called "abort codes" which are listed below. There is an interpreter function in the terminal firmware which allows you to retrieve the last abort code, to write your own error event handler (an example follows later).

Syntax:

sdo.abort
returns the SDO abort code from the last erroneous SDO transfer. If nothing went wrong, the result is zero. This function may be used in a global event definition to trap any SDO errors. Please note: Once sdo.abort is non-zero, it will not return to zero automatically. The error code must be "cleared" (sdo.abort=0) after handling it.
sdo.abort.i (or sdo.abort.index)
returns the CANopen object index which was accessed when the last SDO abort occurred. You may show this value on the display to simplify "debugging" for the end-user.
sdo.abort.s (or sdo.abort.subindex)
returns the subindex of the CANopen object which was accessed when the last SDO abort occurred.

SDO abort codes

The following codes may be returned by the function "sdo.abort". Zero means "no SDO abort" (no error recently).

Some of these codes are defined by CANopen, some are specific to the CANopen implementation in the terminal.
Please note: (*) Due to problems in a certain network, abort code 0x05040000 will only be returned by the "sdo.abort" function if three SDO-communication timeouts occurred in a row. This reduces the chance of false alarms if the network suffers from an occasional loss of CAN messages. All other abort codes will be returned "immediately", though.
SDO Abort Code Meaning
0x00000000 no abort, no SDO error (yet) - TERMINAL SPECIFIC !
0x05030000 SDO toggle bit error (protocol violation)
0x05040000 SDO communication timeout (*)
0x05040001 unknown SDO command specified (protocol incompatibility)
0x05040002 invalid SDO block size
0x05040003 invalid sequence number
0x05040004 CRC error (cyclic redundancy code, during block transfer)
0x05040005 out of memory
0x06010000 unsupported access
0x06010001 tried to read a WRITE-ONLY object
0x06010002 tried to write a READ-ONLY object
0x06020000 object does not exist (in the CANopen object dictionary)
0x06040041 object cannot be mapped (into a PDO)
0x06040042 PDO length exceeded (when trying to map an object)
0x06040043 general parameter incompatibililty
0x06040047 general internal incompatibility
0x06060000 access failed due to hardware error
0x06070010 data type and length code do not match
0x06070012 data type problem, length code is too high
0x06070013 data type problem, length code is too low
0x06090011 subindex does not exist
0x06090030 value range exceeded
0x06090031 value range exceeded, too high
0x06090032 value range exceeded, too low
0x06090036 maximum value is less than minimum value
0x08000000 general error
0x08000020 data could not be transferred or stored
0x08000021 data could not be transferred due to "local control"
0x08000022 data could not be transferred due to "device state"
0x08000023 object dictionary does not exist
Note: If you also wonder why there is no 'abort code' for an SDO timeout, read the CANopen protocol specification. As usual, the reason for NOT having an 'abort code' for this is quite academic.

See also: Retrieve SDO-Abort-Codes in the script .

back to top


File: ..?..\uptwin1\help\sdocm_01.htm
Author: W.Büscher, MKT Systemtechnik
Last modified: 2014-05-07 (ISO8601, YYYY-MM-DD)

back to top