Bausteine von TIA nach Codesys V2.3 mit variablen Arrays

vollmi

Level-3
Beiträge
5.680
Reaktionspunkte
1.600
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi zusammen

Ich hab grade den Auftrag ein recht altes Programm in einer Codesys V2.3 Steuerung mit einem Treiber von mir auszurüsten, den ich auf TIA V16 geschrieben habe.
Ich hab schonmal Codesys programmiert, das ist aber auch schon 10 Jahre her und dabei habe ich nur an der Oberfläche gekratzt.

Womit ich grade meine Mühe habe ist die portierung diverser Funktionen mit variablen Arrayzugriffen als einfach es Beispiel eine Funktion für eine Checksumme.
Code:
FUNCTION FC_Fut_Checksum : BYTEVAR_INPUT
      Proof : ARRAY
[*] OF BYTE;
      start : INT;   (* erstes Element der Prüfung *)
      end : INT;   (* letztes Element der Prüfung *)
END_VAR
VAR
      index : INT;
END_VAR




(* @END_DECLARATION := '0' *)
	FC_Fut_Checksum := 0;
	FOR index := start TO end DO
	    FC_Fut_Checksum := FC_Fut_Checksum - Proof[index];
	END_FOR;
END_FUNCTION

Dass Array
[*] nicht funktioniert habe ich mir schon gedacht, nur habe ich gerade keine Idee wie ich möglichst simpel übersetzen könnte? Ich möchte den Treiber möglichst lesbar übertragen so dass ich spätere verbesserungen auf der Siemens Seite auch wieder in Codesys übertragen kann ggf auch später in V3.

Kleine Erklärung zur Funktion. Ich hab da ein Array angehängt. die sind verschieden gross und ich will aus dem Array zwei Summen auslesen, z.B. von byte 0-7 und von Byte 9-17 und mit den hinterlegenten Checksummen auf Byte 8 und byte 18 vergleichen. mit start/end lege ich den bereich fest.

Ich wäre jetzt sehr froh über einen Tip wie man das möglichst einfach und effizient in die Codesyswelt übertragen könnte.
 
Für CodeSys 2 fällt mir das ausser einem Pointer nichts ein.
Code:
Proof:POINTER TO ARRAY[0..MaxSize] OF BYTE;
Ich nehme an, dass Du schon ausserhalb der Funktion sicherstellst, dass Start und End keine Bereichsüberschreitungen verursachen können. Eine zusätzliche Übergabe der aktuellen Arraygrösse wird also nicht notwendig sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal vorneweg: ARRAY
[*] gibt es nur in CoDeSys V3. CoDeSys V2 wurde entwickelt zu Step7 - Zeiten und auch hier dreht sich das Rad weiter.

CoDeSys ist beachtet strict den Typ. Du hast also keine Chance ein Array von dieser, mal von jener Länge an einen Baustein zu hängen. Die Lösung wird wohl sein das du die Adresse des StartBytes (bzw. des Arrays) und die Länge übergibst. Wird bei vielen Bausteinen so gemacht. Im Aufruf der Funktion wird dann anstattt myArr dann mit ADR(myArr) gearbeitet.
In der Funktion musst du das Ganze dann de-referenzieren. Den Code selber kannst du dann quasi übernehmen...

Alternativ: Überzeug deinen Kunden das, wenn er die Maschine schon abändert gleich auf CoDeSys V3 umsteigt. Irgendwann (Glaskugel sagt so in ca 10 Jahren) wird es vermutlich auch enger mit Ersatzrechner die 32 Bit code rechen können.

Guga
 
Für CodeSys 2 fällt mir das ausser einem Pointer nichts ein.
Code:
Proof:POINTER TO ARRAY[0..MaxSize] OF BYTE;
Ich nehme an, dass Du schon ausserhalb der Funktion sicherstellst, dass Start und End keine Bereichsüberschreitungen verursachen können. Eine zusätzliche Übergabe der aktuellen Arraygrösse wird also nicht notwendig sein.

Ich hab das mal so versucht
Code:
FUNCTION FC_Fut_Checksum : BYTE
VAR_INPUT
      Proof : POINTER TO ARRAY[0..32000] OF BYTE;
      start : INT;   (* erstes Element der Prüfung *)
      end : INT;   (* letztes Element der Prüfung *)
END_VAR
VAR
      index : INT;
    PT1: BOOL;
END_VAR




(* @END_DECLARATION := '0' *)
FC_Fut_Checksum := 0;
    FOR index := start TO end DO
        FC_Fut_Checksum := FC_Fut_Checksum - proof[index];
    END_FOR;




END_FUNCTION

Jetzt kriege ich aber beim Aufruf
Code:
testarray[7] := FC_Fut_Checksum(testarray, 0, 6);

Den fehler:
Anmerkung 2020-09-03 134115.jpg

Das kann doch nicht so schwer sein. Irgendwas grundlegendes hab ich noch nicht verstanden.
Ist das nicht so das er bei pointer to array das array überlagert?

Begrenzen tue ich die bereiche schon im programm. In TIA habe ich aber mit upper und lowerbound noch eine zweite Sicherheit eingebaut.
 
Alternativ: Überzeug deinen Kunden das, wenn er die Maschine schon abändert gleich auf CoDeSys V3 umsteigt. Irgendwann (Glaskugel sagt so in ca 10 Jahren) wird es vermutlich auch enger mit Ersatzrechner die 32 Bit code rechen können.
Ich würd ja CodeSys V3 einsetzen aber leider sind da noch 150 Stück Wago 750-881 drin. Die kann ich schlecht alle rausreissen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jetzt kriege ich aber beim Aufruf
Code:
testarray[7] := FC_Fut_Checksum(testarray, 0, 6);

Den fehler:
Anhang anzeigen 50935

Das kann doch nicht so schwer sein. Irgendwas grundlegendes hab ich noch nicht verstanden.
Ist das nicht so das er bei pointer to array das array überlagert?
Was auch logisch ist und die Fehlermeldung sagt Dir eigentlich schon was nicht passt. Deine Funktion erwartet einen Pointer auf ein Array als ersten Parameter, aber Du übergibst ein Array. Versuch es mal mit
Code:
testarray[7] := FC_Fut_Checksum(ADR(testarray), 0, 6);
dann übergibst Du Deiner Funktion einen Pointer auf das Array testarray und der Compiler müsste glücklich sein. In wie weit Deine Funktion funktionieren müsste habe ich mir aber nicht angesehen, sorry.
Nachtrag: Jetzt habe ich mir Deine Funktion doch kurz angesehen, Du musst beim Arrayzugriff noch den Dereferenzierer (^) angeben.
 
Nachtrag: Jetzt habe ich mir Deine Funktion doch kurz angesehen, Du musst beim Arrayzugriff noch den Dereferenzierer (^) angeben.

Ah tiptop jetzt hab ichs. geschafft. Das mit dem Dereferenzieren hab ich grad noch rausgefunden. Aber die Beschreibung in der hilfe ist schon etwas mager ^^ ;)

Code:
FUNCTION FC_Fut_Checksum : BYTEVAR_INPUT
      Proof : POINTER TO ARRAY[0..32000] OF BYTE;
      start : INT;   (* erstes Element der Prüfung *)
      end : INT;   (* letztes Element der Prüfung *)
END_VAR
VAR
      index : INT;
	PT1: BOOL;
END_VAR




(* @END_DECLARATION := '0' *)
FC_Fut_Checksum := 0;
	FOR index := start TO end DO
	    FC_Fut_Checksum := FC_Fut_Checksum - Proof^[index];
	END_FOR;


END_FUNCTION

Damit hab ich glaub ich die grösste Hürde geschafft. Aber das mit den Pointern verhält sich schon ganz anders als in der Siemenswelt.
 
Ja, das ist komplett anders. Ist halt so, wie in der restlichen Programmiersprachen Welt. Wer damit programmieren gelernt hat der wundert sich um das SIEMENS System.
Ich glaube ich habe es immer noch nicht verstanden. 😔 Gut, dass es jetzt mit TIA ausstirbt.
 
Zurück
Oben