# CodeSys 2.3 und Array



## S7_Mich (1 November 2018)

Hallo Leute,

nach langem brauche ich wieder mal Hilfe von euch. Ich habe hier einen Controller 750-849, der mir über den Modbus Konfigurator eine Verbindung zum Buskoppler 750-352 herstellt. 

Jetzt muss ich die eingelesenen Eingänge vom 750-332 über UDP versenden. Der UDP Versand der Eingangssignale des 849 funktioniert schon. 

Der Modbus Konfigurator erstellt ja selbständig einen Code, der mir die Eingänge des 352 Buskopplers einliest. Es stehen mir dann die Variablennamen xVar_0_0 bis xVar_8_7 zur Verfügung.

Jetzt möchte ich mit einer Schleife durch diese Variablen durchlaufen, und schauen obs sich ein Signal geändert hat, wenn ja schicke ich dieses dann per UDP weg.

Aber wie kann diese Variablen über eine Schleife ansprechen. Ich könnte die Variablennamen schon noch ändern, damit diese dann z. B. heißen xVar_0 bix xVar_72.

Aber schreibe ich dann in der For Schleife den Zugriff auf xVar__

Hat jemand von euch einen Tipp?

Gruß
Michael_


----------



## KLM (1 November 2018)

Moin,
am einfachsten scheint mir, nicht mit einzelnen Variablen für jeden Kanal am Koppler zu arbeiten. Du kannst im MBM-Konfigurator auch generische Variablen erstellen. Dort legst Du eine einzige Variable für alle im Prozessabbild des Kopplers zusammenhängenden Kanäle an. Die Adresse ist die, des ersten Kanals - zeigt Dir zur Not auch der Konfigurator bei den bisher verwendeten Variablen an. Datentyp lässt Du auf BOOL und die Anzahl erhöhst Du von 1 auf 64 (8 Klemmen mit je 8 digitalen Kanälen). Als erzeugten Code bekommst Du dann ein ARRAY[1..64] OF BOOL, dass Du dann in einer FOR-Schleife durchlaufen kannst.


----------



## KLM (1 November 2018)

Alternativ könntest Du auch mit Pointer-Arithmetik arbeiten. Also Pointer auf die erste BOOL-Variable und in jedem Schleifendurchlauf den Pointer um 1 erhöhen. Achtung, der Pointer zeigt immer auf ein ganzes Byte und ein um eins erhöhter Pointer somit auf die immer nächsten 8 BOOL. Hat aber gleichzeitig den Scharm, dass Du gleich 8 digitale Kanäle in einem Schleifendurchlauf als BYTE vergleichen kannst.


----------



## Heinileini (1 November 2018)

Warum jetzt 8 Byte? In #1 waren wir noch bei 9 Byte alias 72 Bit (bzw. 73 Bit?).

PS:
Mit welchen Informationen muss denn der UDP-Versand gefüttert werden?
Byte-Nr, Bit-Nr und Zustand des Bits?


----------



## KLM (1 November 2018)

Ich verstehe die Frage nicht richtig, aber bei 8 digitalen Klemmen mit 8 Kanälen werden 8*8=64 Bit oder 8 Byte benötigt. 8 Klemmen, weil das indirekt aus den Variablennamen hervorgeht.



> Es stehen mir dann die Variablennamen xVar_0_0 bis xVar_8_7 zur Verfügung.


----------



## S7_Mich (1 November 2018)

Ihr habt recht, ich hab mich um ein Byte vertan. Es sind 8 Byte. 

Ich habe wie KLM geschrieben hat, umgesetzt. Somit steht mir jetzt ein Array zur Verfügung, das ich über eine For Schleife durchlaufen kann. Vielen Dank für die schnelle Hilfe.

Jetzt gehts weiter mit dem UDP Versand.


----------



## S7_Mich (1 November 2018)

So jetzt läuft der UDP Versand, allerdings gefällt mir das jetzt noch nicht wirklich. Ich habe jetzt zwei Arrays, einmal mit dem Inhalt der Bits der Eingänge des Controllers und das zweite Array mit den Bits der Eingänge des Buskopplers. Jetzt brauche ich zwei Schleifen, einmal für das eine Array und einmal für das zweite Array. 

Schöner wäre es doch jetzt, man kopiert das Array[0..7] of bool und das Array[0..63] of Bool in ein neues Array, das dann ein Array[0..71] entsteht. Dann könnte ich mit nur einer Schleife durchlaufen.

Aber gibts da einen Kopierbefehl für Arrays?


----------



## Heinileini (1 November 2018)

KLM schrieb:


> Ich verstehe die Frage nicht richtig, aber bei 8 digitalen Klemmen mit 8 Kanälen werden 8*8=64 Bit oder 8 Byte benötigt. 8 Klemmen, weil das *indirekt* aus den Variablennamen hervorgeht.


Viel zu indirekt für meinen Geschmack:
xVar_0_0 : 1. Byte
xVar_1_0 : 2. Byte
xVar_2_0 : 3. Byte
xVar_3_0 : 4. Byte
xVar_4_0 : 5. Byte
xVar_5_0 : 6. Byte
xVar_6_0 : 7. Byte
xVar_7_0 : 8. Byte
xVar_8_0 : 9. Byte
Oder sind damit 8 Byte zu je 9 Bit gemeint?
Das Aufdrieseln von xVar_0 bis xVar_72 mochte ich mir/uns hier ersparen.


----------



## KLM (1 November 2018)

Ob Du zwei Arrays durchläufst oder ein einziges großes, ist aus Sicht der Performance fast unbedeutend im Unterschied. Kopierst Du die beiden aber zusammen brauchst Du dazu den doppelten Speicher und zusätzliche Rechenleistung. Wenn es aber für die weitere Verarbeitung z.B. bei der Übergabe an den UDP-FB optimal wäre, kannst Du eine MemCpy (Memory Copy) Funktion verwenden. In der WagoLibEthernet_01.lib ist z.B. eine.

Das es sich um BOOLs, und nicht um BYTEs handelt, erkennt man am Präfix "x" der Variable. Da die vom Konfigurator generiert werden, wird dort auch der WAGO Standard bei den Präfixen verwendet.
x..BOOL
b..BYTE
w..WORD
etc.


----------



## Heinileini (1 November 2018)

Meine Wago-Kenntnisse beschränken sich leider auf die Benutzung eines Wago-Zollstocks mit WinkelSchätzExtension.
Darum verwirren mich die 2 Arrays mit unterschiedlichen Anzahlen von Elementen (64 vs. 8 ) laut . . .


S7_Mich schrieb:


> Ich habe jetzt zwei Arrays, einmal mit dem Inhalt der Bits der Eingänge des Controllers und das zweite Array mit den Bits der Eingänge des Buskopplers.
> Jetzt brauche ich zwei Schleifen, einmal für das eine Array und einmal für das zweite Array.
> Schöner wäre es doch jetzt, man kopiert das Array[0..7] of bool und das Array[0..63] of Bool in ein neues Array, das dann ein Array[0..71] entsteht.





S7_Mich schrieb:


> Jetzt möchte ich mit einer Schleife durch diese Variablen durchlaufen, und schauen ob sich ein Signal geändert hat, . . .


"Schauen, ob sich ein Signal geändert hat" bedeutet aber, vergleichen mit einem Array von FlankenMerkern (drittes Array!)!
Brauchen wir die nur für die Eingänge des Controllers und/oder auch noch für die Eingänge des Buskopplers (viertes Array?)?
Wäre denn folgendes (sinngemäss) eine Anregung für Dich?

```
// mit arrayA[0 to 63], arrayB[0 to 7] und arrayC[0 to 71] und nur 1 Schleife:
for Idx := 0 to 71
    if Idx < 64 then
        arrayC(Idx) := arrayA(Idx) 
    Else
        arrayC(Idx) := arrayB(Idx - 64) 
    EndIf
Next Idx
```


----------



## KLM (1 November 2018)

Richtig, wenn ein alter Zustand mit dem Aktuellen verglichen werden soll, muss der alte Zustand separat gespeichert sein.
Wie gesagt, ich würde es bei zwei Arrays (inkl. der Kopie für den alten Zustand dann 4 Arrays) belassen und in je zwei separaten FOR-Schleife prüfen. D.h. in der FOR-Schleife abfragen, ob zwischen Array A und Array A alt eine Differenz auftaucht. Nur wenn eine Differenz besteht würde ich den jeweiligen Array-Index von aktuell auf alt kopieren und die Aktion für die UDP-Übertragung starten.


----------

