[gelöst] SerialPort - TCommTimeouts - was einstellen ?

Rund um die LCL und andere Komponenten
MmVisual
Beiträge: 1579
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von MmVisual »

Ich weiß halt nicht, wie die realen RS485-To-USB-Adapter und ihre Treiber reagieren.
Ich kann mir ja nicht alle Adapter selber kaufen, die sich draußen herumtreiben, nur um's zu testen .. :roll:
In der Regel schalten die USB-RS485 Adapter selbstständig zwischen Senden im Empfang um. Immer wenn man was sendet, wird der RS485 Chip auf Senden gesetzt. Man muss mantürlich das Protokoll beachten und darf nur dann was senden wenn man an der Reihe ist, ansonsten gibt es Kollistion und Datenmüll. RS485 ist nur Halfduplex, es darf nur ein Teilenhmer senden und alle anderen müssen hören.

Bei den Adaptern die sich draußen so "herumtreiben" gibt es zum Teil China-Kopieen. Z.B. wurden von FTDI die Chips kopiert. Nun hat FTDI da eine Sperre eingebaut so dass nur noch Original FTDI Chips mit deren Treibern funktionieren. Von daher sollen sich die Kunden nur Original Hardware kaufen bei denen der Treiber ordentlich funktioniert und verweigere einfach den Support wenn die keinen Originalen sondern eine billige CN Kopie kaufen. Wenn ich so einen Adapter kaufe dann achte ich immer darauf dass da ein Original FTDI Chip drin ist, damit gibt es am wenigsten Probleme.
EleLa - Elektronik Lagerverwaltung - www.elela.de

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

sstvmaster hat geschrieben: Di 31. Dez 2024, 16:52 Hallo,

du könntest auch mal LazComPort probieren, ist eigentlich TComPort 4.12.

Link: https://github.com/alexx2000/lazcomport
Okay, hab's mal heruntergeladen.

Da ist ja der gesamte Overhead drin, den ich nicht brauche.

Code: Alles auswählen

  // thread for background monitoring of port events
  TComThread = class(TThread)

Code: Alles auswählen

  TDTRFlowControl = (dtrDisable, dtrEnable, dtrHandshake);
  TRTSFlowControl = (rtsDisable, rtsEnable, rtsHandshake, rtsToggle);
  TFlowControl = (fcHardware, fcSoftware, fcNone, fcCustom);
  
Meine Software kommuniziert nicht mit einem Modem.

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

MmVisual hat geschrieben: Mi 1. Jan 2025, 10:53
Ich weiß halt nicht, wie die realen RS485-To-USB-Adapter und ihre Treiber reagieren.
Ich kann mir ja nicht alle Adapter selber kaufen, die sich draußen herumtreiben, nur um's zu testen .. :roll:
In der Regel schalten die USB-RS485 Adapter selbstständig zwischen Senden im Empfang um. Immer wenn man was sendet, wird der RS485 Chip auf Senden gesetzt. Man muss mantürlich das Protokoll beachten und darf nur dann was senden wenn man an der Reihe ist, ansonsten gibt es Kollistion und Datenmüll. RS485 ist nur Halfduplex, es darf nur ein Teilenhmer senden und alle anderen müssen hören.

Bei den Adaptern die sich draußen so "herumtreiben" gibt es zum Teil China-Kopieen. Z.B. wurden von FTDI die Chips kopiert. Nun hat FTDI da eine Sperre eingebaut so dass nur noch Original FTDI Chips mit deren Treibern funktionieren. Von daher sollen sich die Kunden nur Original Hardware kaufen bei denen der Treiber ordentlich funktioniert und verweigere einfach den Support wenn die keinen Originalen sondern eine billige CN Kopie kaufen. Wenn ich so einen Adapter kaufe dann achte ich immer darauf dass da ein Original FTDI Chip drin ist, damit gibt es am wenigsten Probleme.
Die beiden Geräte, die ich nur belausche, halten sich intern an die RS485-Regeln.
Ich lese nur mit, was sie untereinander an Daten-Paketen austauschen. Von daher bin ich "sauber".

Die RS485-To-ETH-Adapter funktionieren besser bis hin zu viel besser.
Und man kann seinen PC irgendwo im Haus ans Netzwerk "hängen",
ohne ein RS485-Kabel quer durch's ganze Haus ziehen zu müssen.


Von daher empfehle ich meinen Usern immer, diese RS485-To-ETH-Adapter zu verwenden.
Auch wenn sie 2 bis 4 mal so teuer sind wie dieser RS485-To-USB-Kram (mit simulierter COM Schnittstelle).
Und sie sind zuverlässiger.

Aber die User scheuen natürlich im ersten Schritt diese Geldausgabe,
weil sie noch nicht wissen ob sich das Geld ausgeben auch wirklich lohnt.
Und so habe ich dann halt doch die RS485-To-USB - User "an der Backe" :roll:

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

Dann zurück zu ..
PeterS hat geschrieben: Mo 30. Dez 2024, 22:10 Meine Frage war eine Verständnisfrage: record TCommTimeouts - was einstellen ?
Ich habe die Wirkung der hier im record gelisteten Parameter
trotz "Dokumentation" nicht verstanden.

Code: Alles auswählen

    // instance an object of [b]COMMTIMEOUTS[/b].
    COMMTIMEOUTS comTimeOut;
     // Specify time-out between charactor for receiving.
    comTimeOut.ReadIntervalTimeout =3;
     // Specify value that is multiplied
     // by the requested number of bytes to be read.
    comTimeOut.ReadTotalTimeoutMultiplier =3;
     // Specify value is added to the product of the
     // ReadTotalTimeoutMultiplier member
    comTimeOut.ReadTotalTimeoutConstant =2;
     // Specify value that is multiplied
     // by the requested number of bytes to be sent.
    comTimeOut.WriteTotalTimeoutMultiplier =3;
     // Specify value is added to the product of the
     // WriteTotalTimeoutMultiplier member
    comTimeOut.WriteTotalTimeoutConstant =2;
     // set the time-out parameter into device control.
    SetCommTimeouts(handlePort_,&comTimeOut);
Es gibt Beispiele im Web, da werden die folgenden beiden Werte auf 1000 gesetzt,
woanders auf 300, anderes Beispiel war 100 ..

Code: Alles auswählen

ReadTotalTimeoutConstant := 1000;        // 100; ?    https://www.mikrocontroller.net/topic/290997
WriteTotalTimeoutConstant := 1000;        // 100; ?    https://www.mikrocontroller.net/topic/290997
Ich habe beide wieder auf 0 gesetzt, dafür

Code: Alles auswählen

    ReadIntervalTimeout         := 10;       // @ 9600 Bits / sec = 1200 byte / sec
Ein erster User hat zurück gemeldet daß jetzt weniger kaputte Pakete (CRC16-Fehler) ankommen.
Scheint der richtige Weg zu sein.

Trotzdem, meine Frage:
PeterS hat geschrieben: Mo 30. Dez 2024, 22:10 record TCommTimeouts - was einstellen ?

siro
Beiträge: 758
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von siro »

Hallo, erstmal ein frohes neues Jahr:

ich habe mich auch schon intensiv mit der RS232 FTDI usw. unter Windows beschäftigt.
Ich konnte im System auch noch was umstellen, das kann man dem Endanwender natürlich nicht antun, dass er es auch tut :wink:
Aber vielleich kannst Du trotzdem noch etwas Informationen rauslesen:
viewtopic.php?p=92685#p92685

sorry, Link geht nicht, ich guck grad woran es liegt.....
im Suchfenster habe ich eingegeben Synaser FTDI

search.php?keywords=Synaser+FTDI
wenn ich den Beitrag aber anklicke, gibts ne Meldung:
Für den ausgewählten Zeitraum existieren keine Beiträge in diesem Thema.

Mein ursprünglicher Beitrag heisst:
Synaser RS232 und FTDI COM14
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

siro
Beiträge: 758
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von siro »

Hallo, erstmal ein frohes neues Jahr:

ich habe mich auch schon intensiv mit der RS232 FTDI usw. unter Windows beschäftigt.
Ich konnte im System auch noch was umstellen, das kann man dem Endanwender natürlich nicht antun, dass er es auch tut :wink:
Aber vielleich kannst Du trotzdem noch etwas Informationen rauslesen:
viewtopic.php?p=92685#p92685

Ich habe grad hier noch was gefunden:
Es gab mal im Buch Toolbox (Jahr 2006 glaube ich) eine Unit TSerial
Warum er den Wert 12000 also Grundlage nimmt, verstehe ich auch nicht....Alle Werte sollen ja, laut Microsoft, in Millisekunden angegeben werden

Auszug aus der Komponente TSerial

Code: Alles auswählen

// (c) 1998-2009  Rainer Reusch und Toolbox                                 
// (c) 1998-2009  Rainer Reusch und Computer & Literatur Verlag 

 // Basiswert für die Festlegung von Timeout-Werten
  TimeoutBase = 12000;  

     begin  // Timeouts festlegen
      if FRecTimeOut>0 then
      begin
        ReadIntervalTimeout:=0;
        ReadIntervalTimeout:=FRecTimeOut;
        ReadTotalTimeoutMultiplier:=TimeoutBase div dcb.Baudrate;
        if ReadTotalTimeoutMultiplier=0 then ReadTotalTimeoutMultiplier:=1;
        ReadTotalTimeoutConstant:=FRecTimeOut;
      end
      else
      begin
        ReadIntervalTimeout:=0;
        ReadTotalTimeoutMultiplier:=0;
        ReadTotalTimeoutConstant:=0;
      end;
      if FTrmTimeOut>0 then
      begin
        WriteTotalTimeoutMultiplier:=TimeoutBase div dcb.Baudrate;
        if WriteTotalTimeoutMultiplier=0 then WriteTotalTimeoutMultiplier:=1;
        WriteTotalTimeoutConstant:=FTrmTimeOut;
      end
      else
      begin
        WriteTotalTimeoutMultiplier:=0;
        WriteTotalTimeoutConstant:=0;
      end;
      SetCommTimeOuts(FSerHandle,ctmo);
    end;                                                     

Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

siro hat geschrieben: Mi 1. Jan 2025, 14:25 ich habe mich auch schon intensiv mit der RS232 FTDI usw. unter Windows beschäftigt.
Ich konnte im System auch noch was umstellen, das kann man dem Endanwender natürlich nicht antun, dass er es auch tut :wink:
Aber vielleich kannst Du trotzdem noch etwas Informationen rauslesen:
viewtopic.php?p=92685#p92685
Interessant zu lesen, das geht ein wenig in meine Richtung,
abgesehen davon daß ich hier nur lahme 9600 habe .. :roll:
siro hat geschrieben: Mi 1. Jan 2025, 14:25 Ich habe grad hier noch was gefunden:
Es gab mal im Buch Toolbox (Jahr 2006 glaube ich) eine Unit TSerial
Warum er den Wert 12000 also Grundlage nimmt, verstehe ich auch nicht....Alle Werte sollen ja, laut Microsoft, in Millisekunden angegeben werden

Auszug aus der Komponente TSerial

Code: Alles auswählen

// (c) 1998-2009  Rainer Reusch und Toolbox                                 
// (c) 1998-2009  Rainer Reusch und Computer & Literatur Verlag 

 // Basiswert für die Festlegung von Timeout-Werten
  TimeoutBase = 12000;  

     begin  // Timeouts festlegen
      if FRecTimeOut>0 then
      begin
        ReadIntervalTimeout:=0;
        ReadIntervalTimeout:=FRecTimeOut;
        ReadTotalTimeoutMultiplier:=TimeoutBase div dcb.Baudrate;
        if ReadTotalTimeoutMultiplier=0 then ReadTotalTimeoutMultiplier:=1;
        ReadTotalTimeoutConstant:=FRecTimeOut;
      end
      else
      begin
        ReadIntervalTimeout:=0;
        ReadTotalTimeoutMultiplier:=0;
        ReadTotalTimeoutConstant:=0;
      end;
      if FTrmTimeOut>0 then
      begin
        WriteTotalTimeoutMultiplier:=TimeoutBase div dcb.Baudrate;
        if WriteTotalTimeoutMultiplier=0 then WriteTotalTimeoutMultiplier:=1;
        WriteTotalTimeoutConstant:=FTrmTimeOut;
      end
      else
      begin
        WriteTotalTimeoutMultiplier:=0;
        WriteTotalTimeoutConstant:=0;
      end;
      SetCommTimeOuts(FSerHandle,ctmo);
    end;                                                     

Zumindest ergibt hier die Kombination der Parameter endlich mal einen Sinn - danke für den guten Hinweis und den Bespiel-Code !!!

Benutzeravatar
kupferstecher
Beiträge: 431
Registriert: Do 17. Nov 2016, 11:52

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von kupferstecher »

PeterS hat geschrieben: Di 31. Dez 2024, 10:37 [...], wie es "meine" Datenpakete einliest.
Das Terminalfenster reiht ohne Unterbrechung die Bytes wahllos hintereinander.
So ist das absolut unbrauchbar für meine Anwendung.
Bei einer seriellen Schnittstelle gibt es keine Pakete in dem Sinne. Die Bytes werden der Reihe nach ausgegeben und trudeln nacheinander ein. Paketgrenzen auf Schnittstellenebene gibt es nicht, kann der Empfänger also auch nicht detektieren. Dass die eine Lösung funktioniert und die andere nicht, ist dann eher Zufall, insbesondere wenn noch TCP übers Ethernet im Spiel ist. Dort wird nämlich auf Netzwerkebene in Paketen verschickt, aber beim TCP-Protokoll darf jeder Teilnehmer die Pakete neu packen, zerstückeln usw, garantiert wird lediglich der Bytestrom, also dass die Bytes in gleicher Reihenfolge ankommen wie versendet. In der Praxis kommen sie meistens dann doch in einem Block an, man sollte sich aber nicht darauf verlassen, da nicht spezifiziert. Was heute noch getestet funktioniert kann dann theoretisch auch nach einem Firmwareupdate/Win-Update nicht mehr funktionieren.

Die richtige Vorgehensweise wäre also die einkommenden Daten nicht als Pakete zu verstehen (was sie nicht sind), sondern als Bytestrom und die Befehle/Blöcke aus den eingehenden Daten zu rekonstruieren. Da fragt sich halt, ob das Protokoll das her gibt, sonst muss man doch übers Timing gehen.
PeterS hat geschrieben: Di 31. Dez 2024, 10:37 Zum Verständnis: in diesem Hersteller-spezifischen Protokoll
fängt ein Datenpaket mit $32 an und endet mit $34.
Das ist ja schonmal ein guter Anfang, die Paketanfänge und -enden sind also markiert. Problem dabei ist, dass ja auch Daten mit den gleichen Werten innerhalb des Pakets sein können. Gibt es evtl. eine Längenangabe in dem Paket, z.B. direkt nach dem $32? Dann wäre eine Paketerkennung möglich und dein Programm würde mit allen handelsüblichen Konvertern funktionieren.

Zur Not könnte man auch bei offensichtlich unkompletten Daten den nächsten/die nächsten Blöcke mitnehmen, solange sie innerhalb einer gewissen Zeit eintreffen.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6762
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von af0815 »

Man darf bei einer seriellen Schnittstelle egal ob virtuell oder physisch nicht erwarten das die Bytes immer komplett hereinkommen. Mann muss nur dedektieren wann die Kommunikation tot zu sein scheint. Deswegen gibt es die verschiedenen Timeouts.

Wenn ich weis, mit was di kommunikation anfängt und mit was die endet, so ist es einfach. Wenn der Start kommt fange ich an die Teile zusammen zu sammeln bis ich das Ende erkenne - oder das/ein Timeout zuschlägt. Wenn ich rechtzeitig das Ende erkenne, so nehme ich nur was zwischen Start und Ende liegt. Konnt das Timeout, so schmeisse ich alles weg - weil die Daten unbrauchbar sind.

Was man nie erwarten darf - das die Daten auf einmal daher kommen. Warum nicht. Bei der Hardware gab es einen Puffer, war der (fast) voll, so wurde die bisherigen Daten einfach geliefert, auch wenn das Ende der Daten (meistens mit CR oder CRLF terminiert) noch nicht erreicht war. Hat man das nicht beachtet, so hat man nie die Daten richtig lesen können. Auch bei der virtuellen Übertragung kann es vorkommen, das entweder das Paket zu groß wird und somit in Teilen ausgeliefert wird oder ein Übertragungstimeout sagt raus mit den Daten, obwohl die Daten noch geliefert werden. Bei UDP ist das noch lustiger, da die Pakete ja nicht unbedingt in der Reihenfolge garantiert werden, zum Unterschied zu TCP, wo die Reihenfolge über das Protokoll auch festgelegt ist bzw. sich der IP Stack sich um die Reihenfolge kümmern muss.

Ein gutes (manchmal auch negatives) Beispiel können Handscanner sein, die einfach jeweils nach 16 Zeichen eine Übertragung auslösen. Ist der Barcode mit Terminierung unter 16 Zeichen , bekommt man alles auf einmal. Liest man einen Barcode der zum Beispiel 20 Zeichen hat, so bekommt man 2 Übertragungen, die man zusammensetzen muß. Bertrachte ich nur die erste Übertragung, so fehlt mir das Ende Kennzeichen (zB. CR). Wenn ich dann deswegen das Paket weg schmeisse, weil kein gültiges Ende das ist, so habe ich dann im 2ten Paket nur 4 Zeichen und das Ende Kennzeichen. Da wird es jetzt heikel, weil das zweite Paket (ohne dem ersten) ja auch nicht richtig ist. Konklusion, die Kommunikation funktioniert nicht, weil der Programmierer das nicht verstanden hat :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

kupferstecher hat geschrieben: Fr 3. Jan 2025, 17:47 Bei einer seriellen Schnittstelle gibt es keine Pakete in dem Sinne. Die Bytes werden der Reihe nach ausgegeben und trudeln nacheinander ein. Paketgrenzen auf Schnittstellenebene gibt es nicht, kann der Empfänger also auch nicht detektieren.
In meinem Fall liegst Du falsch.

Das Hersteller-spezifische propietäre Protokoll, das ich mitlese,
verschickt Daten-Pakete variabler Länge.
Also mindestens [$32 + HEADER + 1 value + CRC16 +$34].

Daher gibt es hier Paketgrenzen, die ich ganz klar abgrenzen kann. Siehe hier:
Screenshot (49).png
Screenshot (49).png (195.75 KiB) 2497 mal betrachtet

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

kupferstecher hat geschrieben: Fr 3. Jan 2025, 17:47 Gibt es evtl. eine Längenangabe in dem Paket, z.B. direkt nach dem $32?
Dann wäre eine Paketerkennung möglich und dein Programm würde mit allen handelsüblichen Konvertern funktionieren.
"Byte 2" und "3" sind Swapped(word) = Länge Datenpaket (excl. CRC16 und Ende-Byte).
Wobei ein Paket nie größer ist als $00FF

Alles schon längst gelöst und geklärt und in Code gegossen.

Das hier ..

Code: Alles auswählen

    ReadIntervalTimeout         := 10;       // @ 9600 Bits / sec = 1200 byte / sec
scheint in meinem Fall zu funktionieren.

Da die Daten-Pakete aber variable Länge haben, kann ich mit den weiteren Parametern in TCOMMTIMEOUTS nichts anfangen.
Dafür müßte man - soweit ich das bis jetzt verstanden habe - wissen, wie groß das nächste Datenpaket ist.
Ich lese nur mit, fordere also keine Daten an. So kann ich also nicht wissen,
was für Daten mit welcher Paketlänge als nächstes kommen.
Zuletzt geändert von PeterS am Sa 4. Jan 2025, 11:47, insgesamt 1-mal geändert.

Benutzeravatar
kupferstecher
Beiträge: 431
Registriert: Do 17. Nov 2016, 11:52

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von kupferstecher »

PeterS hat geschrieben: Sa 4. Jan 2025, 11:37
kupferstecher hat geschrieben: Fr 3. Jan 2025, 17:47 Bei einer seriellen Schnittstelle gibt es keine Pakete in dem Sinne.
In meinem Fall liegst Du falsch.
Ich spreche von der Seriellen Schnittstelle und auf Schnittstellenenbene gibt es keine Pakete/Blöcke. Deine Blöcke tauchen erst auf Protokollebene auf, du versuchst aber die Blöcke auf Schnittstellenebene zu erkennen, was eben regelmäßig schief geht. Auch wenn du eine Schnittstellene/ einen Treiber gefunden hast, bei dem das einigermaßen passt. Aber ja auch nur einigermaßen, sonst würdest du nicht versuchen an irgendwelchen intenen Timeouts rumzuschrauben.
PeterS hat geschrieben: Sa 4. Jan 2025, 11:45 "Byte 2" und "3" [...] = Länge Datenpaket
Dann bringt ja das Protokoll alles mit, was nötig ist.

Die richtige Vorgehensweise wäre also den Empfangspuffer abzurufen und die Bytes darin nach dem Anfangsstempel abzusuchen, wenn ein solcher gefunden wurde warten bis die beiden Längenbytes eingetroffen sind, diese Auswerten und solange warten bis die dort angegebe Anzahl Bytes eingetroffen sind, das nächste Byte muss dann ein Endestempel sein. Ist das der Fall, ist dein Paket komplett und du kannst es verarbeiten. Ist es kein Endestempel, dann war evtl. der Anfangsstempel kein solcher, sondern nur ein Datenbyte mit zufällig gleichem Wert. Dann gehst du im Datenstrom zurück zum "falschen" Anfangsstempel und suchst den darauffolgenden nächsten Anfangsstempel. Dann wiederholt sich das Spiel von oben.

Ist wohl vergebliche Liebesmühe..

MmVisual
Beiträge: 1579
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von MmVisual »

Fixiere dich nicht auf die 10ms als Paketgrenze, sonder betrachte die Daten als unendlichen Datenstrom und analysiere nur den Datenstrom, unabhängig von der Zeit.
Die 10ms funktionieren nur in der Theorie (in deinem speziellen Fall) gut, in der Praxis hat man als Umgebung Windows, das nicht Echtzeittauglich ist und dazu noch Netzwerke, das ebenfalls nichts mit Echtzeit am Hut hat. Und der Adapter sammelt ebenfalls Daten, wie er gerade zufällig programmiert ist.
Von daher ist der Timeout völlig egal. Auf 10ms ist Windows niemals stabil, man hat zum Teil schon Schwierigkeiten bei 1s je nach Auslastung.

Ich hatte mal Daten zu analysieren, bei dem das Startzeichen auch in den Datenzeichen vorkam, das war dann schon ziemlich ecklig, da ich bei jedem erkannten Start die Daten bis zum Ende auswerten musste und hinterher entscheiden ob das jetzt ein Start war oder Daten und so konnte ich die Daten erst nach der Decodierung aus dem Empfangsbuffer löschen.

Schließlich hat eine serielle Verbindung in sich keine Datensicherheit, den Stecker kann man zu jedem X beliebigen Zeitpunkt aus/ein stecken. Auch können einzelne Bytes mal verloren gehen, z.B. bei Wackelkontakt. Das muss alles die Software errechnen und darauf reagieren. Mit der CRC geht das in deinem Fall zum Glück sehr einfach. Daher ist nur wichtig dass man die Datenalasyse nicht anhand von irgend einer Zeit abhängig macht (außer Timeout wenn keine Daten mehr kommen, z.B. Kabel wird gerade ausgesteckt).

Decodierung serieller Daten ist daher immer ein gewisser Aufwand.

Wie ich so etwas löse:
Ich verwende daher am liebsten CAN Bus Systeme, da macht dies der CAN Controller in der Hardware. Und zum Lazarus geht es mit dem PCAN-USB-FD Adapter, die Firma hat eine sehr gut beschriebene API und Demo Code. Abgesehen davon gibt es dann keine Adapter Probleme mehr, da man nur noch Adapter dieser einen Firma unterstützt.
EleLa - Elektronik Lagerverwaltung - www.elela.de

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

kupferstecher hat geschrieben: Sa 4. Jan 2025, 12:57 Ich spreche von der Seriellen Schnittstelle und auf Schnittstellenenbene gibt es keine Pakete/Blöcke. Deine Blöcke tauchen erst auf Protokollebene auf, du versuchst aber die Blöcke auf Schnittstellenebene zu erkennen, was eben regelmäßig schief geht.
Mit SdpoSerial / Synaser geht das tatsächlich schief.

Code: Alles auswählen

[2025-01-05, 06:06:23:691] FD
[2025-01-05, 06:06:23:705] FD FD 7D FF 32 00 3D
[2025-01-05, 06:06:23:709] 10 01 00 B0 01 FF
[2025-01-05, 06:06:23:713] C0 14 2A
[2025-01-05, 06:06:23:716] 0D 82 3F
[2025-01-05, 06:06:23:719] 00 C8 80
[2025-01-05, 06:06:23:723] 8D 00 80
[2025-01-05, 06:06:23:726] 01 02 82
[2025-01-05, 06:06:23:730] 48 00 FF
[2025-01-05, 06:06:23:733] 82 49 00
[2025-01-05, 06:06:23:737] FF 80 03
[2025-01-05, 06:06:23:741] 02 84 04
[2025-01-05, 06:06:23:745] 04 80 82
[2025-01-05, 06:06:23:748] 02 82 44
[2025-01-05, 06:06:23:752] 00 00 82
[2025-01-05, 06:06:23:757] 47 00 FF
[2025-01-05, 06:06:23:762] 80 61 FF 80 62 00
[2025-01-05, 06:06:23:766] 80 75 FF
[2025-01-05, 06:06:23:771] 80 5E 01
[2025-01-05, 06:06:23:778] 77 62 34
[2025-01-05, 06:06:23:790] FD BD
[2025-01-05, 06:06:23:795] FD
[2025-01-05, 06:06:23:801] FD 32 00

PeterS
Beiträge: 161
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 3.8
CPU-Target: win32

Re: SerialPort - TCommTimeouts - was einstellen ?

Beitrag von PeterS »

MmVisual hat geschrieben: Sa 4. Jan 2025, 13:08 Fixiere dich nicht auf die 10ms als Paketgrenze, sonder betrachte die Daten als unendlichen Datenstrom[/b] und analysiere nur den Datenstrom, unabhängig von der Zeit. Die 10ms funktionieren nur in der Theorie (in deinem speziellen Fall) gut, ..
Schau Dir bitte den Screenshot unten an. Und die Zeitabstände, die dort in ms stehen.
(ab #7, davor ist noch holprig, gerade erst gestartet ..)

Das ist - im vorliegenden Fall - kein "unendlicher Datenstrom" einzelner Bytes.

Screenshot (49).png
Screenshot (49).png (195.75 KiB) 2454 mal betrachtet
.
Ich werde die für meine Zwecke geschriebene Serial Port Komponente
mal in das Synaser Test-Programm einbauen, und an ein paar User verschicken.
Dann schauen wir mal ob das hier "nur in der Theorie" funktioniert:

https://forum.lazarus.freepascal.org/in ... #msg538993

Antworten