Forum: Mikrocontroller und Digitale Elektronik wer kann codesys programmieren


von vicara (Gast)


Lesenswert?

Guten Tag,
ich habe eine Frage, wer kann hier Codesys programmieren?
Ich habe hier ein Projekt in Codesys auf einer SPS und  verstehe nicht 
warum eine Funktion immer zweimal Daten in mein CANOPEN Netz schickt.
 es handelst sich um folgenden Code.
1
IF SDOWrite.CONFIRM THEN
2
  // SDO Write successful.
3
  xEnable := FALSE;
4
ELSIF SDOWrite.ERROR <> CiA405.CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_NO_ERROR THEN
5
  // Error occured
6
  IF SDOWrite.ERROR = CIA405.CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_OTHER_ERROR THEN
7
    //output error info contains abort code in little endian format
8
    MEMUtils.MemCpy(pbyDest := ADR(dwAbortCode), pbySrc := ADR(SDOWrite.ERRORINFO), dwSize := SIZEOF(dwAbortCode));
9
    MEMUtils.SwapLocalToIntel(pAddress := ADR(dwAbortCode), iSize := TO_INT(SIZEOF(dwAbortCode))); //function only swaps on big endian systems  
10
  END_IF
11
  xEnable := FALSE;
12
END_IF
13
14
SDOWrite(  Enable     := xEnable,
15
       Network    := CANbus.NetId + 1, //CODESYS NetId starts by 0 (the number entered into the CANbus configurator); CiA405 NETWORK by 1; That is the reason why we have to increment it here.
16
           Timeout    := 0, //Timeout for SDO read in ms. Here: 0 ==> no timeout
17
           Device     := CANopenRemoteDevice.NodeID, // NodeID of destination device
18
           Channel    := 0, //SDO channel which should be used. 0 means auto channeling ==> the next free channel will be used. It depends on the slave which settings are working here but 0 and channel 1 is always working. 
19
           Index      := 16#3000, //object index which should be written ==> 16#3000 = simple string object
20
           SubIndex   := 0, //object sub index which should be written
21
       MODE      := CIA405.SDO_MODE.AUTO, //Use SDO mode AUTO ==> Mode will be selected automatically. Use SDO_MODE.BLOCK for forcing Block Transfer.
22
           Data       := ADR(aData), // Pointer to data buffer where result should be written to.
23
           DataLength := TO_UDINT(Stu.StrLenA(ADR(aData[0]))) //Length of data
24
);

xEnable wird nur einmal auf True gesetzt.
Was übersehe ich???
Danke
lG

von Witkatz :. (wit)


Lesenswert?

vicara schrieb:
> xEnable wird nur einmal auf True ..

..in dem Quellcode gesetzt, den du nicht gepostet hast.

Wenn xEnable an einer Stelle im Programm gesetzt wird bedeutet nicht 
zwangsweise, dass es nur einmal gesetzt wird. SPS arbeitet zyklisch, die 
Variable wird in jedem Zyklus gesetzt, in dem die Zuweisung abgearbeitet 
wird. So wie ich das sehe, wird xEnable an zwei Stellen auf FALSE 
gesetzt: im IF und im ELSIF Block.

Mach dir ein Zeitdiagramm mit allen beteiligten Signalen Ablauf. Damit 
sollte ersichtlich sein, wann und für wie lange xEnable auf TRUE gesetzt 
wird und wann die beiden geposteten Bedingungen zum Zurücksetzen von 
xEnable erfüllt sind
SDOWrite.CONFIRM
und
SDOWrite.ERROR <> CiA405.CANOPEN_KERNEL_ERROR.CANOPEN_KERNEL_NO_ERROR

Wenn in der Zeitspanne in der xEnable auf TRUE gesetzt wird eine der 
Bedingungen auch nur für einen SPS Zyklus erfüllt ist, dann geht xEnable 
kurz auf FALSE. Der SDOWrite erkennt mehrere Triggerflanken auf Enable 
und sendet die Daten mehrfach.

Eigentlich wäre das eine Frage für sps-forum.de

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.