While Schleife für Zahlerstandauswertung?

mag81

Level-1
Beiträge
14
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe folgende Herausforderung bei der ich Hilfe bräuchte. Ich würde gerne ein Antworttelegramm über RS232 auswerten. Realisieren möchte ich in ST. Das Antworttelegramm kann unterschiedlich lang sein(Ist ein Zählerstand). Meine Idee ist nun eine While Schleife bis der Hex Wert 03 kommt (ETX). Leider zählt mein Index nicht so wie ich möchte. Vielleicht findet ja Jemand den Fehler:

IF RecvBuffer[0] =16#02 AND RecvBuffer[1] =16#06 THEN //Startbedingung
WHILE NOT RecvBuffer =16#03 // Abbruchbeding End OF Text
DO i :=i+1; // Index
aZaehlerYAchse := RecvBuffer[2+i]; // Array zum Speichern des Zaehlerstandes
END_WHILE
i :=0; //Index auf 0 setzen
END_IF

MfG Marco
 
Hallo Marco,

dein Programm setzt voraus, dass die komplette Nachricht bereits empfangen wurde.
Wenn das Ende-Zeichen nicht im Empfangspuffer enthalten ist läuft der Index auch eventuell über die Arraygrenze hinaus. Dies verursacht unter Umständen zu Zugriffsverletzungen.

Die Schleife verhindert eventuell auch das Empfangen neuer Zeichen, da das Programm nicht weiter abgearbeitet wird.

Da das Programm auf einer SPS geschrieben wird, wäre hier eine Statemachine angebracht (CASE).
So kann in einem Schritt geprüft werden ob neue Zeichen empfangen wurden und ob das Ende-Zeichen enthalten ist.

Zusätzlich kann ein Timeout realisiert werden, welcher den Empfangspuffer leer, wenn das Ende-Zeichen nicht empfangen wurde.


Grüße
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie zählt denn Dein Index? Und wie wolltest Du es denn?

Dein Code beginnt mit irgendeinem (hier nicht gezeigten, zufälligen?) Wert für i und erhöht den Wert rasend schnell bis spätestens im drittletzten Byte des RecvBuffer ein 16#03 gefunden wird oder Deine SPS in STOP geht wegen Zykluszeitüberschreitung oder Speicherzugriffsfehler/Überschreitung der Array-Grenzen.

Harald
 
Was genau geht denn nicht?

1. Ich würde zuert einmal i := 0; ganz oben i die erste Zeile schreiben, denn was passiert beim allerersten Durchlauf??? welchen Wert hat dann i?
2. Was passiert, wenn 16#03 gar nicht vorkommt? Zählt i bis ins Unendliche? Ist dein Array unendlich groß? Kommt nicht irgendwann die Zykluszeitüberschreitung, weil die Schleife nie verassen wird?
Also unbedingt eine Abbruchbedingung spätesten, wenn Max-Array erreicht ist mit in die Whilebedingung aufnehmen.
 
Das Antworttelegramm ist immer komplett, wenn ich es auswerten möchte. Ich sende einen Befehl um den Kanal auszulesen und bekomme die Antwort in folgender Form <STX><ACK> nnnnn <ETX>
Das <STX> und das <ACK> sind meine Einsprung Bedingungen der If Schleife (RecvBuffer[0] und RecVBuffer[1]) oben im Text Ich möchte dann ab da alle Werte in ein neues Array schreiben (aZaehlerYAchse) bis das <ETX> kommt. Das i ist meine Index Variable damit ich in dem RecvBuffer immer weiter vorwärts gehe. Die Grenzen und mögliche Zeitüberschreitungen muss ich auf jeden Fall noch bedenken. Geht mein Ansatz in die richtige Richtung oder kann man das viel einfacher oder eleganter lösen? :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hast Du denn in einem Telegramm mehrere Achsenwerte drin oder immer nur einen? Sind die Werte nur 1 Byte groß oder welcher Datentyp? Sind das womöglich Zahlenwerte im Klartext/ASCII? Sind die Telegramme immer gleich lang oder schwankt die Länge? Was ist das "nnnnn", wie sieht es aus?
Kannst Du mal den kompletten genauen Aufbau eines realen Telegramms zeigen?

WHILE-Schleifen ohne Begrenzung der max-Anzahl Durchläufe programmiert man in SPS üblicherweise nicht.
Das i muß auf einen max-Wert überwacht werden, da bietet sich oft eine FOR-Schleife an.

Was willst Du mit "aZaehlerYAchse := RecvBuffer[2+i]" erreichen? Da würdest Du im vorletzten Durchlauf das <ETX> 16#03 in aZaehlerYAchse speichern und im letzten Durchlauf das Byte hinter dem <ETX>, bevor das <ETX> gefunden wird.


PS: IF-Schleifen gibt es nicht

Harald
 
Bis auf die fehlende Abbruchbedingung für die Schleife falls kein ETX im Puffer ist, sieht das ganz OK aus. Aber du hast ja gesagt das es nicht funktioniert.

Den Index i kannst du in der Online-Ansicht nicht beobachten. Der müsste immer als 0 erscheinen wenn die Schleife korrekt beendet wird, weil das ja die letzte Zuweisung ist. Wenn du das i:=0; vor die Schleife schreibst, müsste i dir den letzten Indexwert anzeigen.

Werden denn die Puffer-Daten korrekt in das andere Array kopiert?

EDIT
Die Zeile aZaehlerYAchse := RecvBuffer[2+i]; ist natürlich murks. Wenn du die Werte ab Index 2 kopieren willst, dann darfst du auch erst ab Index 2 anfangen nach deinem ETX zu suchen. Der Offset in RecvBuffer verschiebt dir alles. Im schlimmsten Fall läufst du aus dem Arraybereich raus fals das ETX erst ganz am Ende oder garnicht kommt. Setzte den Startwert von i auf 2 und erhöhe i erst nach dem Kopierbefehl. Um aZaehlerYAchse ab Index 0 zu beschreiben kannst du hier den Startwert wieder abziehen.

i:=2;
WHILE (NOT RecvBuffer = 16#03) AND (i < BUFFER_SIZE) (*Wert für Länge von RecvBuffer*) DO
aZaehlerYAchse[i-2] := RecvBuffer;
i:=i+1;
END_WHILE
 
Zuletzt bearbeitet:
Danke für die vielen hilfreichen Antworten. Meine Antwort sieht immer so aus <STX><ACK>Zaehlerstand(dafür stand das nnnn)<ETX><CR><LF> Meine empfangenen sind immer 1 Byte groß und werden in einem Array of BYte abgelegt (RecvBuffer). Bei mir werden im Moment nicht die Daten aus dem RecvBuffer in mein aZaehlerYAchse übernommen. Das ist mein eigentliches Problem.:lol:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann würde ich vorschlagen du bringst zuerst mal das i := 2 ganz nach oben und testest das. (siehe MasterOh)
 
Zuletzt bearbeitet:
Zurück
Oben