Hallo , wie kann ich den RX Buffer von einem ESP32 erhöhen ?
Hintergrund , mit dem esp32 steuere ich über eine RS232 Schnittstelle eine Modellbahnsteuerung
( Tams Mastercontrol ) . Das funktioniert soweit ganz gut , außer das Auslesen dieser Steuerung .
Die Steuerung legt eine Lokdatenbank mit folgenden Daten an Adresse,Decoderformat,Geschwindigkeitsstufen und den Namen der Lok.
Mit dem Befehl "LOCDUMP" , den ich mit dem esp32 an die Steuerung sende , wird die Lokdatenbank übertragen , allerdings empfängt der esp32 nur 256 ( das entspricht in etwa 20 Lokdatensätzen ) , der Rest geht verloren .
Vielen Dank im vorraus
Damit liest Du 1 Byte und was machst Du mit dem Rest? Zeige doch mal den signifikanten Teil des Sketches. Wo sollen die gelesenen Bytes eigentlich hin?
Das ist richtig , hier lese ich nur ein Byte , nachdem ich nach Stunden der Verzweifelung festgestellt hatte das nach 256 Zeichen Schluß ist ,
habe ich das ausprobiert und bestätigt bekommen ,also ohne jegliche Auswertung,
int z= 0;
Serial2.write("X"); // Befehl zum laden der Datenbank
Serial2.write("LOCDUMP");
Serial2.write(13);
Ach so , anschließend hatte ich das mit einem Nano ausprobiert , hier war nach 64 Zeichen Schluß
Ja, so groß ist der serielle Buffer.
Du machst was falsch!
z.B. solltest du nicht versuchen mehr zu erwarten, als im Buffer stehen kann.
z.B. abwendbar durch Wiederholtes lesen.
Serial2.available() sagt dir wieviel im Buffer stehen.
nach Stunden der Verzweifelung
Der Kopf ist rund,
damit das Denken die Richtung wechseln kann
Dafür ist es jetzt genau die richtige Zeit.
Du willst WARTEN, Das ist aber genau der falsche Weg.
Du SOLLST (und Du willst) IMMER Das auslesen, WAS GERADE DA ist.
Dein Freund hat den ganzen Kofferraum voller Äpfel, Dir Er Dir übergeben möchte - leider kann Er aber immer nur einen Apfel nach dem Anderen transportieren.
Du hast im Lagerraum ein Gestell, wo Du immer 25 Äpfel 'am Stück' einlagern kannst.
Als Schnittstelle zwischen Euch gibt's ein Körbchen, wo die Äpfel liegen bleiben und keine Druckstellen bekommen.
Dieses Körbchen ist aber wesentlich kleiner, als der Kofferraum und auch als Deine Ablage.
Wenn jetzt Dein Freund anfängt, die Äpfel in das Körbchen zu legen, passt Er auf, daß das Körbchen nicht überfüllt wird - wenn Das droht, hört Er auf und geht Fußball gucken und Bier trinken - Abbruch vom Sender.
Du möchtest Deine Ablagen füllen - das geht aber nicht 'in einem Zug', weil Du dort gar nicht so viele Äpfel finden kannst - das Körbchen ist zu klein.
Also wirst Du, wenn mehr als ein Apfel da ist, Einen Apfel entnehmen und einsortieren.
Dein Weg ist außerdem kürzer, weshalb Du auch noch Zeit für andere Dinge hast - ein Kaffee zwischendurch, zumindest einen Schluck, ist drin.
Das machst Du, bis Deine Äpfel in ausreichender Anzahl einsortiert sind.
Wenn keine Äpfel da sind, ist Zeit für Kaffee.
Solange Dein Freund (ab und zu) neue Äpfel liefert, bekommst Du hiermit Deine Ablagen voll, wenn's genug geworden sind, kannst Du Diese verarbeiten (und den Buffer wieder leeren).
... und wenn Sie nicht gestorben sind, so gibt's auch Morgen noch Äpfel ...
MfG
PS: Glaube mir, wenn combie Dir sagt, daß Das Mist ist - wird's zumindest stark verbesserungswürdig sein.
Ggf. sogar in die von Ihm angedeutete Richtung ... munkelt man hier im Forum.
ob man while oder if nimmt ist erstmal egal. Es kommt darauf wie der restliche Code aussieht.
while (Serial2.available() > 0)
if (Serial2.available() > 0)
Mit while alleine kann der Buffer jedenfalls unter Garantie nicht überlaufen. Denn er bleibt ja solange drin bis er leer ist. Überlauf unmöglich. Ich habe aber unzählige Varianten im Kopf wodurch man dennoch Buffer Probleme bekommen kann. Das hängt alles vom restlichen Code ab. Gewöhnlich nimmt man die zweite if Variante, dann wird in jedem nicht blockierenden loop Durchlauf ein Zeichen eingelesen. Mit gefüllten Buffer und while blockiert man seine loop solange der Buffer ausgelesen wird. Man muss wissen was wichtiger ist. loop oder Buffer. Hängt auch wieder vom restlichen Code ab.
Edit:
Wenn die Daten nur mit 9600 Baud ankommen, dann hast du pro Zeichen einlesen viel Zeit, deswegen vermute ich, dass auch deine while nur mit Einzelzeichen einlesen beschäftigt ist. Wenn damit Zeichen verloren gehen, dann vermute ich weiter das deine loop blockiert bzw. zu langsam ist. Wodurch auch immer.
PS: Glaube mir, wenn combie Dir sagt, daß Das Mist ist - wird's zumindest stark verbesserungswürdig sein.
Ggf. sogar in die von Ihm angedeutete Richtung ... munkelt man hier im Forum.
Danke für die Blumen und dein Zutrauen!
Hier mal ein Fragment, ohne die Schleife.
(und auch ohne if :o )
Leider kann es es nicht wirklich testen, da die Anzahl meiner Lokomotiven arg begrenzt ist.
Es ist ein primitiver Parser, welcher zumindest schon mal Zeilen separieren kann und das Ende eines Datenblockes erkennt.
vom return kommst du weg wenn du statt 2 switch-case nur ein switch-case machst. Also die beiden cases Ende und Zeile mit in obiges einbaust. Dann bleiben obige Zustandsänderungen unter sich. Weil aktuell änderst du den switch case Zustand außerhalb eines switch cases. Das soll man nicht machen. Wenn man größeren Code hat sucht man sich tot wo die Änderungen vorgenommen werden und übersieht möglicherweise etwas.
nicht getestet ungefähr so, dann mußte auch keine wilden Sprünge mit goto machen ...
Rebessa:
Die Baudrate beträgt 1200 , langsamer geht nicht
Mach dir auch mal klar was das bedeutet. Ein Zeichen braucht 1 / 1200 * 10 Sekunden. 10 wegen 1 Startbit, 8 Datenbits, 1 Stopbit. Also insgesamt etwa 8,3ms pro Zeichen. Das ist extrem viel für einen µC. Deshalb kann man da nicht alles in einer Schleife einlesen.
Das gilt aber auch für viel schnellere Baudraten. Es sei der µC ist mal einige Zeit mit etwas beschäftigt wirst du in der Regel schneller als die serielle Schnittstelle sein. Deshalb immer nachsehen ob Daten da ist, wenn ja verarbeiten und wenn nein was anderes tun (oder nichts)
wenn du statt 2 switch-case nur ein switch-case machst
Naja, so hast du Eingabe - Verarbeitung - Ausgabe wieder weitreichend verschmolzen, welche ich eigentlich möglichst trennen wollte.
Klar, kann man das machen, verstößt aber, meiner Ansicht nach, gegen das Prinzip: Jede Funktion macht nur ein Ding.
Dann bleiben obige Zustandsänderungen unter sich. Weil aktuell änderst du den switch case Zustand außerhalb eines switch cases. Das soll man nicht machen.