Supported platforms: CODESYS 2.3
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. |
The physical CAN must be initialized according to the device's manual/instructions
The needed VXD and CANopen libraries must be included
Definitions: |
|
VAR_GLOBAL
G_CAN1_CANopenDevice: CANopenDev;
END_VAR
|
Init: |
|
G_CAN1_CANopenDevice.DrvNbr:=0; (* Connect device to can channel *) G_CAN1_CANopenDevice.NodeID := 1; (* Node-ID *) G_CommunicationParameters[4] := 250; (* Bitrate that is not taken from flash *) 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_pDev:=ADR(G_CAN1_CANopenDevice)); (* Connect device to system *)
|
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 |
|
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].Data:=ADR(G_CAN1_CANopenDevice_OD); G_CAN1_CANopenDevice_Protocols[3].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[3].Init:=0; G_CAN1_CANopenDevice_Protocols[3].Update:=0;
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[3]));
|
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(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_CallBackPOU:=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_CallBackPOU:=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_CallBackPOU:=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_CallBackPOU:=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_CallBackPOU:=0);
CANopenODAddLine( (*Communication Parameters*) i_pOD:=ADR(G_CAN1_CANopenDevice_OD),(*Address of Object dictionary where index will be added*) i_index:=16#2003, i_ObjectCode:=OD_ARRAY,(*Type of index*) i_NumOfSubids:=32,(*Length of word array*) i_TypeSpec:=16#0006,(*Index datatype, either user defined or standard CiA 301*) i_ObjectAccess:=G_CANOPEN_OD_ACCESS_SUB0NOWRITE, i_sub0data:=32,(*Length of word array*) i_pIndexData:=ADR(G_CommunicationParameters), i_CallBackPOU:=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_CallBackPOU:=0);
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_NMT: CANopenNMT;
END_VAR
|
Init: |
|
(*Define NMT protocol*) G_CAN1_CANopenDevice_Protocols[1].ProtocolType:=NMT; G_CAN1_CANopenDevice_Protocols[1].Data:=ADR(G_CAN1_CANopenDevice_NMT); G_CAN1_CANopenDevice_Protocols[1].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[1].Init:=INDEXOF(CANopenNMTCLIENT.Init); G_CAN1_CANopenDevice_Protocols[1].Update:=INDEXOF(CANopenNMTCLIENT.Update);
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[1]));
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_SYNC: CANopenSYNC;
END_VAR
|
Init: |
|
(*Define SYNC protocol*) G_CAN1_CANopenDevice_Protocols[6].ProtocolType:=SYNC; G_CAN1_CANopenDevice_Protocols[6].Data:=ADR(G_CAN1_CANopenDevice_SYNC); G_CAN1_CANopenDevice_Protocols[6].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[6].Init:=INDEXOF(CANopenSYNCProtocol.Init); G_CAN1_CANopenDevice_Protocols[6].Update:=0;
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[6]));
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_RPDOS: ARRAY[1..1] OF CANopenPDO; (* RPDO data *) G_CAN1_CANopenDevice_RPDODesc: CANopenDefPDO;
END_VAR
|
Init: |
|
(*Define RPDO protocol*) G_CAN1_CANopenDevice_Protocols[5].ProtocolType:=RPDO; G_CAN1_CANopenDevice_Protocols[5].Data:=ADR(G_CAN1_CANopenDevice_RPDODesc); G_CAN1_CANopenDevice_Protocols[5].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[5].Init:=0; G_CAN1_CANopenDevice_Protocols[5].Update:=INDEXOF(CANopenPDORead);
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[5]));
|
This defines one RPDO byte at index 2200h.
The byte is divided into bits.
Definitions: |
|
VAR_GLOBAL (*VariableObject PDO_Bits1 bit fields *) CANI_PDO_Bits1_Bit0 AT %MX1.0:BOOL:=FALSE; CANI_PDO_Bits1_Bit1 AT %MX1.1:BOOL:=FALSE; CANI_PDO_Bits1_Bit2 AT %MX1.2:BOOL:=FALSE; CANI_PDO_Bits1_Bit3 AT %MX1.3:BOOL:=FALSE; CANI_PDO_Bits1_Bit4 AT %MX1.4:BOOL:=FALSE; CANI_PDO_Bits1_Bit5 AT %MX1.5:BOOL:=FALSE; CANI_PDO_Bits1_Bit6 AT %MX1.6:BOOL:=FALSE; CANI_PDO_Bits1_Bit7 AT %MX1.7:BOOL:=FALSE; END_VAR
VAR_GLOBAL CONSTANT CANI_PDO_Bits1 AT %MB2:BYTE:=0; (* 2201Desc2 *) 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_CallBackPOU:=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 *)
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_TPDOS: ARRAY[1..1] OF CANopenPDO; (* TPDO data *) G_CAN1_CANopenDevice_TPDODesc: CANopenDefPDO;
END_VAR |
|
|
Init: |
|
(* Define TPDO protocol *) G_CAN1_CANopenDevice_Protocols[4].ProtocolType:=TPDO; G_CAN1_CANopenDevice_Protocols[4].Data:=ADR(G_CAN1_CANopenDevice_TPDODesc); G_CAN1_CANopenDevice_Protocols[4].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[4].Init:=0; G_CAN1_CANopenDevice_Protocols[4].Update:=INDEXOF(CANopenPDOSend);
(* Add defined protocol to device *) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[4]));
|
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_CallBackPOU:=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 *)
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_SSDO: CANopenSSDO;
END_VAR
|
Init: |
|
(*Define SSDO protocol*) G_CAN1_CANopenDevice_Protocols[2].ProtocolType:=SSDO; G_CAN1_CANopenDevice_Protocols[2].Data:=ADR(G_CAN1_CANopenDevice_SSDO); G_CAN1_CANopenDevice_Protocols[2].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[2].Init:=INDEXOF(CANopenSDOServer.Init); G_CAN1_CANopenDevice_Protocols[2].Update:=INDEXOF(CANopenSDOServer.Update);
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[2]));
|
Definitions: |
|
VAR_GLOBAL CANopenDeviceEmcyCodes:ARRAY [0..1] OF CANopenEMCYObject; (* EMCY data *) G_CAN1_CANopenDevice_EMCY:CANopenEMCYProtocol;
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[7].Init:=INDEXOF(CANopenEMCYs.Init); G_CAN1_CANopenDevice_Protocols[7].Update:=INDEXOF(CANopenEMCYs.Update);
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDevice:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[3]));
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_HBConsumer: CANopenHeartBeatConsumer;
END_VAR
|
Init: |
|
(*Define HBCons protocol*) G_CAN1_CANopenDevice_Protocols[7].ProtocolType:=HBCons; G_CAN1_CANopenDevice_Protocols[7].Data:=ADR(G_CAN1_CANopenDevice_HBConsumer); G_CAN1_CANopenDevice_Protocols[7].pDevice:=ADR(G_CAN1_CANopenDevice); G_CAN1_CANopenDevice_Protocols[7].Init:=INDEXOF(CANopenHBConsumer.Init); G_CAN1_CANopenDevice_Protocols[7].Update:=INDEXOF(CANopenHBConsumer.Update);
(*Add defined protocol to device*) CANopenDeviceAddProtocol(i_pDev:=ADR(G_CAN1_CANopenDevice), i_pProtocol:=ADR(G_CAN1_CANopenDevice_Protocols[7]));
|
Definitions: |
|
VAR_GLOBAL G_CAN1_CANopenDevice_HbConsumerNodes: ARRAY[1..2] OF CANopenHeartBeat := [(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]));
|
Code:
CANopenInitDevices(); (* Call protocol init funtions *)
|
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
|
Init: |
|
Index2000Data: ARRAY [0..15] OF WORD;(*Application data*)
(**********************************************************************************)
(*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(Index2000Data)/SIZEOF(Index2000Data[0]), (*Length of word array*) i_pIndexData:=ADR(Index2000Data), (*Pointer to indexdata*) i_CallBackPOU:=INDEXOF(Hndl2000h)); (*Callback POU which will cause SDO-Abort if subindex 2 is tryed to write*)
|
Callback code: |
|
PROGRAM Hndl2000h
VAR SDO:POINTER TO CANopenSSDO; 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_CanDevice:=G_CANVXDMSGParam,i_Protocol:=SSDO);
IF (SDO^.MUXinfo AND 16#FF)=2 AND SDO^.post=0 THEN (*if subindex is 2 and post is 0 (see above)*) SDO^.SDOCallbackReturn:=16#06010002; (*SDO abortcode attempt to write read only object*) END_IF
(*if callback POU writes SDOCallbackReturn<>0 this will cause SDO abort*)
|
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 Topic100275.htm
Last updated 19-Dec-2024