Step 7 Auswertung Array of Char

Zuviel Werbung?
-> Hier kostenlos registrieren
Damit habe ich wieder ein

FOR i:=280 TO 4000 DO

END_FOR;

Das ist dann wieder wie bei 200 die Handbremse ziehen. Vor allem da ich den Datenmüll zwischen den Variablen (Teilweise 300 Zeichen) mit durchleuchte, obwohl ich sie einfach ignorieren könnte).

Grüße

Marcel

EDIT: Hat meine Tippserei doch tatsächlich eine 0 gefressen
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein, das verstehst du Falsch!

ich will mir ja helfen lassen, aber den Vorschlag mit "alles durchsuchen" war mein erster Schritt, und führt nur zu einem:

CPU Stop wegen Zykluszeitüberschreitung.

Die Vorschläge sind ja alles soweit ok, und bei kleineren Bereichen sicher sinnvoll (wenn es nur 200 Zeichen wären, würde ich mir jetzt keinen Kopf machen)... aber halt hier nicht Zielführend.

Grüße

Marcel
 
Vor allem da ich den Datenmüll zwischen den Variablen (Teilweise 30 Zeichen) mit durchleuchte, obwohl ich sie einfach ignorieren könnte).
Deine SPS ist aber kein Mensch der aufgrund Erfahrung den Datenmüll sofort sieht - bzw. Du als Mensch machst es doch genauso: Du überfliegst den Datenmülltext Zeichen für Zeichen bis Du etwas bekanntes (vereinbartes) findest.

Wenn Dir der enthaltene Datenmüll nicht gefällt, dann vereinbare mit dem Datensender ein anderes Datentelegramm mit festem Aufbau und fester Anzahl an Dezimalziffern.

Harald
 
Nochmal zusammengefasst bzw. nochmal nachgeguckt:

Ich Empfange ca. 4000 CHAR. Davon verwerten tue ich ca. 160. Der Rest ist "Müll" der mich nicht interessiert.
Die Reihenfolge ist immer:

Header, Variable1, Müll, Variable2, Müll, Variable3, Müll, VariableN, ENDE;

Ich weis wo ungefähr meine Variablen liegen, und dort suche ich nach ihnen. Somit muss ich nur 160 Schleifendurchläufe machen, statt 4000! Deshalb muss ich mir den Müll gar nicht erst angucken! (Ich habe als Mensch für die Maschine bereits vorselektiert).

Somit behaupte ich, dass an diesem Punkt vermutlich keine oder nur eine geringe Optimierung möglich ist, und meiner Meinung nach das durchsuchen der gesamten Daten nicht das Ziel ist.

Die anderen Vorschläge die hier genannt wurden (z.B. Die verschachtelten IF-Abfragen sowie das Rechnen statt String-Wandeln) werde ich umsetzen, denn die sind definitiv gut!

Grüße

Marcel

P.S: Nicht falsch verstehen, ich habe nix gegen Vorschläge und Ideen, aber die habe ich schon durch, und glaubt mir wenn ich sage, dass ich noch NIE so oft nen STOP->RUN Übergang hatte wie bei dieser CPU.

P.P.S: Mein Partner ist eine Serienmaschine -> Friss oder Stirb!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ähm Marcel, ist es bei deine Anwendung wirklich erforderlich das du deine Daten
Zyklisch verarbeitest. Oder könntest du es nicht auch einfach auf mehrere SPS Zyklen
verteilen?

Anders gefragt, brauchst du wirklich, sagen wir mal alle 1-5 sec. die Daten, hat
deine Anwendung solche Taktzyklen?
 
Hättest du den Beitrag komplett gelesen wüsstest du, dass ich mit dem Gedanken spiele die Auswertung auf mehrere Zyklen zu legen!

Taktzeit: Einige Signale sind zyklisch nicht wichtig. Auf 3-4 kommt es aber an. Die hätte ich gern so schnell wie möglich mitbekommen.

Grüße

Marcel
 
Marcel, eins schnapp ich nicht: wenn ich mal großzügig 30 Byte pro Variable für "Name=123.456," annehme und das mal 20 Variablen, dann komme ich auf 600 Byte. Die ersten 280 Byte des Telegramms werden übersprungen. Bleiben trotzdem noch über 3000 Byte Müll - wo hast Du die vor uns versteckt? Bei Deinen Beispielen sind immer nur ein paar bis vielleicht 10 Bytes Müll zwischen den Variablen - dann sollte doch nach Ansehen von 800 aufeinanderfolgenden Bytes alles erledigt sein?

Auch daß Du tatsächlich nur 160 Byte verwerten willst, tsts - das können ja fast nur netto die Ziffern der Werte ohne Variablenname sein, die Du aber erstmal finden mußt bei zugegeben größer werdendem Suchfenster. Alleine die Suchfenster enthalten ja zusammen schon vielleicht 400 Bytes. Die 'zig Byte der Variablennamen willst Du wohl gar nicht mehr lesen? (ist ja eigentlich auch nicht nötig, man muß ja nur das '=' finden) Ich kann mir Dein Datentelegramm nicht so richtig vorstellen. Vor allem "sehe" ich keine Such-Abkürzungen. Wie sieht denn der "Müll" zwischen den Werten aus?

Sind vielleicht die Anzahl Bytes nach der letzten Dezimalziffer eines Wertes bis zum Beginn des nächsten Wertes konstant (die Länge des Müll-/Fülltextes)? Dann könnte man nach dem Einlesen eines Wertes die Startposition des nächsten Wertes berechnen statt suchen. Gibt es alternativ garantierte Mindestlängen des Fülltextes zum nächsten Wert? Dann würden Deine Suchfenster vielleicht nicht größer werden und Du könntest immer relativ die selbe Anzahl Zeichen überspringen.

Wie es momentan für mich aussieht, wirst Du wohl doch nicht ganz ohne Suchen auskommen. Du solltest aber alles versuchen um jeweils möglichst nahe an den Beginn des nächsten Wertes zu springen. Ab da halt immer nur 1 Zeichen prüfen um den Vergleich bei nicht-Übereinstimmung vorzeitig abzubrechen. Und ab der ersten Ziffer dann die Ziffern nicht zu einem String zusammfügen sondern auf Ziffer prüfen und sofort konvertieren in einem fortlaufenden Algorithmus.

Das reine Konvertieren von 20 Werten kann nicht lange dauern. Das Finden der Werte muß natürlich optimiert werden. Ich kann mir irgendwie nicht vorstellen, daß das indirekt adressierte Ansehen und Auswerten von 600 Bytes auf einer aktuellen IM151-8F PN/DP 21ms verschlingen muß. Ich würde mir auch mal das Kompilat des SCL-Compilers ansehen, ob ich ihm etwas unter die Arme greifen muß um effizienten Code zu erzeugen. Sehr wahrscheinlich würde ich den Code bei Geschwindigkeitsproblemen aber in AWL schreiben. Da es ein CHAR-Array ist, wird die Adress-Rechnerei auch nicht besonders undurchsichtig aussehen. Außerdem kann ich in AWL notfalls auch mehrere Zeichen gleichzeitig anfassen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das reine Konvertieren von 20 Werten kann nicht lange dauern.

Sicher?
Ich weiß ja nicht was der Concat da macht aber 20*6 / 20*12 sind auch 120/240 Aufrufe.

Zu den verschachtelten IFs:
Man würde erwarten, dass nach der ersten 0 die restlichen Ausdrücke nicht mehr ausgewertet werden.
Oder ist das zuviel verlangt?
 
Das reine Konvertieren von 20 Werten kann nicht lange dauern.
Sicher?
Ich weiß ja nicht was der Concat da macht aber 20*6 / 20*12 sind auch 120/240 Aufrufe.
CONCAT darf man natürlich nicht benutzen wenn es schnell sein soll. Ich meinte mit eigenem direkten Konvertieren von CHAR zu DINT/REAL ohne STRING-Umweg.

Zu den verschachtelten IFs:
Man würde erwarten, dass nach der ersten 0 die restlichen Ausdrücke nicht mehr ausgewertet werden.
Oder ist das zuviel verlangt?
Ein C-Compiler würde das optimieren, doch der Siemens-SCL-Compiler? Das müßte man eben ausprobieren.

Harald
 
Ich danke euch für die Lösungsansätze!

Die nächsten Tage (Wohl nicht vor Ende dieser Woche) werde ich mich mal wieder an die Problematik rantasten, und euch dann berichten wie es aussieht.

Ich habe gerade gesehen, dass ich mit dem Datenmüll Mist gebaut habe! Ich schrieb etwas von 30 Byte, es handelt sich aber tatsächlich um bis zu 300 Zeichen. Daher kommt bei mir die Sucherei zum Einsatz, weil es mehr Zeit kostet den Müll zu durchsuchen, also grob nach der Variable zu suchen. Wenn ich feststelle, dass der Müll bis auf 1-10 Zeichen immer gleich lang ist, kann ich natürlich das Suchfenster eingrenzen, das ist korrekt!

Grüße

Marcel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
mal einen ganz anderen weg ;;)
wo kommen die daten den überhaupt her? ist dies ein festes messgerät mit fest definiertem protokoll? oder ein pc und ein stück software schickt dir die daten? wenn es ein stück software ist kann man diese nicht ändern das es für dich leichter wird? habe öfters prüfstände die sind mit labview programmiert und die kommunikation legen wir genau fest habe dann quasi ein festes protokoll mit den echten werden ohne suchen ohne umwandeln...
 
Hallo,
@teufel, er schrob was von Serienmaschine und nogo, so wird er wohl mit dem Problem alleine sein. Als nichtSCLer kommt mir immer wieder der AWL Ansatz in den Sinn. Mit anderen Worten, ich würde den relevanten Teil des Codes tatsächlich mal auf seine Funktion hin untersuchen und mal testen ob und wieviel was mit AWL schneller ist.
Und noch mal so als Ansatz, welche Teile interessieren denn wirklich, wenn nur wenige Teile relevant sind, dann die unwichtigen in mehrere Zyklen, die wichtigen in einen, sofern das geht.....

Gruß
Mario
 
Nochwas,
ich habe mal ein wenig nach SFCs gestöbert, hier wird über den FC86 (TBL_Find) gesprochen und über andere Wege. Liegt das ganze überhaupt in einem DB?

Gruß
Mario
 
Zuviel Werbung?
-> Hier kostenlos registrieren
zu deinen Daten

Header, Variable1, Müll, Variable2, Müll, Variable3, Müll, VariableN, ENDE;

1. ist der Header immer Fix?
2. ist das Ende auch klar und Fix zu erkennen
3. deine Variablen haben immer den VariableX=XYZ(.XYZ) Aufbau?
4. Wie genau erkennst du den Müll? Was bedeutet Müll, ungewollte Information? Wie ist dieser Aufgebaut (auch var=wert?) Könnte wichtig sein um die Abtrennung der Daten von Gut/Müll zu verstehen

kannst du bitte einfach mal ganz klar und deutlich die vollständige Syntax deiner Daten beschreiben auch den "Müll"-Anteil - Ist das so schwer?
und ohne logische Trenner wie "," usw. die in den echten Daten nicht vorkommen

Oder am besten: Du stellst hier einfach mal einen Teststream der Daten ein - dann kann man vielleicht auch mal 100% verstehen was du vorhast
z.B. echte Beispieldaten von dir oder ein Wireshark-Log

wobei ich Thomas v2.1 Post (http://www.sps-forum.de/simatic/63876-auswertung-array-char.html#post447338)
und PN/DP recht gebe - du braucht einen richtigen Parser - der ist einfach, sicher und da inkrementell arbeitend auch schneller

Deine ganzen Suche/Länge usw Ideen sind nett aber führen glaube ich nicht zu einem guten Ergebnis - einen richtigen Parser
zu vermeiden macht hier einfach keinen Sinn - nur wenn du nicht weisst wie du einen bauen sollst - oder die Syntax deiner Daten total unformalisiert ist :)
 
Zuletzt bearbeitet:
Hallo,

mariob: Ja liegen alles einem Array of Char in einem DB.

LowLevelMahn:

1. Ja, der Header hat immer 280 Zeichen
2. Von was? Vom Gesamtstring? Nein!
3. Nein, die ersten 10 Variablen sind anders aufgebaut, sind aber alle definiert lang (Daher dort keine Sucherei) und sie stehen direkt nach dem Header. Die Variablen wo ich suchen muss sind aber alle gleich aufgebaut VARIABLEX=123456.123456,
4. Dieser "Müll" sind infos für die Auswertung der Daten, darin steht z.B. sowas "NEXTVAR=VARIABLE1,LENGTH=26,STATUS=BLABLA,FORMAT=FLOAT,TEXT=ASCII etc pp" Das hilft mir z.B. bei einem C-Programm. Aber da dieser Müll immer durcheinander kommt, und die Infos von Variable zu Variable teilweise Unterscheidlich sind (z.B. Schließt ein bestimtes Format den Parameter TEXT komplett aus) will ich diesen "Müll" nicht verwenden, sondern suche lieber nach der Variable.

Mein Problem mit einem schönen Parser ist folgende: Meiner Meinung nach muss ich bei einer inkrementellen Suche durch meinen Empfangspuffer viel zu viele Müll-Infos auswerten bzw. zwangsweise betrachten. Ich tue ja mit meiner Schleife/Suche nix anderes, nur halt schonmal eingegrenzt. Vielleicht ist mein Verständnis von einem Parser auch nicht korrekt, ich werd mir das vielleicht nochmal etwas detailierter zu Gemüte führen.

Grüße

Marcel
 
mariob: Ja liegen alles einem Array of Char in einem DB.

d.h. du liesst erstmal die 4000 Bytes komplett ein - und die länge ist Fix, also hast du gar keine Ende-Kennung so wie
in den vorherigen Post wo du ..., ENDE; als Teil der Daten zeigst

2. Von was? Vom Gesamtstring? Nein!

falls es keine Ende-Kennung gibt - oder eine fixe Menge an Zeichen empfangen werden muss
stell ich mir einfach die Frage ob das nicht einfach inkrementel geht - also so wie du
die Happen per TPC/IP bekommst - aber das setzt einen Parser vorraus - der sich nicht daran stoert das nur Teildaten da sind :)


also ist auch der "Müll" klar mit "NAME=WERT," getrennt? gibts es die Kommas wirklich im Datenstrom und ist
immer klar das NAME=WERT keine Kommas enthalten darf - um nicht mehrdeutig zu sein?
Was darf alles in einem NAME enthalten sein, wird immer mit = zwischen NAME und WERT getrennt,
ist ein Komma immer das Ende eine Zuweisung - solche Fragen hast du bisher sehr unklar beantwortet - weil du dich nur
in deiner Optimierung ausdrückst

Meiner Meinung nach muss ich bei einer inkrementellen Suche durch meinen Empfangspuffer viel zu viele Müll-Infos auswerten bzw. zwangsweise betrachten

dein "Suchen" nimmt genau so viele Bytes in die Hand wie der Parser
wenn deine Syntax klar formalisiert ist schlägt der Parser jedes noch so strategische einstechen, suchen usw. - und ist dazu noch sicherer und schneller

Wie gesagt: Stell doch bitte mal richtige/vollstaendige Testdaten ein oder besser noch ein Wireshark-Log dann kann man das leben Objekt betrachten

Vielleicht ist mein Verständnis von einem Parser auch nicht korrekt, ich werd mir das vielleicht nochmal etwas detailierter zu Gemüte führen.

Wir reden hier nur von einer trivialen Statemachine die deine Name=Wert Paare trennt - aka trivial regex - aber solange du die Syntax deiner Daten nicht verrätst sondern
deine Daten nur mit Hilfe deiner Optimierungsgedanken erklärst ist es einfach nicht klar ob es viel einfacher gehen würde
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

ich hab heut 2h an der Anlage verbringen können, und einige der Dinge umgesetzt:

1. Ermittelt nach wie vielen Zyklen neue Daten kommen -> Antwort 10-14. Somit habe ich die Auswertung auf bisher 3 Zyklen verteilt (erstmal zum Testen) und es hat eine große Zykluszeitminderung ergeben.

2. Alle IF mit vielen AND durch Verschachtelte IF ersetzt -> Da ich meine gesuchte Folge bei diesem Test nach wenigen Zeichen finde, und dann die Schleife mit einem EXIT verlasse hat das nicht viel Zykluszeit eingebracht.

3. Habe ich das Schreiben der Sendedaten verbessert. Es hatte sich ein Fehler eingeschlichen, durch den statische Sendedaten zyklisch in den Sendepuffer geschrieben wurden. Diese werden jetzt einmalig beim Init (z.B. hochlauf der CPU) geschrieben.

Ich hatte vorher eine Durchschnittliche Zykluszeit von 21ms und Peeks bis auf 39ms (mit Sicherheit die Zyklen in denen die Daten kamen). Und bin jetzt bei 13ms und Peaks bei 19ms (ich kann die sicher noch abfedern wenn ich die Aufteilung der Auswertung auf noch mehr Zyklen verteile.

Mit diesem Ergebnis bin ich ERSTMAL! zufrieden, und widme mich diesem Projekt bis ich wieder zeit dafür bekomme.
Wenn dieser Zeitpunkt eintrifft kann ich auch die gewünschten Daten nachliefern. Leider war mir dies heute nicht möglich, da ich
mehr Zeit als gedacht für die Optimierungen brauchte, und dann zu einem Kunden gerufen wurde.

Fazit fürs nächste Mal:

Gleich Daten holen, dann optimieren!

Ich danke euch allen, und hoffe ihr seid mir nicht böse, weil ich das ganze jetzt aus Zeitgründen erstmal beim jetzigen Stand einfrieren muss. Es geht sicher weiter, und ich würde mich freuen wenn der ein oder andere von euch dann wieder mit an board wäre.

Bis dahin habe ich mich dann auch mal in die Fuktionsweise eines Parsers eingelesen, und kann den dann auch besser beurteilen!

Grüße

Marcel

P.S: Erstmal auf Eis legen heißt bei mir: Entweder es geht gleich Morgen wieder los, oder ich sehe die Anlage die nächsten 3-20 Wochen nicht mehr aus der Nähe... das liegt aber leider nicht an mir... Ich könnte mich ziemlich lang damit beschäftigen die gesamte Anlage zu optimieren.
 
Hallo Matze,

ich habe deine Problematik schon gestern aufmerksam verfolgt und habe mir auch Gedanken zur Lösung gemacht. Entsprechend deiner Erläuterungen denke ich wie die meisten hier. Vielleicht kannst du uns noch kurz ein paar weitere Angaben machen. Du verwendest eine IM151-8F PN/DP. Ich habe die normale (nicht -F) eigentlich als recht leistungsfähig in Erinnerung.

Ich stelle mir folgende Fragen, bzw. stelle fest:

  1. Werkelt im Programm sonst noch was Umfangreiches, oder kommst du tatsächlich "nur" mit dem Auswerten des CHAR-ARRAYs auf die 21ms?
  2. Wie lange dauert eigentlich die Übertragung der 4000 Byte?
  3. Wenn du aus 4000 Byte ca. 20 Variablen fischen mußt, dann wären das im Schnitt max. 200 Byte pro Variable.
  4. Wenn du nun nur EINE einzige Variable im Zyklus suchst und ohne SFCs wandelst, kommst du auf eine Zykluszeit von angenommen <5ms (wzbw).
  5. Bei 20 Variablen würde jede einzelne nach ca. 100ms aktualisiert sein (Zykluszeit 5ms). Könntest du damit leben?
  6. Ein Testmuster deines ARRAYs wäre äußerst hilfreich - aber was nich iss, iss nich
  7. Beinhaltet der "Müll" auch '=' oder ','?


Gruß, Onkel

..1. Ermittelt nach wie vielen Zyklen neue Daten kommen -> Antwort 10-14...
Upps, bei 21ms Zykluszeit?
 
Zuletzt bearbeitet:
Hallo Onkel,

1. Außer dem F-Programm ist nix Weltbewegendes drauf (Das unterbricht den Zyklus dank OB35 Aufruf, daher erwähne ich es)
Ich müsste den Baustein nochmal runterwerfen und gucken was ich dann für eine Zykluszeit habe, ich schätze so 3-5ms sind realistisch.

2. 10 - 14 SPS-Zyklen

3. Die Variablen sind so belegt (Hab es jetzt auch wieder etwas genauer im Kopf) "MACRO 3020=123456.123456,"
3020 steht hierbei für die Nummer der Variable.

4. Kann sein, da aber alle 10-14 Zyklen Daten kommen müsste ich 2 Variablen pro Zyklus lesen

5. Ja, sie werden ja eh nicht schneller Empfangen

6. Wird kommen! Nur wann ...

7. Ja! Siehe dann 6.!

Grüße

Marcel
 
Zurück
Oben