1

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
DK999
  • 33
  • 1
  • 7
  • The EtherCAT bus needs at least something to be synced with, as the message says. In your case, you should really link the EtherCAT master AmsNetId and the EtherCAT slave port number variables (if the latter is possible to be linked), so that if those values would change, your code would still work. But for start, just add a variable `EtherCatDevState AT%I* : UINT;` somewhere and link it to `Antrieb 1.InfoData.State` seen in the image. Now you have at least one linked variable, which is enough. If everything works after that, I can help you with linking the AmsNetId if you like. – Quirzo Mar 04 '20 at 09:30
  • I've created the variable and linked it to `Antrieb.InfoData.State` but the message still occurs :-/ Have also seen that my AmsNetID was wrong, should have taken a closer look to my own screenshot – DK999 Mar 04 '20 at 11:17
  • So you still get the "needs sync master (at least one variable linked to a task variable)"? Did you activate configuration after linking the variable? It's required to get the link to work. If so, try to link something under the CX5120.InfoData, for example the CfgSlaveCount. Just incase for testing. – Quirzo Mar 04 '20 at 12:01
  • Doesn't matter which variable under InfoData I'm using (Antrieb or CX5120), it's always telling me the device needs a sync master. Can't build the solution without this error and can't activate without it. – DK999 Mar 04 '20 at 12:41
  • Are you sure it's not complaining about another device then? Try to disable all other devices except the "CX5120 (EtherCAT)" EtherCAT master – Jakob Mar 04 '20 at 15:20
  • Yeah, pretty sure about that. I've connected the (UINT) uLink with the (UINT)State of Antrieb and still getting the message. Doesn't matter if I use any other object under InfoData of Antrieb or CX5120 https://i.imgur.com/VeVQrro.png – DK999 Mar 05 '20 at 06:19
  • That's what I'm thinking also. In all of my cases, the warning message has disappeared after linking. And note also that the project should build fine even if you get that message, it doesn't affect that. – Quirzo Mar 05 '20 at 06:19
  • Actually, I have to take my words back. It seems that the message won't go away with just linking the InfoData. Sorry about that, I remembered it wrong. It seems to need a linked variable from a device that uses a sync unit, and the InfoData seems not to do that. Do you have any variables that can be linked from the Antrieb 1 or other devices? If not, I think you should contact Beckhoff support. I'm also interested in the correct solution. – Quirzo Mar 05 '20 at 06:32
  • I linked a UINT-Variable to the Eingänge(Inputs)/DevState, this seems to work, so screw the InfoData :D So thanks, linking was indeed the solution but to another value than expected. Anyway, is there a possibility to read the length of a Service Data Object? Reading and writing works fine now, but I have to change the cbBufLen of the FB_EcCoeSdoWrite to match the wordsize of the SDO. – DK999 Mar 05 '20 at 07:01
  • Thats great to hear! I don't know about reading the data size, sorry. The way I have used is that I will define the target variables as correct types (like UINT, REAL etc) and then when reading the value just give the size parameter with SIZEOF(). So if you have `VariableToWrite1 : REAL;` and `VariableToWrite2 : INT;`, you will get the correct size with for example: `pSrcBuf := ADR(VariableToWrite1), cbBufLen := SIZEOF(VariableToWrite1);` and so on – Quirzo Mar 05 '20 at 10:53
  • So when I want to write to different SDOs, the User needs to know it's size or I have to store the size of every SDO in my code and change the size-parameter given to the function-call in a huge switch-statement before? Is there a more elegenat way than storing hundreds of SDO-sizes or hoping the user knows what he does? :D – DK999 Mar 06 '20 at 06:29
  • I'm not sure. I can't find any way to read the CoE index size and other info. At least I think the user who uses that `FB_EcCoESdoWrite` needs to know the size. I might as well be wrong. – Quirzo Mar 06 '20 at 06:53

2 Answers2

1

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

DK999
  • 33
  • 1
  • 7
0

You should assign a task to your devices who is responsible to read/write data. double click your master device, go to EtherCAT tab and click on Sync Unit Assignment

there select your terminals then available tasks and apply!