plctwincatcanopenstructured-textethercat

TwinCAT CoE: Write to SDO


I'm pretty new to the EtherCAT/CANopen universe and trying to implement a custom slave. The slave is passing conformance test so far and want to write to one of my Slave Data Objects, the slave is attached to a CX5120, which is found by the XAE and also shows the Slave device. For that, I copied my ESI-file to the TwinCAT folder (C:\TwinCAT\3.1\Config\Io\EtherCAT).

Project Tree Slave Data Objects I've created a small Structured Text PLC program that uses FB_EcCoESdoWrite to write data to address 0x607A. But when I set it active and try to connect, Visual Studio tells me that the device needs at least one Sync Master. Also, when setting bExecute to TRUE, I'm getting an error from the function. As far as I understand, I have to link variables between my ST program and the slave, but I don't see the need of linking variables because afaik the function call should manage the transmission? What are the steps to write to a SDO of an ESC? Can someone tell me what I'm missing or has a small example at hand?

PROGRAM MAIN
VAR
heartbeat       : UINT; 
fbSdoWrite      : FB_EcCoESdoWrite;
sNetId          : T_AmsNetId := '5.76.204.148.1.1'; (* NetId of EtherCAT Master *)
nSlaveAddr      : UINT := 1001; (* Port Number of EtherCAT Slave *)
nIndex          : WORD := 16#607A; (* CoE Object Index *)
nSubIndex       : BYTE := 0; (* Subindex of CoE Object *)
nValue          : UINT := 16#AAAA; (* variable to be written to the CoE Object *)
bExecute                : BOOL; (* rising edge starts writing to the CoE Object *)
bError          : BOOL;
nErrId          : UDINT;
END_VAR

fbSdoWrite(
        sNetId          := sNetId,
        nSlaveAddr      := nSlaveAddr,
        nIndex          := nIndex,
        nSubIndex       := nSubIndex,
        pSrcBuf         := ADR(nValue),
        cbBufLen        := SIZEOF(nValue),
        bExecute        := bExecute
);


IF NOT fbSdoWrite.bBusy THEN
        bExecute := FALSE;
        IF NOT bError THEN 
                (* write successful *)
                bError := FALSE;
                nErrId := 0;
        ELSE 
                (* write failed *)
                bError := fbSdoWrite.bError;
                nErrId := fbSdoWrite.nErrId;
        END_IF

        fbSdoWrite(bExecute := FALSE);
END_IF

Solution

  • Fixed problem by linking variable from PLC code to DevState-input of the device. Linking to plain InfoData doesn't seem to work though.