RX Buffer von esp32 verändern?

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?

Gruß Tommy

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);

while (Serial2.available() > 0) {
incomingByte = Serial2.read();
Serial.print("Zähler ");
Serial.print(z);
Serial.print(" - byte: ");
Serial.println(incomingByte);
z++;
}

Ach so , anschließend hatte ich das mit einem Nano ausprobiert , hier war nach 64 Zeichen Schluß

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.

Jetzt bin ich etwas überfordert ... Die Loksteuerung schiebt ihre Daten in einem durch , da habe ich keinen Einfluß drauf .

Die Loksteuerung schiebt ihre Daten in einem durch , da habe ich keinen Einfluß drauf

Ich spreche vom lesen!

Buffer sind immer begrenzt!
Ändere deine Denke, so dass du damit leben kannst.

Deswegen war ja die Frage , ob und wie man den Buffer ändern kann ?
Wenn das irgendwie möglich ist , möchte ich das gerne nutzen

Und ich sage:

Der Kopf ist rund,
damit das Denken die Richtung wechseln kann

Erst wenn du das akzeptierst, wirst du zu einer tragfähigen Lösung kommen!
Tiefgreifende/Wertvolle Erkenntnisse erwarten dich auf dem Weg.

Tipp:

while (Serial2.available() > 0)
Die Schleife muss da weg!
Nicht der Buffer größer, sondern weg mit der Schleife.

Das hilft mir jetzt nicht wirklich weiter

Hi

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.

Hallo,

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.

Ja, sicherlich noch verbesserungswürdig.

HardwareSerial Serial2(2);

enum ParserResult {Running = 0, Zeile, Ende};

ParserResult parser(Stream &stream,String &buffer)
{
  const String ende("*END*");
  const char endline = '\r';
  int zeichen = stream.read();
  switch(zeichen)
  {
    case -1 : break; // Buffer der Datenquelle leer

    case endline :  return buffer == ende ? Ende : Zeile;

    default: buffer += char(zeichen);                    
  }
  return Running;
}



String zeile;

void setup() 
{
 // while(not Serial); 
 // while(not Serial2);
 
 Serial.begin(9600); // Debug
 Serial.println("Start");
 zeile = "";
 
 Serial2.begin(1200); // Steuerung
 Serial2.print("LOCDUMP\r");
}

void loop() 
{
  switch(parser(Serial2,zeile))
  {
    case Ende:  Serial.println("End Of Data"); zeile = ""; break;
    case Zeile: Serial.print("Lok: ");Serial.println(zeile); zeile = ""; break;
    default: ;
  }

}

Freude , das klappt ... besten Dank ....

Also Äpfel hin oder her , meine Fähigkeiten in Sachen Programmierung sind da doch eher eingeschränkt

combie:
Hier mal ein Fragment, ohne die Schleife.
(und auch ohne if :o )

doch mit if, auch wenn es im switch case versteckt ist. Auf jeden Fall ohne goto. Aber das war eine andere Baustelle ... :grin:

Auf jeden Fall ohne goto.

:fearful: Nur ein Zufall! :fearful:
Der nächste Parser kann wieder "mit" sein.
Denn mir gefällt das Return da mitten in dem switch gar nicht.
:smiling_imp: :smiling_imp: :smiling_imp:

Hallo,

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 ... :smiling_imp:

HardwareSerial Serial2(2);

enum ParserResult {Zeile, Ende};

ParserResult parser(Stream &stream,String &buffer)
{
  const String ende("*END*");
  const char endline = '\r';
  int zeichen = stream.read();
  
  switch(zeichen)
  {
    case -1:      break; // Buffer der Datenquelle leer

    case endline: ende ? Ende : Zeile;
                  break;
    
    case Ende:  Serial.println("End Of Data");
                zeile = "";
                break;
    
    case Zeile: Serial.print("Lok: ");
                Serial.println(zeile);
                zeile = "";
                break;
    
    default: buffer += char(zeichen);                   
  }
  
}



String zeile;

void setup()
{
 // while(not Serial);
 // while(not Serial2);
 
 Serial.begin(9600); // Debug
 Serial.println("Start");
 zeile = "";
 
 Serial2.begin(1200); // Steuerung
 Serial2.print("LOCDUMP\r");
}

void loop()
{
  parser(Serial2,zeile);
  
}

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.

Das verstehe ich nun gar nicht....
Echt nicht..

Hallo,

Verschmelzung, okay, ist eher ungünstig, wenn die Funktion noch überschaubar bleibt könnte ich damit leben.

Wegen Zustandsänderung an anderer Stelle. Du hast zweimal switch case. Die im zweiten switch benötigten Zustände (Ende, Zeile) werden im ersten switch geändert. Also außerhalb vom zweiten Switch in dem sie benötigt werden.

switch 1:

switch(zeichen)
{
  case -1 : break; // Buffer der Datenquelle leer

  case endline :  return buffer == ende ? Ende : Zeile;

  default: buffer += char(zeichen);                   
}

switch 2:

switch(parser(Serial2,zeile))
{
  case Ende:  Serial.println("End Of Data"); zeile = ""; break;
  case Zeile: Serial.print("Lok: ");Serial.println(zeile); zeile = ""; break;
  default: ;
}

Wegen Zustandsänderung an anderer Stelle. Du hast zweimal switch case. Die im zweiten switch benötigten Zustände (Ende, Zeile) werden im ersten switch geändert. Also außerhalb vom zweiten Switch in dem sie benötigt werden.

Ja, das ist so!
Auch wenn dir dieser Rückgabe Wert komisch erscheint .....

Der Parser sendet der aufrufenden Funktion eine Statusmeldung.
Die aufrufende Funktion kann dann angemessen darauf reagieren.
Mir scheint, dass damit der Sinn und Zweck eines Rückgabewertes, einer Funktion, voll und ganz erfüllt wird.

Hmmm...
"Verbesserungswürdig", hatte ich schon gesagt....

Viellicht bist du auch so überrascht, weil ich das Ding nicht in ein OOP Mäntelchen gesteckt habe. Denn dann würde es vermutlich anders aussehen. Also "gewöhnlicher", eher meinem normalen Stil entsprechend.