# Große Datenmengen in einem großen Array



## bastian c (20 Dezember 2017)

Hallo Zusammen,

ich versuche gerade den Umstieg von v2.3 auf v3.5 notgedrungener Weise, da die 750-880 für meine benötigten Datenmengen zu klein wird.

Für ein Tanksmesssystem mit 32 Tanks, bei denen die geometrie nicht durch einfache Funktionen abbildbar ist, benötige ich am liebstens ein Array [1..9] of Array [1..32] of Array [1..109,1..2] OF REAL als Konstante definiert (Ein Array [1..9,1..32,1..109,1..2] of REAL geht grundsätzlich auch, ich empfinde es aber als Übersichtlicher in der anderen Schreibweise).
Zur Erläuterung, ich habe 32 Tanks die jeweils, für eine halbwegs genaue Volumenanzeige, 109 Stützstellen benötigen, für jeden Tank gibt es nochmal 9 Unterschiedliche Tabellen, da diese Tanks auf einem Schiff sind und durch unterschiedliche Trimstufen jeweils andere Verhältnisse von Höhe zu Volumen besitzen.

Das Array kann ich auf der 880er zwar noch abbilden (gerade so) aber wenn ich das Array mit seinen Werten initialisiere platzt mir der Quellcode bzw. das übersetzte Programm aus allen Nähten.

Daher habe ich mich nun für einen PFC100 750-8100 entschieden, da hier deutlich mehr Programmspeicher zur Verfügung stehen.

Beim Umstieg auf Codesys v3.5 habe ich nun aber ein paar Probleme bekommen.

Zum einen bekomme ich mehrere Fehlermeldungen wenn ich unter Var Global Constant folgenden Code habe.

```
ps_sensor_tank_curve: ARRAY [1..9] OF ARRAY [1..32] OF ARRAY [1..109,1..2] OF REAL:=[0,0,0.1,1.03,0.2,2.505,0.3,4.228,0.4,6.159,0.5,8.258,0.6,10.489,0.7,12.726,0.8,14.98,0.9,17.276,1,19.626,1.1,22.024,1.2,24.485,1.3,26.868,1.4,29.164,1.5,31.549,1.6,34.026,1.7,36.586,1.8,39.1,1.9,41.582,2,44.099,2.1,46.651,2.2,49.238,( hier folgen noch weiter 30.000 Werte)];
```
Fehler 1 ist "Zu viele Initialisierer für Datenfeld" obwohl die Anzahl der Werte in jedem Fall kleiner ist als die Gesamtgröße des Arrays, hier scheint V3.5 im Vergleich zur 2.3 die Anzahl der Initialisierungswerte mit der Anzahl der Felder nur des letzten Arrays zu vergleichen. Erstelle ich ein Array[1..9,1..32,1..109,1..2]  geht es.

Fehler 2 Eine "0" wird als Bit erkannt und nicht als Real, daher Fehler kann Bit nicht in Real konvertieren. Wenn man das Array als Array [1..9,1..32,1..109,1..2] abbildet kommt diese Fehlermeldung nicht.

Das dritte ist eher ein Darstellungsproblem anstatt eines Fehlers. Möchte ich mir nun das Array in der Steuerung im Online-Modus anschauen endet die Liste bei [1,5,64,2]. Kann e!Cockpit nicht mehr als 1000 Zellen anzeigen? Hier zeigt sich gerade der Vorteil der verschachtelten Arrays, ich muss sie zwar alle einzeln Aufklappen, habe aber immer nur maximal 218 Zeilen.

Der oben dargestellte Code ging auf der 880 problemlos durch, dort hatte ich bisher nur diese erste Dimension des Arrays mit 1..9 nicht. Da diese nun aber benötigt wird reicht der Platz auf der 880er nicht mehr.

Viele Grüße

Bastian


----------



## oliver.tonn (20 Dezember 2017)

Ich kann leider nur zur 0 etwas sagen. Damit diese als REAL erkannt wird musst Du 0.0 schreiben.

Von irgendwas mit Internetzugang gesendet


----------



## Mavorkit (20 Dezember 2017)

Hi Bastian,

Ich hab Mal eine Frage zu deinem Problem. Hilft es dir nicht hier mit der Wago SD-Karte zu arbeiten?

Du hast am Ende der Deklaration nochmal 1..2 für was benötigst du das? Und hast du schon Mal darüber nachgedacht mit Array Strukturen zu arbeiten oder ist dafür deine Zuordnung nicht passend?

Gruß

Mavorkit

Gesendet von meinem SM-G389F mit Tapatalk


----------



## PN/DP (20 Dezember 2017)

Hallo Bastian,

ich kann mir kaum vorstellen, daß man für eine Tank-Volumenberechnung wirklich sooo viele Datenpunkte braucht. Wie wurden denn die 30.000 Werte erfasst (ca. 1000 Datenpunkte je Tank)? Ist die Volumenberechnung für eine wissenschaftliche Doktorarbeit oder braucht man das wirklich so genau? Wie genau muß das "halbwegs genau" sein? Wie wird die Füllhöhe gemessen?

Braucht die Tankgeometrie tatsächlich 109 Stützstellen? Oder kann die Geometrie nicht auch mit ein paar Formeln beschrieben werden? (Stichwort: Wertepaare in Excel eingeben und Näherungsformel ermitteln lassen)
Sind das 32 total verschieden geformte Tanks oder gibt es da auch Tanks mit gleicher Geometrie? (z.B. Backbord = Steuerbord?)
Du willst 9 Trimmstufen des Schiffes berücksichtigen - wie wird der Seegang eingerechnet/rausgerechnet?
Müssen da wirklich alle 32 Tanks im selben Array sein und könnten es auch 32 Arrays sein?

Harald


----------



## bastian c (21 Dezember 2017)

Nabend, erstmal danke für die schnellen Antworten. 



oliver.tonn schrieb:


> Ich kann leider nur zur 0 etwas sagen. Damit diese als REAL erkannt wird musst Du 0.0 schreiben.



Wenn ich das Array nicht verschachtel schluckt er die 0 auch einwandfrei.



Mavorkit schrieb:


> Hi Bastian,
> 
> Ich hab Mal eine Frage zu deinem Problem. Hilft es dir nicht hier mit der Wago SD-Karte zu arbeiten?
> 
> Du hast am Ende der Deklaration nochmal 1..2 für was benötigst du das? Und hast du schon Mal darüber nachgedacht mit Array Strukturen zu arbeiten oder ist dafür deine Zuordnung nicht passend?


Bezüglich SD Karte, muss gestehen habe ich nicht getestet, wäre prinzipiell eine Idee Wert das mal zu machen, jedoch ist ja der Programspeicher laut Handbuch ca. 1mb und ich weiß nicht ob es was ändert, wenn man die SD Karte als Hauptlaufwerk nimmt.
Grundsätzlich könnte man sicherlich die Daten bei jedem Neustart der PLC aus einer csv einlesen aber das habe ich bisher grundsätzlich nicht stabil hinbekommen.

Zu den Array Dimensionen:
Array [1..9]             [1..32]         [1..109]                  [1..2]
9 Trimstufen           32 Tanks      109 Stützstellen     Pro Stützstelle ein Wertepaar von Höhe zu Volumen (Die Höhen sind nicht immer identisch zwischen den Tanks, sonst könnte man hier auch die hälfte weglassen)




PN/DP schrieb:


> Hallo Bastian,
> 
> ich kann mir kaum vorstellen, daß man für eine Tank-Volumenberechnung wirklich sooo viele Datenpunkte braucht. Wie wurden denn die 30.000 Werte erfasst (ca. 1000 Datenpunkte je Tank)?
> Ist die Volumenberechnung für eine wissenschaftliche Doktorarbeit oder braucht man das wirklich so genau? Wie genau muß das "halbwegs genau" sein? Wie wird die Füllhöhe gemessen?
> ...



Also die Genauigkeit ist nen Thema für sich und da kann man sich am Ende in jedem Fall drüber Streiten.

Ich hole mal ein bisschen weiter aus.

Bisher haben wir schon ein paar Schiffe mit einem Tankmesssystem ausgerüstet welches eher ein Beiprodukt zu unseren Ventilsteuerungen ist. Wir bekamen bisher von den Werften immer eine Tanktabelle pro Tank, die auf Trim=0° basiert. Diese Tanks haben ansich häufig, wenn es Ballasttanks an den Seiten der Schiffe sind, eine Geometrie wie eine halbe Parabel, dies gilt aber nur wenn der Tank im mittleren Teil des Schiffes liegt, ist er Fore oder Aft gilt das auch nicht mehr. Innerhalb Tanks sind auch oftmals große Rohrleitungen verlegt die ebenfalls das Volumen sehr ungleichmäßig Steigen lassen. Als ich die Aufgabe bekam das erste mal ein Tankmesssystem zu erstellen wollte ich auch gerne diese riesen Tabellen als Funktionen hinterlegen. Ich habe damals zunächst mit Excel und später auch mal mit Matlab mir Näherungsfunktionen der Graphen errechnen lassen und geschaut wie genau man diese Abbilden kann. Selbst mit Polynomfunktionen höherer, ich glaube ich bin bis 5. oder 6. Ordnung gegangen, waren gerade an den Eckpunkten Abweichungen von 10-15% eher die Regel als die Ausnahme und selbst im mittleren Bereich lag der Fehler oft noch bei 3-5%. Jetzt kann man natürlich sagen, dass man die Graphen in mehrere Abschnitte unterteil und dann für die einzelnen Abschnitte Funktionen errechnet und so das ganze dann macht, jedoch sollte man diese Arbeit nicht unterschätzen, denn 32 Tanks und insgesamt 9 Trimstufen und selbst wenn es nur 3 Abschnitte pro Tank sind damit der Fehler in einem erträglichen Rahmen bleib macht man das ganze 870 mal. Daher habe ich gesagt ich übernehme die Tanktabellen so wie wir sie bekommen.

Bei den letzten beiden Projekten wo ein Tankmesssystem gefordert ist haben wir das ebenfalls so wieder gehandhabt. Die Werft errechnet mit einer Software und den 3D-Datensätzen der Tankgeometrien diese Tanktabellen und kann dann die Schrittweite der Stützstellen anpassen. Zunächst hatten wir eine Schrittweite von 5cm was bei zum Teil 11m Tankhöhe dann rund 210 Punkte macht. Für eine Trimstufe ist das auch noch kein Problem auf der 750-880. Nun ging das erste Schiff in Betrieb und bei einer Montage auf dem Schiff kam die Frage von der Crew wie genau das System ist, denn es sind Zementfrachter und das Wiegesystem landseitig ist eher grob ungenau, so dass die Crew am liebsten einen Tiefgang über die Ballasttanks einstellt der vor und nach dem Laden identisch ist um so möglichst genau ermitteln zu können wie viel Ladung sie aufgenommen haben. Da sie immer mit einem negativen Trim fahren, passen nun die Tanktabellen nicht mehr zum realem Zustand und das Ergebnis ist verfälscht. Daher wollen wir nun die unterschiedlichen Tabellen für unterschiedliche Trimstufen hinzufügen.

Zu der Frage ob man wirklich so viele Stützstellen benötigt. Ich konnte nun Tanktabellen mit 5cm und 10cm Schrittweite vergleichen und habe mir dann den fehlenden 5cm Schritt linear interpoliert. Der Fehler lag im überwiegenden Teil unter 1% was dicke ausreichend ist. Gerade in den Randbereichen ging er jedoch auch schon wieder auf 3-5% hoch was ich gerade noch so aktzeptabel finde und daher wurde der Entschluss gefasst 10cm Schrittweiten zu benutzen.

In meinen Augen muss das System auch immer nur dann sehr genau sein wenn ich Ladevorgänge habe somit kann der Seegang vernachlässigt werden.

Grundsätzlich können bei den Ballast Tanks die Steuer- und Backbordtanks schon gleich sein, verlassen würde ich mich darauf allerdings nicht, denn wie schon geschrieben können auf der einen Seite mal große Rohre verlegt worden sein die es auf der anderen Seite nicht oder an unterschiedlicher Position gibt.

Grundsätzlich könnten es auch 32 Arrays sein, jedoch sind dann meine "universalen" Funktionsblöcke wieder so abzuändern, dass ich bei jedem Funktionsaufruf das Array mit übergeben muss. Zur Zeit starte ich eine For-Schleife, bei der die Zählvariable den passenden Array Index angibt.

Die grundlegende Frage die habe ist eigentlich eher, wie muss ich bei verschachtelten Arrays die Initialisierung vornehmen in V3.5? In V2.3 ging das in dem ich alle Werte hintereinander wegschreibe. Warum geht das so nicht in V3.5? Denn wären die Arrays verschachtelt hätte ich das 1000 Zeilen Problem im Online Modus nicht.

Nochmal ein paar Eckdaten zu den Tanks:

tank   height
    [cm]tank volume
    [m³]785,0267,642785,0237,708857,5210,775857,5210,675233,1180,629233,1180,5841072,0281,8821072,0281,882


Gemessen wird mit Drucksensoren die entweder seitlich am Tank angebaut sind oder mit Tauchsonden. Diese Sensoren haben eine Genauigkeit von <0,5% FSO. 
Ich will die ganzen Fehler die sich dabei noch durch ungenauigkeiten die beim Bau oder bei nicht korrekt positionierte Sensoren einschleichen können nicht aussen vor lassen, bin jedoch der Meinung, dass man die vorliegenden Daten dennoch so genau, wie sinnvoll möglich, als Grundlage benutzen sollte.

Ich habe mal zum Anschauen die Rohdaten von zwei Tanks angehängt.

Gruß Bastian


----------



## PN/DP (21 Dezember 2017)

Hallo Bastian,

Danke für Deine ausführlichen Erklärungen - Du hast Dir also schon alle möglichen Gedanken gemacht.
Zu Deinem Array-Problem kann ich leider nichts helfen.

Harald


----------



## Tobsucht (22 Dezember 2017)

Hallo Bastian,

wenn man die Eingabehilfe bemüht bekommt man schnell raus wie die Werte übergeben werden müssen.

Für eine bessere Übersicht habe ich die Arraygrenzen verkleinert:




Grüße


----------



## Heinileini (22 Dezember 2017)

Hallo Bastian,



bastian c schrieb:


> ... ein Array [1..9] of Array [1..32] of Array [1..109*,1,2*] OF REAL ...     _==> hier *1 Dimension mehr *als im folgenden!!!? und anscheinend ziemlich nutzlos?_
> ... Ein Array [1..9,1..32,1..109,*1..2*] of REAL geht grundsätzlich auch, ...



Gruss, Heinileini


----------



## bastian c (23 Dezember 2017)

Hallo,



Tobsucht schrieb:


> Hallo Bastian,
> 
> wenn man die Eingabehilfe bemüht bekommt man schnell raus wie die Werte übergeben werden müssen.
> 
> ...



Da hätte ich auch selber drauf kommen könne, Danke! Die ganzen neuen Helferlein verwirren mich zur zeit noch eher 

@ Heinilein
Ja da oben ist nen Tippfehler drinne, in allen anderen Darstellen und auch den erläuterungen habe ich aber deutlich gemacht, dass das letzte Array [1..109,1..2] sein solte.
Habs mal korrigiert, danke.

Vielen Dank für die Hilfe, werde das bei nächster gelegenheit mal testen.

Gruß

Bastian


----------



## HausSPSler (26 Dezember 2017)

Hi,
Cooles Projekt ;-)
So generell würde ich einfach das V2.3 Projekt in CODESYS V3 importieren (einfach mit CODESYS V3.5 öffnen - das .pro also V2.3 Projekt)
dabei wird das Projekt (also der CODE) konvertiert nach V3, dann gibt’s diese Probleme nicht.
Eines muss man beachten, diesen V2.3 nach V3 Importfilter gibt es nur in der CODESYS V3 32Bit Version.
Grüße


----------

