TSM#Let’s Connect the CET5 to the EXOR XA5 Codesys via CAN Bus!

In this article, we will connect TSM’s CET5 sensor to EXOR’s in-vehicle HMI XA5 and perform CANopen communication on the CODESYS Runtime.

Furthermore, we will make it possible to check the acquired data from the JMobile screen.

Let’s enjoy FA.

CET?

The CET5 is a robust, high-performance wire-actuated displacement sensor with CANopen output, possessing the high quality and durability required for industrial applications. Due to its excellent repeatability, high IP protection rating, shock and vibration resistance, and electromagnetic noise immunity, it is suitable for mobile hydraulic equipment such as agricultural vehicles, earthmoving machinery, construction machinery, articulated arm cranes, and aerial work platforms.

The order code for the CET5 series is configured by combining measurement range, power supply voltage range, output method, connection specifications, sensor configuration, customization availability, and certification specifications. By specifying each code, you can select product specifications according to your application. For example, you can clearly specify specifications such as measurement range, CANopen communication, Deutsch connector, redundant sensor configuration, and SIL2/PLd support on the order code.

Operating Principle

The wire-actuated displacement sensor has an internally supported drum supported by bearings, around which a wire rope is wound.

When the wire rope is pulled out, the drum rotates in conjunction with its movement. The linear movement amount of the wire rope is converted into the rotation angle of the drum.

By detecting the rotation angle of this drum, the pull-out amount of the wire, i.e., the linear displacement amount, is measured.

Note that using the sensor beyond the maximum wire pull-out length may damage the wire and internal mechanism. When using, always use within the measurement range defined in the specifications.

Terminal Block

CANOPEN

CANopen is an open and non-proprietary standard communication protocol based on CAL (CAN Application Layer), which is the application layer of the Controller Area Network (CAN). It is a communication standard located at the 7th layer of the ISO/OSI reference model, developed and internationally standardized by the CAN in Automation (CiA) user group, and is still maintained today.

The CET sensor, as a CANopen device, meets the requirements of device specifications based on CiA DS301. It also partially supports CiA DS406, which is a device profile for encoders, and CiA DS410, which is a device profile for inclinometers.

Communication Objects

CANopen communication is performed via CAN messages. A CAN message is a command sent to or from a device, and is exchanged on the CAN bus in the form of a network packet.

Each CAN message consists of the following elements:

  • Identifier (CAN message ID)
  • Control bits
  • 0 to 8 bytes of data

CAN messages are sometimes called Communication Objects, or COB for short. Also, the CAN message ID is called COB-ID.

All numeric data types are stored in the data field in little-endian format. Therefore, the LSB (Least Significant Byte) is placed at the lowest data index, and the MSB (Most Significant Byte) is placed at the highest data index. An example placement is shown in the table below.

The 11-bit identifier (COB-ID) consists of a 4-bit function code and a 7-bit Node ID. The function code indicates the type and priority of the communication object, and the Node ID is used to identify CANopen devices existing on the same network. This mechanism allows each communication object to be properly identified and managed within the CANopen network.

This mechanism allows for peer-to-peer communication between one CANopen master device and up to 127 NMT slave CANopen devices. The CET supports the communication objects detailed in the chapters below.

  • Network Management Object (NMT)
  • Synchronization Object (SYNC)
  • Emergency Object (EMCY)
  • Process Data Object (PDO)
  • Service Data Object (SDO)
  • Node Guarding / Heartbeat

PDO

Process Data Objects (PDOs) are mapped to a single CAN frame using a data field of up to 8 bytes to transmit application objects.

Transfer via PDO takes place in real time without additional protocol overhead. Each PDO is assigned a unique identifier and is transmitted from only one node. However, that PDO can be received by multiple nodes. This is called producer/consumer communication.

PDOs are defined by communication parameters and mapping parameters. Communication parameters indicate the communication functions and conditions of the PDO, and mapping parameters indicate the data content contained in that PDO.

Communication parameters and application parameters that determine the operation of a CANopen device are managed in a standardized list called an Object Dictionary.

In the object dictionary, a unique 24-bit address is assigned to all data exchanged between the communication part, such as the CANopen protocol stack, and the device’s application software part.

This 24-bit address consists of the following two:

  • 16-bit Index
  • 8-bit SubIndex

Each entry in the CANopen object dictionary can be read using CANopen communication services.

TPDO1 – Linear sensors output

Depending on the device version, different static mappings are provided for TPDO1. Specifically, there are mappings for the CET5 model and mappings for the CET7, CET12, and CET20 models, respectively.

TSM16 mapping: Valid for CET5:

TSM32 mapping: Valid for CET7, CET12, CET20:

Position 1 and Position 2 indicate the length measurements obtained by the two linear sensors. The data format depends on the mapping method.

  • TSM16 mapping: INT16
  • TSM32 mapping: INT32

The endian format is little-endian, and the resolution is 0.1 mm.

  • Position 1 is represented as a direct value (0 to FS).
  • Position 2 is represented as a complement value (0 to -FS).

For TSM16 mapping, if the length measurement is 1000.0 mm:

D0 = 0x10, D1 = 0x27
→ Position 1 = 0x2710 = 10000d

Since the resolution is 0.1 mm,

10000 × 0.1 mm = 1000.0 mm

On the other hand, Position 2 is represented as a complement value as follows:

D2 = 0xF0, D3 = 0xD8

→ Position 2 = 0xD8F0 = -10000d

In other words, -10000 × 0.1 mm = -1000.0 mm

TPDO2 – Inclinometers output

This mapping function is available for all CET models with built-in inclinometers.

Angle 1 and Angle 2 indicate the angle measurements obtained by the two inclinometers, the data format is INT16, and the endian format is little-endian. The resolution is 0.1°.

Angle 1 is represented as the angle in the clockwise direction (0 to 3599).
Angle 2 is represented as the angle in the counterclockwise direction (3599 to 0).

Here, since the value is represented in 0.1° units, for example, 900 means 90.0°.

If the angle measurement is 90.0°:

D0 = 0x84, D1 = 0x03
→ Angle 1 = 0x0384 = 900d

Since the resolution is 0.1°,
900 × 0.1° = 90.0°.

On the other hand, Angle 2 is represented as a value in the counterclockwise direction as follows:

D2 = 0x8C, D3 = 0x0A
→ Angle 2 = 0x0A8C = 2700d

In other words, 2700 × 0.1° = 270.0°.

SDO

Service Data Objects (SDO) are used to read from and write to entries in the object dictionary. The SDO transfer protocol supports object transfers of arbitrary size, and transmits and receives data divided into multiple segments as necessary. Each segment contains control information and user data, and the receiving side returns a confirmation response for each segment or segment block. If the transfer fails, an abort message is sent.

The CET also includes an SDO server function as a standard setting. In SDO communication, you can read and write data to the object dictionary, and the CET supports both expedited transfer and normal transfer (segmented transfer). Expedited transfer is a method of transmitting and receiving small amounts of data up to 4 bytes in a single CAN frame.

Transmission

To initiate an expedited transfer, the master sends the following message:

Cmd is the command specifier indicating the request type.

Index and Sub-Id indicate the address of the object dictionary entry to be accessed. Data stores the write value in the case of a write command.

Reception

The sensor responds with the following message:

Ans is the response specifier indicating the response type.

Index and Sub-Id indicate the address of the object dictionary entry that was accessed. Data stores the read value in the case of a read command.

If the transfer fails, an abort code is stored in the Data field.

The 0x80 abort message indicates that the transfer did not complete successfully.

The reason for this is one of the reasons listed in the abort code table in section 8.3.

Node ID

Each device on the CANopen network is uniquely identified by its own Node-ID. The Node-ID is set in the range of 1 to 127 and must be set so that it does not overlap within the same network. To change the Node-ID, send the SDO command shown below.

(Default ID=4)

Store parameters

All parameters in the object dictionary can be saved to a dedicated area provided in the internal non-volatile memory. This storage area is protected by checksum calculation and mirrored backup. This ensures that data loss is prevented even if an unexpected power failure occurs during the saving process.

However, due to the internal structure of the microcontroller, there is a limit to the number of times parameters can be written, which is up to 10,000 times.

Store default parameters

By using this SDO, all parameters in the object dictionary saved in the non-volatile memory can be restored to factory default values. Note that a device reset is required to complete the restoration process.

set/reset customer INCLINOMETER ZERO point (Preset value)

With this command, the angle measurement value can be corrected to an arbitrary preset value. If you set 0 as the preset value, you can register the current sensor position as the zero point of the inclination angle. In the case of a redundant sensor configuration, this setting applies to both of the two angle outputs.

  • Format: UINT16
  • Resolution: Resolution set by another command.
  • Range: 0 to 65535

PRESET value

Operation

0

Set zero point

Non-zero

Set preset point

FB

Next, I will introduce the FB used in this article.

SDO_WRITE_DATA (FB)

This function block is used to write data to a specific object in the device’s object dictionary. When data is written without error, CONFIRM becomes TRUE.

DATA must be specified in little-endian byte order. If an error occurs, ERROR will be a non-zero value.

If an SDO abort occurs, ERROR is set to CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR, and the corresponding abort code defined in CiA 301 is stored in ERRORINFO in little-endian format.

VAR_INPUT

Name

Type

Description

NETWORK

USINT

Specifies the CAN network number on which the function block operates. This is different from the network number on the CANbus configurator. The NETWORK of CiA405 is calculated as NETID + 1. Example: 1 = CAN0, 2 = CAN1, 3 = CAN2

ENABLE

BOOL

Activates the function block on the rising edge. Interrupts processing on the falling edge.

TIMEOUT

UDINT

Specifies the timeout time in ms. 0 means no timeout.

DEVICE

DEVICE

Specifies the Node-ID of the destination device. 0 means the local device, i.e., CANopen Manager.

CHANNEL

USINT

Specifies the SDO channel to use. 0 uses any free channel, 1..n specifies a specific channel.

INDEX

WORD

Specifies the Index of the object to be written to.

SUBINDEX

BYTE

Specifies the SubIndex of the object to be written to.

MODE

SDO_MODE

Specifies the SDO mode to use. Usually use SDO_MODE.AUTO.

DATA

POINTER TO BYTE

Specifies the pointer to the data to be written. The data must be specified in little-endian byte order.

DATALENGTH

UDINT

Specifies the length of the data to be written in bytes.

CONFIRM

BOOL

TRUE indicates that the function block has completed normally without errors.

ERROR

CANOPEN_KERNEL_ERROR

Indicates the content of the error that occurred during processing. Refer to CANOPEN_KERNEL_ERROR for details.

VAR_OUTPUT

Name

Type

Description

CONFIRM

BOOL

TRUE indicates that the SDO write processing has completed normally without errors.

ERROR

CANOPEN_KERNEL_ERROR

Indicates the error code that occurred. Refer to CANOPEN_KERNEL_ERROR for details.

ERRORINFO

SDO_ERROR

Indicates detailed information when an SDO abort occurs. If ERROR is CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR, the abort code defined in CiA 301 is stored in little-endian format.

SDO_READ

SDO_READ function block is used to read data from a specified object in the CANopen device’s object dictionary. When reading is completed normally, CONFIRM becomes TRUE, and the read data is stored in DATA in little-endian byte order. When an error occurs, ERROR will be non-zero. If an SDO abort occurs, ERROR is set to CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR, and the abort code defined in CiA 301 is stored in ERRORINFO in little-endian format.

VAR_INPUT

Name

Type

Description

NETWORK

USINT

Specifies the CAN network number on which the function block operates. This is different from the network number on the CANbus configurator. The NETWORK of CiA405 is calculated as NETID + 1. Example: 1 = CAN0, 2 = CAN1, 3 = CAN2

ENABLE

BOOL

Activates the function block on the rising edge. Interrupts processing on the falling edge.

TIMEOUT

UDINT

Specifies the timeout time in ms. 0 means no timeout.

DEVICE

DEVICE

Specifies the Node-ID of the destination device. 0 means the local device, i.e., CANopen Manager.

CHANNEL

USINT

Specifies the SDO channel to use. 0 uses any free channel, 1..n specifies a specific channel.

INDEX

WORD

Specifies the Index of the object to be read.

SUBINDEX

BYTE

Specifies the SubIndex of the object to be read.

MODE

SDO_MODE

Specifies the SDO mode to use. Usually use SDO_MODE.AUTO.

DATA

POINTER TO BYTE

Specifies the pointer to the memory area where the read data will be written. The data is stored in the CANopen byte order, i.e., little-endian format.

Implementation

Then, let’s actually create the project.

Codesys side

First, build from the Codesys side of the EXOR XA5.

Adding CAN master

Select Device from the Codesys project → right-click → Add Device.

Add Fieldbus → CANBus.

Now CANBus has been added.

Adding CAN manager

Next, to add CANOpen Manager, right-click on the CANBus added earlier → Add Device.

Let’s add CANopen → CANopen Manager → CANopen Manager.

Now the CANOPEN Master has been added.

Installing EDS file

Next, to install the EDS FILE for the TSM CET5 sensor used in this article, click Tools → Device Repository.

Click the Install button.

Select the CET5 EDS FILE.

Now the CET5 EDS FILE is registered.

Adding CET5

Next, to add the TSM CET5 sensor to the CAN OPEN network, right-click on CANopen Manager → Add Device.

Select and add the TSM CET5 sensor (SI) used in this article.

The TSM CET5 sensor has been added to the CAN OPEN network.

From “Address” in the CANOPEN I/O Mapping Tab, you can see that the absolute address occupied by this Sensor starts at %IB100. That address will be used when defining variables in the GVL later.

CAN bus settings

Next, set the CANbus communication settings, etc.

Set General → Network to 0. We will use CAN BUS1 of the XA5, so if you use CAN BUS2, set the Network number = 1. Also, set the Baud Rate according to your application.

CAN Open Manager settings

Now set up the CAN Open Manager.

Just setting General → Node-ID is fine.

CET5 sensor settings

Finally, it is the setting for CET5.

Set the Node-ID of the CET sensor in General → Node-ID. We will use the sensor’s default value 4.

Also, uncheck the Reset Node Checkbox in the figure below.

GVL

gHMI

This GVL is for reading and writing HMI, and defines global variables for storing values to be acquired/set via SDO communication, etc. We have prepared arrays for reading and writing of REAL type, BOOL type, and INT type, which are used as temporary storage areas for various parameters. We also define string variables to store the device name, hardware version, and firmware version.

{attribute ‘qualified_only’}
VAR_GLOBAL
arrr32,arrwr32 :ARRAY[0..99]OF REAL;
arrrx,arrwx :ARRAY[0..99]OF BOOL;
arrri,arrwi :ARRAY[0..99]OF INT;
TSM_4_strDeviceName :STRING;
TSM_4_strHardwareVersion :STRING;
TSM_4_strFirmwareVersion :STRING;
END_VAR

gTSM

This GVL defines variables mapped directly to the input memory area to reference the input data received from the CET5 device on CODESYS. CET5_0_0 treats the 4-byte input data starting from %IB100 as a USINT array, and CET5_0_1 treats the 2-word input data starting from %IW52 as a UINT array. This allows you to reference the received PDO data in byte or word units.

{attribute ‘qualified_only’}
VAR_GLOBAL
CET5_0_0 AT %IB100 :ARRAY[0..3]OF USINT;
CET5_0_1 AT %IW52 :ARRAY[0..1]OF UINT;
END_VAR

pTSMCET5_ID004

Next, let’s create a program.

VAR

Define the variables for the program used in this article.

PROGRAM pTSMCET5_ID004
VAR
Position1,Position2:INT;
rPosition1,rPosition2:REAL;
ErrorRegister: INT;
NumbeOfErrors: INT;
arrErrroField: ARRAY[0..7] OF DINT;
i: INT;
iTestCounter: INT;
xParametersStoreOK: BOOL;
xParametersStoreError: BOOL;
xBusReset: BOOL;
iInitCounter: INT;
xDataIntited: BOOL;
END_VAR

VAR
iInitStep:INT;
xReInit :BOOL;
xInited:BOOL;
xInitError:BOOL;
xInitReset:BOOL;
INDEX:WORD;
SUBINDEX:WORD;
data:ARRAY[0..99]OF BYTE;
data2:ARRAY[0..3]OF BYTE;
uint8Baudrate :USINT;
uint8NodeID :USINT;
strDeviceName:STRING;
strHardwareVersion:STRING;
strFirmwareVersion:STRING;
setValue:DINT;
iSDOReadPollingStep:INT;
xSensorSetZero: BOOL;
xSensorSetZeroErr: BOOL;
xSensorSetZeroOK: BOOL;
fbTON1,fbTON2:Standard.TON;
END_VAR
VAR
NodeID:INT;
DeviceState:INT;
CANMasterStatus: _3SCOS.CANOPEN_KERNEL_STATE;
DATALENGTH:UDINT;
DATALENGTH2:UDINT;
ERRORINFO:CIA405.SDO_ERROR;
EERR:CIA405.SDO_ERROR;
MODE:CIA405.SDO_MODE;
DEVICE:CIA405.DEVICE:=4;
fbR_TRIG:Standard.R_TRIG;
fbR_TRIG2:Standard.R_TRIG;
fbR_TRIG3:Standard.R_TRIG;
SDO_READ_DATA :CIA405.SDO_READ_DATA;
SDO_READ_DATA2 :CIA405.SDO_READ4;
SDO_WRITE_DATA :CIA405.SDO_WRITE_DATA;
SDO_WRITE_DATA2 :CIA405.SDO_WRITE_DATA;
arrdata000 :ARRAY[0..3]OF BYTE;
xParametersStore:BOOL;

iDummy:INT;
END_VAR

a000SDOInitData

This program is an initialization process that reads device information and communication setting values using SDO communication when the CET5 device starts or when a re-initialization request is made.

SDO_READ_DATA function block, it sequentially reads 1008h, 1009h, 100Ah, 3000h, and 3001h from the object dictionary to obtain the device name, hardware version, firmware version, baud rate, and Node-ID.

Each SDO Read process is executed sequentially by step control, and an initialization completion flag is set when it completes successfully. If an error occurs during processing, it transitions to the initialization error state and stops SDO communication.

fbR_TRIG3(CLK:=
iInitCounter=0
);

fbR_TRIG2(CLK:=
( xReInit ) AND NOT SDO_READ_DATA.ENABLE
);
IF fbR_TRIG2.Q OR fbR_TRIG3.Q THEN
IF TRUE THEN
NodeID:=IoConfig_Globals.SI.NodeID;
iInitStep:=10;
;
END_IF
END_IF;

IF iInitStep > 0 AND TO_INT(SDO_READ_DATA.ERROR)<>0 THEN
iInitStep:=999;
END_IF

CASE iInitStep OF

0:
SDO_READ_DATA.ENABLE:=FALSE;
;
10:
xInited:=FALSE;
xDataIntited:=FALSE;
xInitError:=FALSE;
strDeviceName:=”;
SDO_READ_DATA.INDEX:=16#1008;
SDO_READ_DATA.SUBINDEX:=16#00;
MEM.MemFill(ADR(data),SIZEOF(data),0);
DATALENGTH:=100;
SDO_READ_DATA.ENABLE:=TRUE;
iInitStep:=15;
15:
IF SDO_READ_DATA.CONFIRM THEN
MEM.MemMove(
ADR(data),ADR(strDeviceName)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA.ENABLE:=FALSE;
iInitStep:=20;
END_IF;
;
20:
strHardwareVersion:=”;
SDO_READ_DATA.INDEX:=16#1009;
SDO_READ_DATA.SUBINDEX:=16#00;
MEM.MemFill(ADR(data),SIZEOF(data),0);
DATALENGTH:=100;
SDO_READ_DATA.ENABLE:=TRUE;
iInitStep:=25;
25:
IF SDO_READ_DATA.CONFIRM THEN
MEM.MemMove(
ADR(data)
,ADR(strHardwareVersion)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA.ENABLE:=FALSE;
iInitStep:=30;
END_IF;
;
30:
strFirmwareVersion:=”;
SDO_READ_DATA.INDEX:=16#100A;
SDO_READ_DATA.SUBINDEX:=16#00;
MEM.MemFill(ADR(data),SIZEOF(data),0);
DATALENGTH:=100;
SDO_READ_DATA.ENABLE:=TRUE;
iInitStep:=35;
35:
IF SDO_READ_DATA.CONFIRM THEN
MEM.MemMove(
ADR(data)
,ADR(strFirmwareVersion)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA.ENABLE:=FALSE;
iInitStep:=40;
END_IF;
40:
uint8Baudrate:=0;
SDO_READ_DATA.INDEX:=16#3000;
SDO_READ_DATA.SUBINDEX:=16#00;
MEM.MemFill(ADR(data),SIZEOF(data),0);
DATALENGTH:=100;
SDO_READ_DATA.ENABLE:=TRUE;
iInitStep:=45;
45:
IF SDO_READ_DATA.CONFIRM THEN
MEM.MemMove(
ADR(data)
,ADR(uint8Baudrate)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA.ENABLE:=FALSE;
iInitStep:=50;
END_IF;
50:
uint8NodeID:=0;
SDO_READ_DATA.INDEX:=16#3001;
SDO_READ_DATA.SUBINDEX:=16#00;
MEM.MemFill(ADR(data),SIZEOF(data),0);
DATALENGTH:=100;
SDO_READ_DATA.ENABLE:=TRUE;
iInitStep:=55;
55:
IF SDO_READ_DATA.CONFIRM THEN
MEM.MemMove(
ADR(data)
,ADR(uint8NodeID)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA.ENABLE:=FALSE;
iInitStep:=60;
END_IF;
60:
iInitStep:=899;

899:
iInitStep:=900;
900:
xInited:=TRUE;
iTestCounter:=iTestCounter+1;
xDataIntited:=TRUE;
iInitCounter:=iInitCounter+1;

999:
xInitError:=TRUE;
SDO_READ_DATA.ENABLE:=FALSE;
IF xInitReset THEN
xInitError:=FALSE;
iInitStep:=0;
END_IF
;


END_CASE

a100CANBusStatus

This program acquires the communication status of the CANopen Manager and the target device, and resets the CAN bus alarm if necessary. Also, it expands the 4-byte position data received via PDO from the CET5 into two INT16 values, Position1 and Position2. Since the position data resolution of the CET5 is 0.1 mm, it divides the acquired integer value by 10 and treats it as real position data rPosition1 and rPosition2 in mm units.

CANMasterStatus:=IoConfig_Globals.CANopen_Manager.KernelState;
DeviceState:=TO_INT(IoConfig_Globals.SI.CANopenState);

IF xBusReset THEN
IoConfig_Globals.CANbus.ResetBusAlarm();
END_IF

a200PDO

MEM.MemMove(ADR(gTSM.CET5_0_0),ADR(Position1),SIZEOF(Position1));
MEM.MemMove(ADR(gTSM.CET5_0_0[2]),ADR(Position2),SIZEOF(Position2));
rPosition1:=TO_REAL(Position1)/10.0;
rPosition2:=TO_REAL(Position2)/10.0;

a300SDOWrite

This calls the program for writing parameters via SDO.

a310SetZero();
a399StoreParams();

a310SetZero

This program detects the rising edge of the zero point setting request xSensorSetZero, and executes SDO writing using the SDO_WRITE_DATA function block. If SDO writing completes normally, xSensorSetZeroOK is set to TRUE, and if an error occurs, xSensorSetZeroErr is set to TRUE. After processing is complete or an error occurs, it sets SDO_WRITE_DATA.ENABLE back to FALSE to prepare for the next request.

fbR_TRIG(CLK:=xSensorSetZero);

IF fbR_TRIG.Q THEN
SDO_WRITE_DATA.ENABLE:=TRUE;
END_IF

IF SDO_WRITE_DATA.CONFIRM THEN
xSensorSetZeroOK:=TRUE;
SDO_WRITE_DATA.ENABLE:=FALSE;
xSensorSetZeroErr:=FALSE;
END_IF

IF TO_INT(SDO_WRITE_DATA.ERROR) <> 0 THEN
xSensorSetZeroOK:=FALSE;
SDO_WRITE_DATA.ENABLE:=FALSE;
xSensorSetZeroErr:=TRUE;
END_IF

a399StoreParams

This program sets the string “save” used for the parameter save command to the byte array arrdata000. By writing this data to 1010h:01h via SDO_WRITE_DATA2, it requests parameter saving to the non-volatile memory inside the sensor. If SDO writing completes normally, xParametersStoreOK becomes TRUE, and if an error occurs, xParametersStoreError becomes TRUE.

arrdata000[0]:=16#73;
arrdata000[1]:=16#61;
arrdata000[2]:=16#76;
arrdata000[3]:=16#65;


xParametersStoreError:=TO_INT(SDO_WRITE_DATA2.ERROR) <>0;
xParametersStoreOK:=SDO_WRITE_DATA2.CONFIRM;

a400SDOPolling

In this program, after the CET5 device initialization is complete, error information is periodically read via SDO communication. It acquires the number of errors registered in the error history from 1003h:00h from the error history, and acquires the state of the Error Register from 1001h:00h.

In normal operation, it repeats reading at a 500ms cycle, and if an SDO communication error occurs, it stops SDO Read once, then waits for 500ms and retries.

IF iSDOReadPollingStep > 0 AND TO_INT(SDO_READ_DATA2.ERROR)<>0 THEN
iSDOReadPollingStep:=999;
END_IF

CASE iSDOReadPollingStep OF

0:
SDO_READ_DATA2.ENABLE:=FALSE;
IF xInited THEN
iSDOReadPollingStep:=10;
END_IF
;
10:
NumbeOfErrors:=0;
SDO_READ_DATA2.INDEX:=16#1003;
SDO_READ_DATA2.SUBINDEX:=16#00;
MEM.MemFill(ADR(data2),SIZEOF(data2),0);
DATALENGTH:=100;
SDO_READ_DATA2.ENABLE:=TRUE;
iSDOReadPollingStep:=15;
15:
IF SDO_READ_DATA2.CONFIRM THEN
MEM.MemMove(
ADR(data2),ADR(NumbeOfErrors)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA2.ENABLE:=FALSE;
iSDOReadPollingStep:=20;
END_IF;
;
20:
ErrorRegister:=0;
SDO_READ_DATA2.INDEX:=16#1001;
SDO_READ_DATA2.SUBINDEX:=16#00;
MEM.MemFill(ADR(data2),SIZEOF(data2),0);
DATALENGTH:=100;
SDO_READ_DATA2.ENABLE:=TRUE;
iSDOReadPollingStep:=25;
25:
IF SDO_READ_DATA2.CONFIRM THEN
MEM.MemMove(
ADR(data2),ADR(ErrorRegister)
,uiNumberOfBytes:=TO_UINT(DATALENGTH)
);
SDO_READ_DATA2.ENABLE:=FALSE;
iSDOReadPollingStep:=60;
END_IF;
;
60:
iSDOReadPollingStep:=899;

899:
fbTON1(IN:=TRUE,PT:=T#500MS);
IF fbTON1.Q THEN
fbTON1(IN:=FALSE);
iSDOReadPollingStep:=10;
END_IF

999:
fbTON2(IN:=TRUE,PT:=T#500MS);
IF fbTON2.Q THEN
fbTON2(IN:=FALSE);
iSDOReadPollingStep:=10;
SDO_READ_DATA2.ENABLE:=FALSE;
END_IF
;


END_CASE


SDO_READ_DATA2.NETWORK:=1;

SDO_READ_DATA2(
NETWORK:=
,ENABLE:=
,TIMEOUT:=0
,CONFIRM=>
,ERROR=>EERR
,CHANNEL:=
,DEVICE:=IoConfig_Globals.SI.NodeID
,INDEX:=
,SUBINDEX:=
,DATA=>data2
,DATALENGTH=>DATALENGTH2
,ERRORINFO=>ERRORINFO
)
;

a990HMI

In this program, information acquired from the CET5 device, communication status, position data, error information, and operation results are transferred to the HMI global variable gHMI.

It also reflects operation requests from the HMI side to internal PLC control variables.

gHMI.TSM_4_strDeviceName:=strDeviceName;
gHMI.TSM_4_strFirmwareVersion:=strFirmwareVersion;
gHMI.TSM_4_strHardwareVersion:=strHardwareVersion;

gHMI.arrri[0]:=uint8NodeID;
gHMI.arrri[1]:=uint8Baudrate;
gHMI.arrri[2]:=iInitStep;
gHMI.arrri[3]:=DeviceState;
gHMI.arrri[4]:=TO_INT(CANMasterStatus);
gHMI.arrri[5]:=iSDOReadPollingStep;
gHMI.arrri[6]:=NumbeOfErrors;
gHMI.arrri[7]:=ErrorRegister;

gHMI.arrr32[0]:=rPosition1;
gHMI.arrr32[1]:=rPosition2;

gHMI.arrrx[0]:=xDataIntited;
gHMI.arrrx[1]:=xInitError;
gHMI.arrrx[2]:=xSensorSetZeroOK;
gHMI.arrrx[3]:=xSensorSetZeroErr;
gHMI.arrrx[4]:=xParametersStoreOK;
gHMI.arrrx[5]:=xParametersStoreError;

xReInit:=gHMI.arrwx[0];
xSensorSetZero:=gHMI.arrwx[1];
xParametersStore:=gHMI.arrwx[2];
xBusReset:=gHMI.arrwx[3];

a999BlockCall

In this program, the function blocks for SDO reading for initialization, SDO reading for error information polling, SDO writing for zero point setting, and SDO writing for parameter saving are called.

SDO_READ_DATA.NETWORK:=1;

SDO_READ_DATA(
NETWORK:=
,ENABLE:=
,TIMEOUT:=0
,CONFIRM=>
,ERROR=>EERR
,CHANNEL:=0
,DEVICE:=IoConfig_Globals.SI.NodeID
,INDEX:=
,SUBINDEX:=
,MODE:=MODE
,DATA:=ADR(data)
,DATALENGTH:=DATALENGTH
,ERRORINFO=>ERRORINFO
)
;

SDO_READ_DATA2.NETWORK:=1;

SDO_READ_DATA2(
NETWORK:=
,ENABLE:=
,TIMEOUT:=0
,CONFIRM=>
,ERROR=>EERR
,CHANNEL:=
,DEVICE:=IoConfig_Globals.SI.NodeID
,INDEX:=
,SUBINDEX:=
,DATA=>data2
,DATALENGTH=>DATALENGTH2
,ERRORINFO=>ERRORINFO
)
;

SDO_WRITE_DATA(
NETWORK:=1
,DEVICE:=4
,CHANNEL:=0
,INDEX:=16#6003
,SUBINDEX:=0
,Data:=ADR(setValue)
,DATALENGTH:=SIZEOF(setValue)
);

SDO_WRITE_DATA2(
NETWORK:=1
,ENABLE:=xParametersStore
,DEVICE:=4
,CHANNEL:=0
,INDEX:=16#1010
,SUBINDEX:=1
,Data:=ADR(arrdata000)
,DATALENGTH:=SIZEOF(arrdata000)
);

Download

Finally, download the project to the Codesys Runtime with Online → Login.

Results

Communication between the Codesys Runtime and the TSM CET5 sensor has been established.

EXOR side

Next, build the HMI on the EXOR side.

Screen

This is the screen created for this article.

LED variable

Although it was not used in this article, I defined an LED variable specifically for XA5.

Results

You can check the operation in this video.

Download

You can download the project created in this article from the link below.

https://github.com/soup01Threes/Codesys/blob/main/Demo_TSM_CET5_XA5.zip

シェアする

  • このエントリーをはてなブックマークに追加

フォローする