Supported platforms: CODESYS 3.5

 

How to use CANopen library in CODESYS 3.5

CANopen protocol initializations are automatically generated to code template when MultiTool Creator is used.

 

This section contains instructions on how to use CANopen library.

 

Do not use string type members in RECORDs.

 

Preconditions

  1. The physical CAN must be initialized according to the device's manual/instructions

  2. The needed VXD and CANopen libraries must be included

 

Step 1: Define the CANopen device

Define the CANopen deviceDefine the CANopen device

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_Channel: CANVXD.Channel;

    G_CAN1_CANopenDevice: CANopenDev;  

 

END_VAR

 

 

Init:

 

 

G_CAN1_CANopenDevice.itfCanChannel := G_CAN1_Channel; (* Connect device to can channel *)

G_CAN1_CANopenDevice.NodeID := 1;                     (* Node-ID *)

G_CAN1_CANopenDevice_NMT.NmtState := 127;             (* Pre-operational state *)

G_CAN1_CANopenDevice_NMT.HeartBeat.PT:=T#200ms;       (* Optional: Change manually heartbeat producer time *)

                                                      (* default 0=no heartbeat *)

CANopenSystemAddDevice(i_pDevice:=ADR(G_CAN1_CANopenDevice)); (* Connect device to system *)

 


 

Step 2: Define the used protocols

The first three are as follows: OD, NMT, SYNC… Select the needed protocols using the following table:

 

What protocols I need, if I want to..

OD

NMT

SYNC

RPDO

TPDO

SSDO

EMCY

HB

Send PDO messages to other devices

X

X

 

 

X

 

 

 

Receive PDO messages from other devices

X

X

 

X

 

 

 

 

Configure device parameters via CAN bus

X

X

 

 

 

X

 

 

Monitor other CANopen devices

X

 

 

 

 

 

 

X

Send synchronous PDO messages to other devices

X

X

X

 

X

 

 

 

Receive PDO messages synchronously from other devices

X

X

X

X

 

 

 

 

Send emergency messages

X

 

 

 

 

 

X

 

  

Define Object Dictionary and OD protocolDefine Object Dictionary and OD protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_OD: CANopenOD;

    G_CAN1_CANopenDevice_ODEntrys: ARRAY[1..69] OF CANopenOD_ENTRY;

    G_CAN1_CANopenDevice_Protocols: ARRAY[1..7] OF CANopenProtocolEntry;

 

END_VAR

 

 

Init:

 

 

(*Initialize OD's data structures. Max entries of given OD(CANopenDeviceODEntrys array)*)

G_CAN1_CANopenDevice_OD.EntryCount:=SIZEOF(G_CAN1_CANopenDevice_ODEntrys)/SIZEOF(G_CAN1_CANopenDevice_ODEntrys[1]);

G_CAN1_CANopenDevice_OD.InOrder:=FALSE;(*OD isn't in order*)

G_CAN1_CANopenDevice_OD.NextFree:=0;(*OD does not have any entries yet*)

G_CAN1_CANopenDevice_OD.pODEntry:=ADR(G_CAN1_CANopenDevice_ODEntrys); (*Pointer to OD array*)

 

(*Define OD protocol*)

G_CAN1_CANopenDevice_Protocols[3].ProtocolType:=OD;

G_CAN1_CANopenDevice_Protocols[3].pData:=ADR(G_CAN1_CANopenDevice_OD);

G_CAN1_CANopenDevice_Protocols[3].pDevice:=ADR(G_CAN1_CANopenDevice);

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[3]));

 

Initialize Object DictionaryInitialize Object Dictionary

This example adds following indexes to OD:

 

Index

Object

Definition

0001h

Deftype

BOOLEAN

0002h

Deftype

INTEGER8

0003h

Deftype

INTEGER16

0004h

Deftype

INTEGER32

0005h

Deftype

UNSIGNED8

0006h

Deftype

UNSIGNED16

0007h

Deftype

UNSIGNED32

0008h

Deftype

REAL32

0009h

Deftype

Visible string

1000h

Var

Device type

1001h

Var

Error register

100Ah

Var

Manufacturer software version

1017h

Var

Producer heart beat time

1018h

Array

Identity object

2130h

Array

EPEC Software information

 

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_OD: CANopenOD;

    G_CAN1_CANopenDevice_ODEntrys: ARRAY[1..69] OF CANopenOD_ENTRY;

    G_CAN1_CANopenDevice_Protocols: ARRAY[1..7] OF CANopenProtocolEntry;

 

END_VAR

 

 

Init:

 

 

(*initialize CAN1 OD*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0001, OD_DEFTYPE, 0, 0, 16#28, 0, 1, 0);(*typedef U1*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0002, OD_DEFTYPE, 0, 0, 16#28, 0, 8, 0);(*typedef I8*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0003, OD_DEFTYPE, 0, 0, 16#28, 0, 16, 0);(*typedef I16*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0004, OD_DEFTYPE, 0, 0, 16#28, 0, 32, 0);(*typedef I32*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0005, OD_DEFTYPE, 0, 0, 16#28, 0, 8, 0);(*typedef U8*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0006, OD_DEFTYPE, 0, 0, 16#28, 0, 16, 0);(*typedef U16*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0007, OD_DEFTYPE, 0, 0, 16#28, 0, 32, 0);(*typedef U32*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0008, OD_DEFTYPE, 0, 0, 16#28, 0, 32, 0);(*typedef of real*)

CANopenODAddLine(ADR(G_CAN1_CANopenDevice_OD), 16#0009, OD_DEFTYPE, 0, 0, 16#28, 0, 80*8, 0);(*typedef str*)

 

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#1000,

    i_ObjectCode:=OD_VAR,(*Type of index*)

    i_NumOfSubids:=0,(*Length of word array*)

    i_TypeSpec:=16#0007,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_NOWRITE OR G_CANOPEN_OD_ACCESS_SUB0NOWRITE,

    i_sub0data:=0,(*Length of word array*)

    i_pIndexData:=ADR(OD_DeviceType_Device1),

    i_itfSDOHandler:=0);

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#1001,

    i_ObjectCode:=OD_VAR,(*Type of index*)

    i_NumOfSubids:=0,(*Length of word array*)

    i_TypeSpec:=16#0005,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_NOWRITE OR G_CANOPEN_OD_ACCESS_SUB0NOWRITE,

    i_sub0data:=0,(*Length of word array*)

    i_pIndexData:=ADR(OD_ErrorReg_Device1),

    i_itfSDOHandler:=0);

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#100a,

    i_ObjectCode:=OD_VAR,(*Type of index*)

    i_NumOfSubids:=0,(*Length of word array*)

    i_TypeSpec:=16#0009,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_NOWRITE OR G_CANOPEN_OD_ACCESS_SUB0NOWRITE,

    i_sub0data:=0,(*Length of word array*)

    i_pIndexData:=ADR(SystemParameters.o_SoftwareVersion),

    i_itfSDOHandler:=0);

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#1017,

    i_ObjectCode:=OD_VAR,(*Type of index*)

    i_NumOfSubids:=0,(*Length of word array*)

    i_TypeSpec:=16#0006,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=0,

    i_sub0data:=0,(*Length of word array*)

    i_pIndexData:=ADR(G_CAN1_CANopenDevice_NMT.HeartBeat.PT),

    i_itfSDOHandler:=0);

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#1018,

    i_ObjectCode:=OD_ARRAY, (*Type of index*)

    i_NumOfSubids:=4,

    i_TypeSpec:=16#0007,(*Index of 16-bit deftype*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_NOWRITE OR G_CANOPEN_OD_ACCESS_SUB0NOWRITE,

    i_sub0data:=4,

    i_pIndexData:=ADR(OD_IdentityArray_Device),

    i_itfSDOHandler:=0);

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#2130,

    i_ObjectCode:=OD_ARRAY, (*Type of index*)

    i_NumOfSubids:=10,

    i_TypeSpec:=16#0009,(*Index of 16-bit deftype*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_NOWRITE OR G_CANOPEN_OD_ACCESS_SUB0NOWRITE,

    i_sub0data:=10,

    i_pIndexData:=ADR(OD_SoftwareInformation),

    i_itfSDOHandler:=0);

 

 

 

 

 


Define NMT protocolDefine NMT protocol

 

Definitions:

 

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_NMT: CANopenNMT;

    G_CAN1_CANopenDevice_NMT_Handler: CANopenNMTClient;  

 

END_VAR

 

 

Init:

 

 

(*Define NMT protocol*)

G_CAN1_CANopenDevice_Protocols[1].ProtocolType:=NMT;

G_CAN1_CANopenDevice_Protocols[1].pData:=ADR(G_CAN1_CANopenDevice_NMT);

G_CAN1_CANopenDevice_Protocols[1].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[1].itfProtocol:=G_CAN1_CANopenDevice_NMT_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[1]));

 


Define SYNC protocolDefine SYNC protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_SYNC: CANopenSYNC;

    G_CAN1_CANopenDevice_SYNC_Handler: CANopenSYNCProtocol;

      

END_VAR

 

 

Init:

 

 

(*Define SYNC protocol*)

G_CAN1_CANopenDevice_Protocols[6].ProtocolType:=SYNC;

G_CAN1_CANopenDevice_Protocols[6].pData:=ADR(G_CAN1_CANopenDevice_SYNC);

G_CAN1_CANopenDevice_Protocols[6].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[6].itfProtocol:=G_CAN1_CANopenDevice_SYNC_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[6]));

 


Define RPDO protocolDefine RPDO protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_RPDOS: ARRAY[1..1] OF CANopenPDO; (* RPDO data *)

    G_CAN1_CANopenDevice_RPDODesc: CANopenDefPDO;

    G_CAN1_CANopenDevice_RPDO_Handler: CANopenRPDO;

 

END_VAR

 

 

Init:

 

 

(*Define RPDO protocol*)

G_CAN1_CANopenDevice_Protocols[5].ProtocolType:=RPDO;

G_CAN1_CANopenDevice_Protocols[5].pData:=ADR(G_CAN1_CANopenDevice_RPDODesc);

G_CAN1_CANopenDevice_Protocols[5].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[5].itfProtocol:=G_CAN1_CANopenDevice_RPDO_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[5]));

 

 

Define RPDO dataDefine RPDO data

This defines one RPDO byte at index 2200h.

The byte is divided into bits.

 

Definitions:

 

VAR_GLOBAL

    (* RPDO data in OD *)

    OD_ByteVarIndex2200h AT %MB0: BYTE := 0;

 

    (* CAN IN data for application *)

    CANI_PDO_Bits1 AT %MB2: BYTE := 0;

    /// bit 1

    CANI_b1 AT %MX1.0: BOOL := FALSE;

    /// bit 2

    CANI_b2 AT %MX1.1: BOOL := FALSE;

    /// bit 3

    CANI_b3 AT %MX1.2: BOOL := FALSE;

    /// bit 4

    CANI_b4 AT %MX1.3: BOOL := FALSE;

    /// bit 5

    CANI_b5 AT %MX1.4: BOOL := FALSE;

    /// bit 6

    CANI_b6 AT %MX1.5: BOOL := FALSE;

    /// bit 7

    CANI_b7 AT %MX1.6: BOOL := FALSE;

    /// bit 8

    CANI_b8 AT %MX1.7: BOOL := FALSE;

 

END_VAR

 

 

Init:

 

 

(* Add RPDO to OD *)

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#2200,

    i_ObjectCode:=OD_VAR,(*Type of index*)

    i_NumOfSubids:=0,(*Length of word array*)

    i_TypeSpec:=16#0005,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=0,

    i_sub0data:=0,(*Length of word array*)

    i_pIndexData:=ADR(OD_ByteVarIndex2200h),

    i_itfSDOHandler:=0);

 

(* Initialize CAN1 RPDOs *)

G_CAN1_CANopenDevice_RPDOS[1].i_Mapping[0]:= 16#22010208;

G_CAN1_CANopenDevice_RPDOS[1].Init(

    i_pDevice:= ADR(G_CAN1_CANopenDevice),

    i_PDONumber:= 0,

    i_PDOType:= ReceivePDO,

    i_COB_ID:= 16#201,

    i_TransmissionType:= 16#ff,

    i_InhibitTime:= 100,

    i_Reserved:= 0,

    i_EventTime:= 300,

    i_Mappings:= 1);

 

G_CAN1_CANopenDevice_RPDODesc.pPDO:=ADR(G_CAN1_CANopenDevice_RPDOS);(*connect PDO to Protocol descriptor of RPDO*)

G_CAN1_CANopenDevice_RPDODesc.Count:=1; (* Amount of RPDOs *)

 

 


Define TPDO protocolDefine TPDO protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_TPDOS: ARRAY[1..1] OF CANopenPDO; (* TPDO data *)

    G_CAN1_CANopenDevice_TPDODesc: CANopenDefPDO;

    G_CAN1_CANopenDevice_TPDO_Handler: CANopenTPDO;

 

END_VAR

 

 

Init:

 

 

(* Define TPDO protocol *)

G_CAN1_CANopenDevice_Protocols[4].ProtocolType:=TPDO;

G_CAN1_CANopenDevice_Protocols[4].pData:=ADR(G_CAN1_CANopenDevice_TPDODesc);

G_CAN1_CANopenDevice_Protocols[4].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[4].itfProtocol:=G_CAN1_CANopenDevice_TPDO_Handler;

 

(* Add defined protocol to device *)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[4]));

 

 

Define TPDO dataDefine TPDO data

This defines one TPDO

 

Definitions:

 

VAR_GLOBAL

    (* TPDO variable *)

    CANO_PDO_Byte1 AT %MB1: BYTE := 0;

  

END_VAR

 

 

Init:

 

(* Add TPDO to OD *)

CANopenODAddLine(

    i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*)

    i_index:=16#2201,

    i_ObjectCode:=OD_ARRAY,(*Type of index*)

    i_NumOfSubids:=2,(*Length of word array*)

    i_TypeSpec:=16#0005,(*Index datatype, either user defined or standard CiA 301*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_SUB0NOWRITE OR G_CANOPEN_OD_ACCESS_PDOMAP,

    i_sub0data:=2,(*Length of word array*)

    i_pIndexData:=ADR(CANO_PDO_Byte1),

    i_itfSDOHandler:=0);

 

(* Initialize CAN1 TPDOs *)

G_CAN1_CANopenDevice_TPDOS[1].i_Mapping[0]:= 16#22010108;

G_CAN1_CANopenDevice_TPDOS[1].Init(

    i_pDevice:= ADR(G_CAN1_CANopenDevice),

    i_PDONumber:= 0,

    i_PDOType:= TransmitPDO,

    i_COB_ID:= G_CAN1_CANopenDevice.NodeID + 16#180,

    i_TransmissionType:= 16#ff,

    i_InhibitTime:= 100,

    i_Reserved:= 0,

    i_EventTime:= 300,

    i_Mappings:= 1);

G_CAN1_CANopenDevice_TPDODesc.pPDO:=ADR(G_CAN1_CANopenDevice_TPDOS);(*connect PDO to Protocol descriptor of TPDO *)

G_CAN1_CANopenDevice_TPDODesc.Count:=1; (* Amount of TPDOs *)

 

 


Define SSDO protocolDefine SSDO protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_SSDO: CANopenSSDO;

    G_CAN1_CANopenDevice_SSDO_Handler: CANopenSDOSERVER; 

 

END_VAR

 

 

Init:

 

 

(*Define SSDO protocol*)

G_CAN1_CANopenDevice_Protocols[2].ProtocolType:=SSDO;

G_CAN1_CANopenDevice_Protocols[2].pData:=ADR(G_CAN1_CANopenDevice_SSDO);

G_CAN1_CANopenDevice_Protocols[2].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[2].itfProtocol:=G_CAN1_CANopenDevice_SSDO_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[2]));

 

 


Define EMCY protocolDefine EMCY protocol

 

Definitions:

 

VAR_GLOBAL

    CANopenDeviceEmcyCodes:ARRAY [0..1] OF CANopenEMCYObject;   (* EMCY data *)

    G_CAN1_CANopenDevice_EMCY:CANopenEMCYProtocol;

    G_CAN1_CANopenDevice_EMCY_Handler: CANopenEMCYs;

 

END_VAR

 

 

Init:

 

 

(*Define EMCY protocol*)

G_CAN1_CANopenDevice_Protocols[3].ProtocolType:=EMCY;

G_CAN1_CANopenDevice_Protocols[3].pData:=ADR(CANopenEMCYData);

G_CAN1_CANopenDevice_Protocols[3].pDevice:=ADR(CANopenDevice);          

G_CAN1_CANopenDevice_Protocols[3].itfProtocol:=G_CAN1_CANopenDevice_EMCY_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[3]));

 


Define HB consumer protocolDefine HB consumer protocol

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_HBConsumer: CANopenHeartBeatConsumer;

    G_CAN1_CANopenDevice_HBConsumer_Handler: CANopenHBConsumer;  

 

END_VAR

 

 

Init:

 

 

(*Define HBCons protocol*)

G_CAN1_CANopenDevice_Protocols[7].ProtocolType:=HBCons;

G_CAN1_CANopenDevice_Protocols[7].pData:=ADR(G_CAN1_CANopenDevice_HBConsumer);

G_CAN1_CANopenDevice_Protocols[7].pDevice:=ADR(G_CAN1_CANopenDevice);

G_CAN1_CANopenDevice_Protocols[7].itfProtocol:=G_CAN1_CANopenDevice_HBConsumer_Handler;

 

(*Add defined protocol to device*)

CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[7]));

 

 

Add nodes to HB consumerAdd nodes to HB consumer

 

Definitions:

 

VAR_GLOBAL

    G_CAN1_CANopenDevice_HbConsumerNodes: ARRAY[1..2] OF CANopenHeartBeatProducer :=

        [(i_NodeID := 2, i_Time := T#100ms, i_pNext := 0),

         (i_NodeID := 3, i_Time := T#100ms, i_pNext := 0)];

 

END_VAR

 

 

Init:

 

 

(* Add monitored nodes *)

CANopenConsumeHB(i_pDevice := ADR(G_CAN1_CANopenDevice), i_pProducer:=ADR(G_CAN1_CANopenDevice_HbConsumerNodes[1]));

CANopenConsumeHB(i_pDevice := ADR(G_CAN1_CANopenDevice), i_pProducer:=ADR(G_CAN1_CANopenDevice_HbConsumerNodes[2]));

 

 

 

Step 3: Initialize defined protocols

Code:

 

CANopenInitDevices(); (* Call protocol init funtions *)

 

 

Step 4: Use defined protocols

Code:

 

 

G_CAN1_Channel.CheckMessages(); (* Receive CAN data *)

CANopenUpdateDevices();         (* Update all data of protocols in devices and send CAN data *)

 

(* Check for NMT reset *)

IF G_CAN1_CANopenDevice_NMT.StateChanged THEN

   IF G_CAN1_CANopenDevice_NMT.LastNmtCommand = 16#81 OR G_CAN1_CANopenDevice_NMT.LastNmtCommand = 16#82 THEN

      (* If there is NMT reset command for IEC application CANopen device,

      IEC application is started after IEC cycle in execution. *)

      G_RESET_MODULE := TRUE;

   END_IF

END_IF

 

 

Create SDO callbackCreate SDO callback

 

Init:

 

VAR_GLOBAL

    G_Index2000Data: ARRAY [0..15] OF WORD;(*Application data*)

 

END_VAR

 

(**********************************************************************************)

 

(*Add index 2000h for application data and deny write access to subindex 2*)

(*Add index 2000h array of 16 16bit parameters*)

 

CANopenODAddLine(

    i_pOD:=ADR(CANopenDeviceOD),     (*Address of Object dictionary where index will be added*)

    i_index:=16#2000,                (*Index 2000h*)

    i_ObjectCode:=OD_ARRAY,          (*Type of index*)

    i_NumOfSubids:=SIZEOF(Index2000Data)/SIZEOF(Index2000Data[0]),  (*Length of word array*)

    i_TypeSpec:=16#0006,                                            (*Index of 16-bit deftype*)

    i_ObjectAccess:=G_CANOPEN_OD_ACCESS_SUB0NOWRITE,                (*Subindex 0 readonly*)

    i_sub0data:=SIZEOF(G_Index2000Data)/SIZEOF(G_Index2000Data[0]), (*Length of word array*)

    i_pIndexData:=ADR(G_Index2000Data),                             (*Pointer to indexdata*)

    i_itfSDOHandler:=Hndl2000h);                                    (*Callback*)

 

 

Callback code:

 

 

(*Callback which will cause SDO-Abort if subindex 2 is tried to write*)

FUNCTION_BLOCK Hndl2000h IMPLEMENTS ICANopenSDOHandler

 

 

METHOD HandleSDO

VAR_INPUT

    i_pDevice: POINTER TO CANopenDev; (* Pointer to device *)

END_VAR

 

 

VAR

    SDO:POINTER TO CANopenSSDO;

    subindex: BYTE;

END_VAR

 

(**********************************************************************************)

 

(*post  State                      Description

    0   SDO Download indication    Beginning of SDO-data download to index, data is intact

    1   SDO Download end           Data is transferred to index data-contets is new-data

    2   SDO Upload indication      Beginning of SDO-data upload from index, data is not send jet

    3   SDO Upload end             Data is transferred From index to bus

*)

 

SDO:=CANopenGetProtocolData(i_pDevice:=i_pDevice,i_Protocol:=SSDO);

 

subindex:=DWORD_TO_BYTE(SDO^.MUXinfo AND 16#FF);

IF 2 = subindex AND 0 = post THEN                 (*if subindex is 2 and post is 0 (see above)*)

    (*SDO abortcode attempt to write read only object*)

    SDO^.SDOCallbackReturn:=G_CANOPEN_SDO_ABORT_WRITE_READ_ONLY;  

END_IF

 

(*if callback POU writes SDOCallbackReturn<>0 this will cause SDO abort*)

 

 

Diagnose missing HBDiagnose missing HB

 

Definitions:

 

VAR

    Module02Missing:BOOL;

    Module03Missing:BOOL;

 

END_VAR

 

 

Code:

 

 

IF 16#FF = G_CAN1_CANopenDevice_HbConsumerNodes[0].o_State THEN (* HB producer status is timeout *)

    Module02Missing:=TRUE;

ELSE

    Module02Missing:=FALSE;

END_IF

 

IF 16#FF = G_CAN1_CANopenDevice_HbConsumerNodes[1].o_State THEN (* HB producer status is timeout *)

    Module03Missing:=TRUE;

ELSE

    Module03Missing:=FALSE;

END_IF

 

 

 

 

Source file topic000829.htm

Last updated 13-Jun-2024