Bibliothek WagoAppCom

3ei

Level-2
Beiträge
7
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuche gerade Daten über die Serielle RS485 Onboard Schnittstelle eines PFC200s zu empfangen mit der Bibliothek WagoAppCom in Codesys 3.5.
Das klappt auch soweit gut, ich habe nur folgendes Problem:

- Ich habe einen Empfangspuffer RxBuff mit Größe [0..199](Das ist die maximale Länge die übermittelt werden kann)
- Es können aber auch weniger Daten übermittelt werden

Beispiel: Erstes Telegramm 50 Bytes, 2. Telegramm 100 Bytes und 3. Telegramm 150 Bytes. Ich kann vorher nicht wissen wie viele Bytes in der nächsten Nachricht kommen ich weiß nur die Maximale Anzahl.

Hier mein Bausteinaufruf:
FBSerialInterface_Read_mod_0(xExecute := xRead,
Connection := Connection_Open,
pRxBuffer := ADR(RxBuff),
udiRxBufferSize := 200,
udiToRead := 200);

Das Problem was ich habe ist, dass die Telegramme immer an den Puffer drangehängt werden. Wenn der Puffer nun schon bis [150] gefüllt ist und ein Telegramm der Länge 150 gesendet wird, wird der Puffer voll beschrieben und fängt dann wieder ab [0] an. Dabei verliere ich aber dann die Bytes die noch in den Puffer gepasst haben.

Eine einfache Lösung wäre es natürlich nach jeder Nachricht wieder bei RxBuff[0] mit dem Schreiben anzufangen.
Hat jemand dort einen Vorschlag, eine Lösung oder einen anderen Baustein für mich?

Vielen Dank!
 
Idealerweise kannst Du erkennen, wie lang das Telegramm ist.
Da es eine Pause zwischen den Telegrammen geben sollte, kannst Du den Pufferindex nach dem Auswerten eines Telegrammes auf Null setzen.
Somit sollte das nächste Telegramm dann am Anfang des Puffers liegen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kann vorher nicht wissen wie viele Bytes in der nächsten Nachricht kommen
In den Nachrichten sind aber Endezeichen enthalten?
Du könntest die empfangenen Zeichen einzeln aus dem Empfangspuffer lesen, ggf. den Read mehrmals im Zyklus aufrufen.
 
Oder Du liest Dir die Zeichen in einen eigenen Buffer. Aus diesem liest Du Dein Telegramm aus, löschst die ausgewerteten Zeichen und schiebst den Rest nach vorne. Beim nächsten Lesen des Empfangspuffers hängst Du den dann an die verbliebenen Zeichen an und hast wieder im Idealfalle ein vollständiges Telegramm. Bleiben wieder Zeichen über, schiebst Du die wieder nach vorne, hängst den Empfangspuffer wieder an, ... usw ...
 
Vielen Dank für die Antworten.

@Tobsucht Die Telegrammlänge kann ich erkennen, Wie gebe ich im FB Aufruf einen Index an, ab wann das Array beschrieben werden soll?

@JSEngineering Wenn es zum von mir beschriebenen überlauf kommt habe ich keine Chance das Auszulesen:
Der FB hat einen Ausgang: xDone_Read := FBSerialInterface_Read_mod_0.xDone;
xDone_Read werte ich mit einem RTRIG aus um zu wissen wann der FB fertig ist mit lesen. Deine Idee mit dem Überschreiben in einen Extra Puffer habe ich bereits ausprobiert:
Wenn ich 2 Telegramme sende, wobei das 2. zum "Überlauf" führt, wird xDone_Read nur 2 mal getriggert. Um deine Idee zu realisieren müsste die Variable 3 mal umschalten:
- 1. Telegramm -> xDone eine Flanke + Puffer fast voll -> Alles in anderen Puffer
- 2. Telegramm -> xDone eine Flanke + Puffer endgültig voll -> Alles an den anderen puffer anhängen ohne 1. Telegramm,
- xDone zweite Flanke vom 2. Telegramm -> Den Rest an den Puffer anhängen.
Oder übersehe ich da etwas?

@PN/DP Die Nachricht hat einen definierten Anfang und ein definiertes Ende. der FB beschreibt meinen Puffer in einem Zyklus. Ich habe soweit ich weiß nicht die Möglichkeit die einzelnen CLKs der Seriellen Übertragung an sich auszuwerten, das macht alles der FB. Ich bekomme nur ein beschriebenen Puffer.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

aus der Hilfe:
The FB waits for a number of received bytes udiToRead before it terminates. If a number of 0 is applied, it returns after the first try.

The FB may read more bytes than udiToRead if the buffer size udiRxBufferSize is larger than the desired number of bytes.

Example: udiToRead=0 , udiRxBufferSize=1

The FB may read one byte if one comes in, but otherwise it simply returns.

Also Buffer zunächste einmal größer wählen. Dann udiToRead kleiner. Entweder kleineste Telegrammlänge oder noch weniger.

Dann einen zusätzliche Buffer nehmen. Dort die jeweils empfangenen Daten (siehe udiRxNBytes) reinkopieren bzw. anhängen, wie @JSEngineering geschrieben hat. Danach im Buffer Telegramanfang suchen, wenn gefunden prüfen ob Telegramm vollständig. Wenn ja Auswerten und Telegramm aus Buffer löschen, wenn nicht warten bis nächster Schwung an Daten reinkommt.

Gruß
 
Danke, mit einer 0 bei udiToRead Wird der Puffer vom FB im nächsten Zyklus geleert und wieder ab [0] beschrieben.
Gibt man eine Zahl ungleich 0 an, wartet der FB bis die Entsprechende Menge an Bytes angekommen ist.
 
Zuletzt bearbeitet:
@JSEngineering Wenn es zum von mir beschriebenen überlauf kommt habe ich keine Chance das Auszulesen:
Der FB hat einen Ausgang: xDone_Read := FBSerialInterface_Read_mod_0.xDone;
xDone_Read werte ich mit einem RTRIG aus um zu wissen wann der FB fertig ist mit lesen. Deine Idee mit dem Überschreiben in einen Extra Puffer habe ich bereits ausprobiert:
Wenn ich 2 Telegramme sende, wobei das 2. zum "Überlauf" führt, wird xDone_Read nur 2 mal getriggert. Um deine Idee zu realisieren müsste die Variable 3 mal umschalten:
- 1. Telegramm -> xDone eine Flanke + Puffer fast voll -> Alles in anderen Puffer
- 2. Telegramm -> xDone eine Flanke + Puffer endgültig voll -> Alles an den anderen puffer anhängen ohne 1. Telegramm,
- xDone zweite Flanke vom 2. Telegramm -> Den Rest an den Puffer anhängen.
Oder übersehe ich da etwas?

Naja, dann bist zu entweder zu langsam oder der Empfangspuffer ist zu klein gewählt.
Wenn DU es nicht schaffst, den Empfangspuffer "rechtzeitig" auszulesen, liegt es eher an Deinem Programm als an dem Baustein.
Du hast mehrere Optionen:
  • Zykluszeit verringern
  • Den Empfangspuffer öfter auslesen (führt dann aber vermutlich früher oder später zum Überlauf Deines internen Puffers, weil Du nicht ausreichend schnell verarbeitest)
  • Den Empfangspuffer vergrößern, so daß wenigstens 2 Telegramme reinpassen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du ein definierte Start- und Endzeichen hast, welche nicht weiter im Telegramm vorkommen, kannst Du auch die WagoAppScanner nehmen.
Der Funktionsbaustein ist dafür gebaut solche Zeichenketten zu empfangen.
 
Zurück
Oben