Hi Leute!
Ich bin noch ziemlich neu im EtherCAT/CANopen Universum und versuche momentan, einen selbst geschriebenen Slave über eine Beckhoff CX5120 SPS an zu sprechen.
Mein Slave Device durchläuft den Conformance Test von Beckhoff und kann mit PySOEM mit dem PC verbunden auch beschrieben/gelesen werden.
Jetzt habe ich ein kleines XAE Projekt im Visual Studio aufgesetzt, das ESI File ins TwinCAT-Verzeichnis kopiert (C:\TwinCAT\3.1\Config\Io\EtherCAT), als Ziel die SPS ausgewählt und konnte CX5120 und meinen Slave finden / das Object Dictionary auslesen.
![]()
Mit einem kleinen SPS Structured Text Programm versuche ich nun an die Adresse 0x607A einen Wert zu schreiben und nutze dafür die FB_EcCoESdoWrite Funktion. Während der Aktivierung bekomme ich eine Meldung, dass die CX5120 einen Sync Master benötigt. Wenn ich mich mit dem Gerät verbinde und die Funktion ausführen lasse, bekomme ich von ihr ebenfalls einen Fehler zurück (bError wird TRUE).
Soweit ich mich eingelesen habe, muss ich eine Variable aus meinem ST Programm mit einer Variable aus meinem Slave oder CX5120 linken, damit der Sync Manager zugewiesen ist.
Nur scheine ich keine Variablen zu benötigen, da der Funktionsaufruf doch die Pakete versenden/empfangen sollte?
Was habe ich bei der Konfiguration/Programmierung übersehen?
Gibt es irgendwo ein Minimal-Beispiel, wie man in einem Projekt mit SDOs kommuniziert?
Code:
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