RS232 einlesen

Mohamed

Level-2
Beiträge
76
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
Ich brauche bitte Hilfe bei meinem Projekt. Ich schreibe und Empfänge (SPS) Daten über RS232 an/von Kommunikationsplatine. Die gesendeten Daten werden von kommunikationsplatine validiert und verarbeitet. Wird ein Fehler erkannt, wird im Errorcode das jeweilige bit zur Erkennung des Fehlers gesetzt. Sind die Daten Valide, so werden die an die Steuerplatinen gesendet. Die Kommunikationsplatine empfängt wiederrum Antwort(en) von Steuerplatinen. Alle empfangenen Daten werden gesammelt und in einem Output String aus-gegeben. Der Output String enthält einmalig die Anzahl der Antworten und für jede geantwortete Steuerplatine die Antwortnummer, Modulnummer, Instruktion, Parameter, Wert und den Errorcode. Der Errorcode gibt im Fehlerfall die Art eines Fehlers an. Der ist 32 Bit lang.
Zunaechst, ich arbeite mit e!cockpit und verwende für die RS232 die Bibliothek WagoAppCom.
Ich lese die Daten in ein Array auf BYTE:
Problem: ich muss die empfangene Daten verarbeiten, dass im Fehlerfall die Anlage ausgeschaltet werden muss und die Fehlern im HMI anzeigen lassen.
Danke für jeden, der mir helfen kann.
Unbenannt.PNGUnbenannt1.PNGUnbenannt2.PNGUnbenannt3.PNGUnbenannt5.PNG
 
Hallo zusammen,
Ich brauche bitte Hilfe bei meinem Projekt. Ich schreibe und Empfänge (SPS) Daten über RS232 an/von Kommunikationsplatine. Die gesendeten Daten werden von kommunikationsplatine validiert und verarbeitet. Wird ein Fehler erkannt, wird im Errorcode das jeweilige bit zur Erkennung des Fehlers gesetzt. Sind die Daten Valide, so werden die an die Steuerplatinen gesendet. Die Kommunikationsplatine empfängt wiederrum Antwort(en) von Steuerplatinen. Alle empfangenen Daten werden gesammelt und in einem Output String aus-gegeben. Der Output String enthält einmalig die Anzahl der Antworten und für jede geantwortete Steuerplatine die Antwortnummer, Modulnummer, Instruktion, Parameter, Wert und den Errorcode. Der Errorcode gibt im Fehlerfall die Art eines Fehlers an. Der ist 32 Bit lang.
Zunaechst, ich arbeite mit e!cockpit und verwende für die RS232 die Bibliothek WagoAppCom.
Ich lese die Daten in ein Array auf BYTE:
Problem: ich muss die empfangene Daten verarbeiten, dass im Fehlerfall die Anlage ausgeschaltet werden muss und die Fehlern im HMI anzeigen lassen.
Danke für jeden, der mir helfen kann.Unbenannt.PNGUnbenannt1.PNGUnbenannt2.PNGUnbenannt3.PNGUnbenannt5.PNG
 
Zuletzt bearbeitet von einem Moderator:
Zuviel Werbung?
-> Hier kostenlos registrieren
Geändert von rostiger Nagel (Heute um 16:53 Uhr) Grund: Themen zusammengeführt, Doppelpost in unterschiedlichen Foren ist nicht erwünscht
Hat jemand eine DoppelGlasKugel günstig abzugeben? ;)

Hilfe welcher Art? Problem mit dem Empfangen der Daten? Problem beim Auswerten der ErrorCodes? Problem mit dem Ausschalten der Anlage? Problem beim Anzeigen des AusschaltGrundes? Problem mit dem Formulieren der Frage[n]?

PS:
Wie viele SteuerPlatinen/Module?
n * 48 Byte/SteuerModul + 16 Byte wäre ein AntwortTelegramm im worst case (alle Module melden einen Fehler) lang.
In ein Array mit 201 Byte passen also maximal die Antworten von 3 Modulen gleichzeitig.
 
Zuletzt bearbeitet:
Hallo Heinileini,
Die Daten Empfänge ich in ein Array of BYTE, mit dem Ausschalten der Anlage wenn eine Fehler aufgetreten wird ist kein Problem,ich kriege es alleine hin sowie auch die anzeigen der Fehler im HMI.
Problem ist beim Auswerten der Errorodes:???: wie kann ich das auswerten wenn ich nur die Errorcodes Empfänge und wenn wenn ich die Errorcodes mit anderen Parametern (Anzahl der Antworten, Antwortnummer, Modulnummer, Instruktion, Parameter, Value) Empfänge. Ich hab mit diese Klein Code angefangen aber ich weiß nicht wie es weiter geht??

For i:=0 TO (SIZEOF (uC_READ)) BY 1 DO
IF uC_READ:= 10 AND uC_READ[i+1]:= 13 AND uC_READ[i+2]:= 10 AND uC_READ[i+3]:=13 THEN
IF.......
........
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@ rostiger Nagel:
Sorry Helmut, das war ein böser Tippfehler. Ich meinte natürlich "Hat jemand eine DoppelGlasKugel günstig abzugeben?". Habe ich in #3 korrigiert.
Um doppelte Posts zu enträtseln, brauche ich einfach eine DoppelGlasKugel. ;)

@Mohamed:
Ich würde zunächt das 3. DoppelWort prüfen.
Steht \n\r\n\r drin, so dürfte es ein ErrorTelegramm laut Bild 4 sein.
Steht "nur" \n\r drin (rechtsbündig oder linksbündig? Was steht in den beiden anderen Bytes? Bitte klären!), so dürfte es eine Antwort laut Bild 3 sein.
3. DoppelWort: die Bytes 8..11.

PS:
Welche DatenTypen haben 'Errorcode' (DWORD?), 'Anzahl der Antworten' (DINT?), u.s.w.?
 
Zuletzt bearbeitet:
@Heinileini
vielen lieben Dank für die Rückmeldung!
Es sind 7 Steuerplatinen.
Die Variablen sind im Programm der Steuerplatinen so deklariert:
uint8_t NumberOfAnsweres;
uint8_t Modulnumber;
uint8_t Instruction;
uint8_t Parameter;
uint32_t Value;
uint32_t ErrorCode;

Also das Telegramm laut Bild 3 wird immer Empfangen egal ob es ein Fehler aufgetreten ist oder nicht. Es beginnt mit der Ausgabe des Trennzeichens „\n\r\n\r“. Anschließend folgt die Anzahl der Antworten und dem Trennzeichen „\n\r“. Die Software zum Auslesen der Antworten weiß nun anhand der Anzahl der Antworten wie häufig der kommende Text wiederholt wird. Für jede antwortende Steuerplatine wird die jeweilige Modulnummer, die Instruktion, die Parameter, der Wert und der Errorcode ausgegeben (Wird ein Fehler erkannt, wird im Errorcode das jeweilige Bit zur Erkennung des Fehlers gesetzt). Die einzelnen Kommunikationsparameter werden durch ein „\t“ voneinander getrennt. Die Antworten selbst, werden durch ein „\n\r“ voneinander getrennt. Die Ausgabe der Antworten endet wieder mit einem „\n\r\n\r“.

Laut Bild 4 beginnt die Empfang beginnt mit dem Trennzeichens „\n\r\n\r“. Anschließend folgt der Errorcode und endet mit einem weiterem Trennzeichen „\n\r\n\r“.

Also Beide Telegramme (Bild 3 und Bild 4) beginnen und enden mit dem Trennzeichens „\n\r\n\r“.

Ich hoffe, ich habe dir das gut erklärt.
 
Ich hoffe, ich habe dir das gut erklärt.
Nicht schlecht.
Habe ich Dich auch richtig verstanden bzw. interpretiert?
Bytes.jpg
Die Anzahl Bytes vor den roten '?' habe ich improvisiert. Bitte kontrollieren!

Habe ich das richtig verstanden, dass Du nicht mit Telegrammen vom Typ laut Bild 4 rechnen musst???
Wenn doch:
Wie die den Typ erkennen?
Sind die ErrorCodes in beiden Typen gleich zu deuten? Gibt es evtl. DoppelBelegungen der Codes?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Heinileini

Die Anzahl Bytes vor den roten '?' ist Korrekt. Die Tabelle ist sehr gut.
Doch ich muss mit Telegramm von Typ laut Bild 4 rechnen. Die Fehle können an der Kommunikationsplatine aufgetreten werden( dann empfängt man nur Telegramm Bild 4). oder an der Steuerplatinen dann empfängt man nur Telegramm Bild 3.

Die Steuerdaten werden von der SPS an die Kommunikationsplatine gesendet. Da werden die Daten geprüft und Validiert. Wird ein Fehler erkannt, wird im Errorcode das jeweilige Bit zur Erkennung des Fehlers gesetzt (Telegramm bild 4 wird empfangen).
Ist kein Fehler aufgetreten, werden die Daten weiter zum Steuerplatinen gesendet. Die Steuerplatinen antworten mit dem Telegramm (Bild 3). Ist ein Fehler bei Steuerplatine(n) aufgetreten, wird im Errorcode das jeweilige Bit zur Erkennung des Fehlers gesetzt.
Die Errorcodes sind in beiden Typen gleich zu deuten. Sehe Bild 1.

Der Errorcode gibt im Fehlerfall die Art eines Fehlers an. Ist beispielsweise das erste Bit gesetzt, bedeutet das, dass Fehler A aufgetreten ist. Wenn zudem das zweite Bit gesetzt ist, bedeutet dies, dass zusätzlich Fehler B geschehen ist. Damit können unterschiedliche Fehler im gleichen Errorcode gespeichert werden. Tabelle Bild 1 zeigt hierfür, welcher Fehler bei welchem gesetzten Bit aufgetreten ist.
 
Zuletzt bearbeitet:
Hallo,

bau Dir am besten eine State Machine / Schrittkette.

Mit Deiner for Schleife hast Du schon einmal einen guten Anfang.

Jetzt suchst Du erst einmal den Anfang einer Nachricht, da hast Du schon die if Abfrage.
Wenn Das Ergebnis negativ ist erhöhst Du i um 1 (entweder i := i +1 oder den continue Befehl um die Schleife weiterlaufen zu lassen).
Wenn das Ergebnis positiv ist erhöhst Du i um 4 wechselst Du in den nächsten State.

Jetzt schaust Du nach ob die beiden übernächsten Zeichen im Puffer (i+1 und i+2) \n\r sind.
Wenn ja dann sollte im Puffer die Anzahl der Antworten stehen und Du wechselst in den State zum Auswerten der Nachrichten.
Wenn nein dann solltest Du einen Errorcode habe und Du wechselst in den State zum Auswerten des Errorcodes.
Wenn beides nicht zutrifft, dann liegt ein anderer Fehler vor.

Bei Errorcode kann man dann noch weitere Prüfungen durchführen, Puffer[i+4] sollte ja wieder \n enthalten.

Und so arbeitest Du Dich weiter durch den Puffer.

Frage ist, ob im Puffer immer eine vollständige Antwort liegt oder es auch mal zu Teilen einer Nachricht kommen kann.

Auch ist es fraglich ob Du direkt nach dem Schreibbefehl auch gleich gültige Werte mit dem Lesenbefehl erhälst oder ob Du da erst warten solltest bis der Schreibbefehl abgeschlossen ist (s. Bild unbenannt5.jpg im ersten Post)

Gruß
 
Hallo Thruser,

Danke für die Hinweise:)
zu Frage 1: ich denke, dass im Puffer immer eine vollständige Antwort liegt, weil die Steuerelektronik (Kommunikationsplatine/ Steuerplatinen) schicken immer eine vollständige Antwort zur SPS. wenn was ich gesagt habe, reicht nicht zu wissen das im Puffer immer eine vollständige Antwort liegt, wie kann man dann das wissen?

zu Frage 2: Es muss erst mal der Schreibbefehl abgeschlossen werden, dann werden die Daten von Steuerelektronik verarbeitet und dann wird entweder ein Errorcode oder eine Nachricht zurück gesendet, diese werden mit der Lesenbefehl empfangen.

Wie sieht mein Code aus? es freut mich sehr für eure hinweise und Ideen.

GVL.SUC.Read(pRxBuffer := ADR(uC_READ),udiRxBufferSize:=SIZEOF(uC_READ));
For i:=0 TO (SIZEOF (uC_READ)) BY 1 DO

IF uC_READ:= 10 AND uC_READ[i+1]:= 13 AND uC_READ[i+2]:= 10 AND uC_READ[i+3]:=13 THEN
i:=i+4;
IF uC_Read[i+1]:=10 AND uC_Read[i+2]:=13 THEN
Anzahl_der_Antworten:=uC_Read;
Nachrichten_Auswerten(); // in diesem Baustein/Aktion werden die Nachrichtet ausgewertet
ELSE
Auswerten_Errorcode(); // in diesem Baustein/Aktion wird der Errorcodes ausgewertet
END_IF
ELSE
i:=i+1;
END_IF
END_FOR
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo


Wie sieht mein Code aus? es freut mich sehr für eure hinweise und Ideen.


Es ist ein Anfang.


Bitte den Code in den entsprechenden Tags posten, dann ist es übersichtlicher


Code:
GVL.SUC.Read(pRxBuffer := ADR(uC_READ),udiRxBufferSize:=SIZEOF(uC_READ));


For i:=0 TO (SIZEOF (uC_READ)) BY 1 DO
  IF uC_READ[i]:= 10 AND uC_READ[i+1]:= 13 AND uC_READ[i+2]:= 10 AND uC_READ[i+3]:=13 THEN
    i:=i+4;
    IF uC_Read[i+1]:=10 AND uC_Read[i+2]:=13 THEN
      Anzahl_der_Antworten:=uC_Read[i];
      Nachrichten_Auswerten(); // in diesem Baustein/Aktion werden die Nachrichtet ausgewertet
    ELSE
        Auswerten_Errorcode(); // in diesem Baustein/Aktion wird der Errorcodes ausgewertet
    END_IF
  ELSE
      i:=i+1;
  END_IF
END_FOR


Ich würde das als State Machin aufbauen und nicht mit Unterfunktionen, aber das ist Dir überlassen.


Bei Nachrichten_Auswerten() gehst Du jetzt nach dem gleichem Muster vor.


Du solltest aber noch folgende Prüfungen vorsehen bzw. Dir Gedanken machen:
- uC_Read[i+x] - was passiert bei i+x > udiRxBufferSize:=SIZEOF(uC_READ)
- Warum überhaupt das i := i+1 am Ende
- Püfen ob nach den Errorcode auch wirklich die vier Trennzeichen kommen


zu Frage 1: ich denke, dass im Puffer immer eine vollständige Antwort liegt, weil die Steuerelektronik (Kommunikationsplatine/ Steuerplatinen) schicken immer eine vollständige Antwort zur SPS. wenn was ich gesagt habe, reicht nicht zu wissen das im Puffer immer eine vollständige Antwort liegt, wie kann man dann das wissen?


zu Frage 2: Es muss erst mal der Schreibbefehl abgeschlossen werden, dann werden die Daten von Steuerelektronik verarbeitet und dann wird entweder ein Errorcode oder eine Nachricht zurück gesendet, diese werden mit der Lesenbefehl empfangen.
Damit wirst Du Dich noch ausführlich beschäftigen müssen. Auch mit dem Senden. Da hast Du ja noch den anderen Thread.


Habe gerade nicht die Zeit alles auszuführen, ich hoffe jemand anderes hier vom Board kann das auch besser als ich erklären.


Kümmern wir uns jetzt erst einmal um die Auswertung der empfangenen Nachricht.


Gruß
 
@Thruser
Vielen dank. Ich werde den Code in den entsprechenden Tags posten.
Hier ist noch mal den Code und die Unterfunktion Auswerten_Errorcode.

Code:
GVL.SUC.Read(pRxBuffer := ADR(uC_READ),udiRxBufferSize:=SIZEOF(uC_READ));


For i:=0 TO (SIZEOF (uC_READ)) BY 1 DO
  IF uC_READ[i]:= 10 AND uC_READ[i+1]:= 13 AND uC_READ[i+2]:= 10 AND uC_READ[i+3]:=13 THEN
    i:=i+4;
    IF uC_Read[i+1]:=10 AND uC_Read[i+2]:=13 THEN
      Anzahl_der_Antworten:=uC_Read[i];
      Nachrichten_Auswerten(); // in diesem Baustein/Aktion werden die Nachrichtet ausgewertet

    ELSIF  uC_READ[i+4]:= 10 AND uC_READ[i+5]:= 13 AND uC_READ[i+6]:= 10 AND uC_READ[i+7]:=13 THEN

        Auswerten_Errorcode(); // in diesem Baustein/Aktion wird der Errorcodes ausgewertet
    END_IF
 
  END_IF
END_FOR


[FONT=Verdana]-------Auswerten_Errorcode()--------[/FONT]

i:=i+4;
[FONT=Verdana]IF (uC_READ[i] AND 2#00000001) THEN[/FONT]
[FONT=Verdana]    message:= 'UKNOW_Error' ;[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00000010) THEN[/FONT]
[FONT=Verdana]    message:= 'CAN_Error' ;[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00000100) THEN[/FONT]
[FONT=Verdana]    message:= 'Adressee_unkown' ;[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00001000) THEN[/FONT]
[FONT=Verdana]     message:= '[/FONT][FONT=Verdana]Parameter_unkown' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]     END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00010000) THEN[/FONT]
[FONT=Verdana]    message:= '[/FONT][FONT=Verdana]Parameter_is_setable_only' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00100000) THEN[/FONT]
[FONT=Verdana]    message:= 'Parameter_is_getable_only' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#01000000) THEN[/FONT]
[FONT=Verdana]    message:= 'Value_to_low' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#10000000) THEN[/FONT]
[FONT=Verdana]    message:= 'Value_to_high' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000001) THEN[/FONT]
[FONT=Verdana]    message:= 'Instruction_not_allowed' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000010) THEN[/FONT]
[FONT=Verdana]   message:= 'Instruction_unkown' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000100) THEN[/FONT]
[FONT=Verdana]    message:= 'Ask_priority_unkown' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00001000) THEN[/FONT]
[FONT=Verdana]    message:= 'Answer_priority_unkown' [/FONT][FONT=Verdana];[/FONT]
[FONT=Verdana]    END_IF[/FONT]

Gruß
 
Moin Mohamed,

wenn tatsächlich mehrere FehlerBits in einem ErrorCode gleichzeitig gesetzt sein sollten, überschreibst Du nach Deiner Methode mehrfach die Variable 'message'.
Wenn dann im AntwortTelegramm bis zu 7 ErrorCodes ankommen und die dortigen MeldeBits ebenfalls zum Überschreiben desselben 'message' führen, dann werden u.U. sehr viele Meldungen "geschlabbert".
Du musst Dir überlegen, ob Du Meldungen ganz bewusst unterdücken willst/sollst, z.B. eine Meldung mit geringerer Priorität bewusst unterdrücken, wenn gleichzeitig eine Meldung mit höherer Priorität ansteht. Ferner brauchst Du eine Vorstellung davon, wo und wie die Meldungen angezeigt werden sollen und wo und wie Du sie speichern kannst (ggfs FIFO), bis sie angezeigt werden können.
Es wäre schlecht, zu unterstellen, dass es nie zu einer Schwemme von sehr vielen gleichzeiten Meldungen kommen wird.
Willst Du evtl. sogar protokollieren, von wann bis wann eine Meldung angestanden hat?
Wie sieht evtl. mit dem Quittieren von Meldungen aus?
Willst Du die MeldungsTexte evtl. auf verschiedene Sprachen umschaltbar gestalten?
Willst Du dieselben MeldungsTexte mehrfach im Programm eintippen oder nur an einer Stelle und sie in einem Array ablegen?
... ?
Erstmal überlegen, was das Programm leisten können soll und auch über evtl. spätere Erweiterungen nachdenken, bevor man anfängt, eine "auf-die-Schnelle-Variante" zu programmieren, die hinterher niemand gebrauchen kann. ;)

Gruss, Heinileini
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Heinileini,

Durch Verwendung der Alarmverwaltung von e!Cockpit werden die kritische Prozesszustände festgestellt, aufgezeichnet und anschließend mit Hilfe von Visualisierungselementen dargestellt werden. z.B. S. Bild k.PNG


Im Störungsfall, um die Anzeige wiederStörungsfrei zu erhalten, müssen folgende Dinge erledigt werden:
·Die Ursache derStörung muss beseitigt werden -->Es muss alle Meldungenquittiert werden --> Die Anlage neuEinschalten sehe beispiel hier
l.PNG
Code:
[FONT=Verdana]-------Auswerten_Errorcode()--------[/FONT]
(--- Variable A,B,C......... werden als Bool deklariert---)
i:=i+4;
[FONT=Verdana]IF (uC_READ[i] AND 2#00000001) THEN[/FONT]
[FONT=Verdana]    A;   //  UKNOW_Error[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00000010) THEN[/FONT]
[FONT=Verdana]    B;   //CAN_Error[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00000100) THEN[/FONT]
[FONT=Verdana]    C,   //Adressee_unkown[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00001000) THEN[/FONT]
[FONT=Verdana]     Z;    //[/FONT][FONT=Verdana]Parameter_unkown[/FONT]
[FONT=Verdana]     END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00010000) THEN[/FONT]
[FONT=Verdana]    D;   //[/FONT][FONT=Verdana]Parameter_is_setable_only[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#00100000) THEN[/FONT]
[FONT=Verdana]    E;   //Parameter_is_getable_only[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#01000000) THEN[/FONT]
[FONT=Verdana]    F;   //Value_to_low[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i] AND 2#10000000) THEN[/FONT]
[FONT=Verdana]    G;   //Value_to_high[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000001) THEN[/FONT]
[FONT=Verdana]    H;    //Instruction_not_allowed[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000010) THEN[/FONT]
[FONT=Verdana]   I;    //Instruction_unkown[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00000100) THEN[/FONT]
[FONT=Verdana]    K;    //Ask_priority_unkown[/FONT]
[FONT=Verdana]    END_IF[/FONT]
[FONT=Verdana]IF (uC_READ[i+1] AND 2#00001000) THEN[/FONT]
[FONT=Verdana]    L;    //Answer_priority_unkown[/FONT]
[FONT=Verdana]    END_IF[/FONT]
 
Zuletzt bearbeitet:
Geändert von Mohamed (Heute um 14:40 Uhr)
Durch Deine Änderung beginne ich zu verstehen, was Du meinst.
Code:
    IF (uC_READ[i] AND 2#00000001) THEN
        A[B] := TRUE[/B] ;   //  UKNOWN_Error
    END_IF ;
Setzt das Bit A auf TRUE, wenn das Bit 0 in uC_READ TRUE ist (und löscht/rücksetzt es nie - das geschieht z.B. anderweitig beim Quittieren).
Das würde ich lieber als "Einzeiler" programmieren:
Code:
    A := uC_READ[i] AND 2#00000001 OR A ;    // UKNOWN_Error
    B := uC_READ[i] AND 2#00000010 OR B ;    // CAN_Error
// u.s.w. bis
    L := uC_READ[i+1] AND 2#00001000 OR L ;  // Answer_priority_unkown
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kannst du mir bitte erklären wofür verwendest du jedes mal (OR A) (OR B) ..... ?
Code:
// Weil 

    IF (uC_READ[i] AND 2#00000001) THEN
       A := TRUE ;   //  UKNOWN_Error
    END_IF ;

// dasselbe tut, wie

    A := uC_READ[i] AND 2#00000001 OR A ;

// nämlich das Bit 'A' [B]SETZEN[/B], wenn 'uC_READ[i] AND 2#00000001' TRUE ist.

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Zugegeben, ich hatte Deine vermeintliche Anweisung 'A ;' zu 'A := TRUE ;' ergänzt, 
// weil meine Glaskugel der Überzeugung war, dass Du das so gemeint haben dürftest.

// Stichwort: [B]Selbsthaltung[/B]. Vielleicht besser verständlich, wenn man die
// Oder-Verknüpfung in der KOP-Variante darstellt.    

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Man kann z.B. auch

    IF (uC_READ[i] AND 2#00000001) THEN
       A := TRUE ;   //  UKNOWN_Error
    ELSE
       A := FALSE ;  //  UKNOWN_Error
    END_IF ;

// als "Einzeiler" schreiben, nämlich so
    
    A := uC_READ[i] AND 2#00000001 ;
    
// aber dann übernimmt 'A' den Zustand von 'uC_READ[i] AND 2#00000001' [B]immer[/B],
// also auch dann, wenn 'uC_READ[i] AND 2#00000001' FALSE ist ([B]WertZuweisung![/B]).
 
@Heinileini, Danke
Hier ist noch mal den Code nach der Verbesserung. Es fehlt mir noch die Unterfunktion Nachrichten_Auswerten()
Findest du immer noch Fehlern im Code oder ist bis jetzt alles in Ordnung?

Code:
GVL.SUC.Read(pRxBuffer := ADR(uC_READ),udiRxBufferSize:=SIZEOF(uC_READ));


For i:=0 TO (SIZEOF (uC_READ)) BY 1 DO
  IF uC_READ[i]:= 10 AND uC_READ[i+1]:= 13 AND uC_READ[i+2]:= 10 AND uC_READ[i+3]:=13 THEN
    i:=i+4;
    IF uC_Read[i+1]:=10 AND uC_Read[i+2]:=13 THEN
      Anzahl_der_Antworten:=uC_Read[i];
      Nachrichten_Auswerten(); // in diesem Baustein/Aktion werden die Nachrichtet ausgewertet

    ELSIF  uC_READ[i+4]:= 10 AND uC_READ[i+5]:= 13 AND uC_READ[i+6]:= 10 AND uC_READ[i+7]:=13 THEN

        Auswerten_Errorcode(); // in diesem Baustein/Aktion wird der Errorcodes ausgewertet
    END_IF
 
  END_IF
END_FOR




-----Ausweten_Errorcode()----


i:=i+4;


 A := uC_READ[i] AND 2#00000001 OR A ;    // UKNOWN_Error
 B := uC_READ[i] AND 2#00000010 OR B ;    // CAN_Error
 C := uC_READ[i] AND 2#00000100 OR C ;    //Adressee_unkown
 D := uC_READ[i] AND 2#00001000 OR D ;    //Parameter_unknow
 E := uC_READ[i] AND 2#00010000 OR E ;     //Parameter_is_setable_only  
 F := uC_READ[i] AND 2#00100000 OR F ;    //Parameter_is_getable_only 
 G := uC_READ[i] AND 2#01000000 OR G ;      //Value_to_low
 H := uC_READ[i] AND 2#10000000 OR H ;      //Value_to_high 
I := uC_READ[i+1] AND 2#00000001 OR I ;    //Instruction_not_allowed
K := uC_READ[i+1] AND 2#00000010 OR K ;    //Instruction_unkown
L := uC_READ[i+1] AND 2#00000100 OR L ;   //Ask_priority_unkown
M := uC_READ[i+1] AND 2#00001000 OR M ;    //Answer_priority_unkown

Gruß
 
Hallo,

ich sehe gerade, daß die IF Abfragen so nicht funktionieren. Du machst da eine Zuweisung anstelle eines Vergleichs. Das funktioniert zwar auch, aber anders als erwartet.

Code:
IF A=B THEN
anstelle von
Code:
IF A:=B THEN

Bei der Auswertung des Errorcodes kann es sein, daß Du die beiden Bytes vertauschen mußt. Das mußt Du ausprobieren.

Dann mußt Du aufpassen mit den Arraygrenzen. Was passiert, wenn i+7 > SIZEOF(uC_READ)? Das solltest Du vorher noch abfangen.

Deine Unterfunktion Nachrichten_Auswerten hast Du doch mit dem vorhandenen Code schon fast zusammen.

Das uint32_t value bekommt man entweder mit union (suche im Forum) oder mit
Code:
dwDWord := BYTE_TO_DWORD(uC_READ[i+3]) + BYTE_TO_DWORD(uC_READ[i+2]) * 16#100 + BYTE_TO_DWORD(uC_READ[i+1]) * 16#10000 + BYTE_TO_DWORD(uC_READ[i]) * 16#1000000
Auch hier muß man die Reihenfolge bzw. Wertigkeit ausprobieren

Gruß
 
Zurück
Oben