Sämtliche Zeichen eines Arrays um eine Stelle verschieben

Hallo,

da ich mir gerne einen FIFO-Buffer selber erstellen möchte, suche ich eine Möglichkeit um alle Zeichen eines Arrays (bis auf die "Ende-NULL" um eine Stelle nach links zu schieben. Das Zeichen an der ersten Stelle soll somit das Array "verlassen". Die Stelle vor der "Ende-NULL" würde ich im nächsten Programmierschritt durch ein "frisches" Zeichen füllen.

Wie macht man das am elegantesten?

Gruß Chris

Am schnellsten ist daß Du nicht die Elemente des Array verschiebst sondern einfach den die Nullstelle des Index definierst und dort das nächste Zeichen hinschreibst. Nullindex+1 fängt das Array an und geht bis Nullindex. Wenn der Index = Größe des Array-1 ist dann get der Index bei 0 weiter.
Grüße Uwe

Hallo,

dann würde das Array doch aber so befüllt werden..

123
456
789

..und nicht so..

123
234
345

..was für mich ein Problem wäre, da ich z.B. dann ein Problem hätte, wenn ich nach einer "Textpassage" innerhalb des Arrays suchen wollen würde und sich diese "Textpassage" dann an Position 3 und 4 befinden würde.

Mein Plan ist es, seriell eingehende Zeichen kontinuierlich zu überprüfen.

Würde ich dabei einfach nur "im Kreis" in ein Array schreiben, könnte ich zusammenhängende Textpassagen u.U. nicht erkennen.

Den ersten Satz von Dir habe ich aber glaub grammatikalisch irgendwie nicht so ganz verstanden.

Gruß Chris

Alle Zähler beginen mit 0. Das Array hat zB 9 Elemente.

Im Array steht zB
123456789 und Anfangsposition 0 // Abfangssituation bei gefülltem Array
nächtes Zeichen A:
A23456789 und Anfangsposition 1
nächstes Zeichen B:
AB3456789 und Anfangsposition 2

Wenn Du einen Text in Array suchst zB "45"
dann findest Du ihn in
AB3456789, Anfangsposition 2 (was dem Array 3456789AB entspricht) an der Stelle 3 dann subtrahierst Du davon die Anfangsposition und erhälst die richtige Position 1.
Hoffe ich habe mich jetzt verständlicher ausgedrückt.

Die Alternative
123456789 ->23456789x -> 23456789A benötigt n Verschiebungen und das ist langsam.

Grüße Uwe

Ich blick es nicht.

Vielleicht sollte ich das Ganze doch ehr mit einem Pointer aufbauen.

Trotzdem vielen Dank!

Gruß Chris

Hallo,

so, nun bin ich (gedanklich) ein gutes Stückchen weiter.

Mit diesem Code bin ich bereits in der Lage ein Array immer wieder mit Zeichen zu befüllen:

char fifo[7] = "______";                                          // FIFO-Array (Platz für 6 Zeichen und eine Ende-Null)
char zeichen = 0;                                                 // Aktuelles Zeichen
int index = 0;                                                    // Indexzähler/Speicherstelle

void setup()
{
  Serial.begin(9600);
}

void loop()
{

while (Serial.available() > 0 && index < 7)
{
  zeichen=Serial.read();
  fifo[index]=zeichen;
  index++;
  if(index == 6)
  {
    index=0;
  }
  Serial.println(fifo);
}

}

Nun möchte ich den geschriebenen Inhalt sinnvoll weiterverarbeiten.

Die habe ich mir so vorgestellt:

Wenn z.B. auf Index "3" geschrieben wurde, sollen Zeiger (oder evtl. andere Dinge, welche ich aufgrund von Unkenntnis noch nicht kenne) auf folgende Indexes (heisst bestimmt anders) verweisen und ein "Zielarray" speisen:

4 5 0 1 2 3

Ziel soll ein Array sein, welches immer von rechts die "neuesten" Zeichen bekommt.

So in etwa in der Theorie:

Ich würde dann dieses Array von rechts auf bestimmt "Bedinungen" hin überprüfen (z.B. if(rechts im Array steht "OK\r) then "Aktion".

Mein Problem ist nun das Erstellen der Zeiger.

Hoffe, ich konnte meinen Ansatz genau genug beschildern.

Gruß Chris

PS: Naja- so hab ich es vorerst mal gelöst, hab aber das starke Gefühl, dass das nicht die optimale Lösung sein kann:

char fifo[7] = "______";                                          // FIFO-Array (Platz für 6 Zeichen und eine Ende-Null)
char zeichen = 0;                                                 // Aktuelles Zeichen
int index = 0;                                                    // Indexzähler/Speicherstelle

char ziel_array[7] = "______";

void setup()
{
  Serial.begin(9600);
}

void loop()
{

while (Serial.available() > 0 && index < 7)
{
  zeichen=Serial.read();
  fifo[index]=zeichen;
  index++;
  if(index == 1)
  {
    ziel_array[0]=fifo[1];
    ziel_array[1]=fifo[2];
    ziel_array[2]=fifo[3];
    ziel_array[3]=fifo[4];
    ziel_array[4]=fifo[5];
    ziel_array[5]=fifo[0];
  }
  if(index == 2)
  {
    ziel_array[0]=fifo[2];
    ziel_array[1]=fifo[3];
    ziel_array[2]=fifo[4];
    ziel_array[3]=fifo[5];
    ziel_array[4]=fifo[0];
    ziel_array[5]=fifo[1];
  }
  if(index == 3)
  {
    ziel_array[0]=fifo[3];
    ziel_array[1]=fifo[4];
    ziel_array[2]=fifo[5];
    ziel_array[3]=fifo[0];
    ziel_array[4]=fifo[1];
    ziel_array[5]=fifo[2];
  }
  if(index == 4)
  {
    ziel_array[0]=fifo[4];
    ziel_array[1]=fifo[5];
    ziel_array[2]=fifo[0];
    ziel_array[3]=fifo[1];
    ziel_array[4]=fifo[2];
    ziel_array[5]=fifo[3];
  }
  if(index == 5)
  {
    ziel_array[0]=fifo[5];
    ziel_array[1]=fifo[0];
    ziel_array[2]=fifo[1];
    ziel_array[3]=fifo[2];
    ziel_array[4]=fifo[3];
    ziel_array[5]=fifo[4];
  }
  if(index == 6)
  {
    ziel_array[0]=fifo[0];
    ziel_array[1]=fifo[1];
    ziel_array[2]=fifo[2];
    ziel_array[3]=fifo[3];
    ziel_array[4]=fifo[4];
    ziel_array[5]=fifo[5];
  }
  if(index == 6)
  {
    index=0;
  }
  Serial.print(fifo);
  Serial.print("   ");
  Serial.print(ziel_array);
  Serial.print("   Index:");
  Serial.print(index);
  Serial.println();
}

}

Chris72622:
PS: Naja- so hab ich es vorerst mal gelöst, hab aber das starke Gefühl, dass das nicht die optimale Lösung sein kann:

Besonders dann nicht, wenn der Zeichenpuffer vielleicht auch mal 10, 50, 100 oder 200 Zeichen groß sein soll.
:wink:

Also mit einem FIFO-Ringpuffer funktioniert es so:
Du hast den Puffer selbst, einen Lesezeiger und einen Schreibzeiger

Der Lesezeiger und der Schreibzeiger können dabei Pointer (Größe eines Pointers auf Arduino: 2 Bytes) auf Speicherstellen im Array sein. Oder wenn der Ringpuffer nur maximal 255 Zeichen enthält, können es einfach Indexangaben (1 Byte) für das Array sein. Um möglichst speichersparend zu programmieren also einen Leseindex und einen Schreibindex als "byte".

Zu Anfang sind Leseindex und Schreibindex gleich null, sie verweisen auf array[0], und immer wenn Leseindex und Schreibindex gleich sind, bedeutet das so viel: Puffer ist leer, es kann nichts gelesen werden.

Zum Füllen des Puffers hast du ja schon herausgefunden wie es geht: Du füllst das nächste Zeichen an der aktuellen Indexstelle ein (Dein "index" ist also der Schreibindex) und schaltest den Schreibindex um eins weiter. Am Ende des Puffers springt der Schreibindex wieder auf null.

Für eine ganz billige Lösung brauchst Du jetzt nur noch einen Leseindex, der genau so implementiert ist. Wenn Leseindex==Schreibindex ist der Puffer leer, dann nichts lesen. Ansonsten nach dem Lesen eines Zeichens immer den Leseindex um eins weitersetzen, am Ende wieder auf 0, und gelesen werden kann, bis Leseindex==Schreibindex erfüllt ist.

Knifflig wird es mit so einem Puffer nur, wenn er überlaufen kann, d.h. wenn mehr Zeichen in den Puffer geschrieben werden als es seiner Größe entspricht, bevor er ausgelesen wird.

Die einfachste und wenig sinnvolle Möglichkeit ist: Beim Overflow wird der Schreibindex weitergeschaltet bis auf den Leseindex. Dann ist der Puffer logisch "leer", kann nicht mehr ausgelesen werden, die im Puffer enthaltenen Zeichen sind verloren.

Am zweiteinfachsten zu implementieren und deutlich sinnvoller wäre folgende Overflow-Logik: Wenn ein Zeichen den Puffer vollgeschrieben hat und das Versetzen des Schreibzeigers zu der Bedingung Leseindex==Schreibindex führen würde, dann den Schreibindex NICHT versetzen. So bleibt dann die geschriebene Zeichenzahl im Puffer zwar erhalten (und kann ausgelesen werden), aber der nächste Schreibvorgang führt dazu, dass das zuletzt geschriebene Zeichen wieder überschrieben wird (d.h. es geht ein Zeichen verloren, jedesmal wenn ein Zeichen in einen vollen Puffer geschrieben werden soll).

Falls Du Fragen zur Realisierung hast, kann ich ggf. auch ein paar Codeschnipsel zu einem FIFO-Ringpuffer raussuchen.

Oh Gott, bitte ja!!

Die Suche im Interent macht mich echt noch fertig grad.

Gruß Chris

Chris72622:
Oh Gott, bitte ja!!

Anbei mal ein paar Deklarationen und Funktionen zur Verwaltung eines FIFO-Ringpuffers.

#define FIFOSIZE 25
char fifoBuf[FIFOSIZE]; // ring buffer
byte fifoReadIndex,fifoWriteIndex;  // read and write index into ring buffer

void fifoWrite(char c)
// write char into buffer
{
  fifoBuf[fifoWriteIndex]=c; // store the char
  fifoWriteIndex++;  // advance write pointer in ringbuffer
  if (fifoWriteIndex>=FIFOSIZE) fifoWriteIndex=0; // ring buffer is at its end
}  

char fifoRead()
// read char from buffer
// always check first if char is available with fifoAvailable()
// before reading the buffer using this function
{ 
  char c;
  c=fifoBuf[fifoReadIndex];
  fifoReadIndex++;
  if (fifoReadIndex>=FIFOSIZE) fifoReadIndex=0;
  return(c);
}  

boolean fifoAvailable()
// checks for available chars in buffer
// char is available for reading if (fifoReadIndex!=fifoWriteIndex)
{
  return (fifoReadIndex!=fifoWriteIndex);
}

Falls FIFOSIZE über 255 groß werden soll, müssen fifoReadIndex,fifoWriteIndex als int statt byte deklariert werden.

Falls man andere Datentypen als char puffern möchte, ist dies durch kleinere Änderungen an fifoBuf, fifoWrite() und fifoRead() möglich.

Falls der FIFO-Puffer in Interrupt-Serviceroutinen verwendet werden soll, so dass er z.B. in einer ISR mit Daten gefüllt und in der loop ausgelesen werden soll, sind ebenfalls kleinere Änderungen notwendig.

Und immer dran denken: Die Funktion fifoRead() darf erst dann aufgerufen werden, nachdem mit fifoAvailable() geprüft wurde, ob tatsächlich etwas zum Auslesen im Puffer vorhanden ist!

Also zum Auslesen immer starten mit:
while (fifoAvailable()) ...
oder
if (fifoAvailable()) ...

Vielleicht kannst Du etwas damit anfangen.

1000 Dank!!

Werd mich durchwühlen.. :slight_smile:

Gruß Chris

Chris72622:
1000 Dank!!

Werd mich durchwühlen.. :slight_smile:

Dann mal zu! Zwei Anmerkungen zu meinem Ringpuffer-Code noch:

  1. Maximal speicherbare Zeichenzahl
    Die maximal speicherbare Zeichenzahl im Puffer ist "FIFOSIZE minus eins".
    Grund: Da der Zustand (fifoReadIndex==fifoWriteIndex) als "Ringspeicher ist leer" definiert ist, müssen sich bei einem Daten enthaltenden Ringpuffer der Readindex und Writeindex unterscheiden, daher kann der Puffer prinzipbedingt nicht bis aufs letzte Zeichen gefüllt werden, sondern ein Zeichen muß mindestens als Lücke zwischen ReadIndex und WriteIndex unbelegt bleiben. D.h. ein 25 Zeichen großer Puffer kann 25 verschiedene Zustände annehmen (leer sein oder 1-24 Zeichen enthalten), aber er kann keine 25 auslesbaren Zeichen enthalten.

  2. In dem geposteten Code habe ich nur die von mir weiter oben als am wenigsten sinnvolle Methode im Falle eines Pufferüberlaufs implementiert: Bei einem Puffer-Overrun überrennt der WriteIndex den ReadIndex und damit wird der Pufferspeicher leer und der gesamte Inhalt ist quasi gelöscht und kann nicht mehr ausgelesen werden.

Hier noch die bei Pufferüberläufen etwas sinnvollere Version für die Speicherfunktion zum Austauschen gegen die oben gepostete:

void fifoWrite(char c)
// write char into buffer
{
  fifoBuf[fifoWriteIndex]=c; // store the char
  c=fifoWriteIndex;  // store old WriteIndex
  fifoWriteIndex++;  // advance write pointer in ringbuffer
  if (fifoWriteIndex>=FIFOSIZE) fifoWriteIndex=0; // ring buffer is at its end
  if (fifoReadIndex==fifoWriteIndex) fifoWriteIndex=c; // restore old WriteIndex
}

Mit dieser Schreibfunktion für den Puffer geht beim Puffer-Overrun immer nur das letzten Zeichen im Puffer durch Überschreiben verloren, während der Anfang des Puffers erhalten und zum einwandfreien Auslesen verfügbar bleibt.

Vielen Dank für den Nachtrag.

Konnte beide Codes zusammenführen und bekomme nun "sichere" Werte aus der Funktion geliefert.

Muss ich die "Auswertung" des Arrays innerhalb einer Funktion vornehmen, oder kann man auch eine Funktion erstellen, die auf einmal gleich mehrere Zeichen übergibt; sprich eine array-Rückmeldungs-Funktion.

Leider habe ich ja noch immer das Problem, dass ich nicht nur einzelne Zeichen auswerten möchte, sondern (wie in dem unteren meiner beiden hochgeladenen Bilder zu sehen) eine Zeichenkette.

Ich könnte mir auch eine Überprüfung auf \r vorstellen. Hierfür müsste ich ja aber dann wiederum auf die zuvor in den Ringbuffer geschriebenen Zeichen zugreifen können.

Leider kann ich werder im Netz noch in meinen Büchern was dazu finden.

Bin über jede Hilfe dankbar!

Gruß Chris

Chris72622:
Leider habe ich ja noch immer das Problem, dass ich nicht nur einzelne Zeichen auswerten möchte, sondern (wie in dem unteren meiner beiden hochgeladenen Bilder zu sehen) eine Zeichenkette.

Ich könnte mir auch eine Überprüfung auf \r vorstellen. Hierfür müsste ich ja aber dann wiederum auf die zuvor in den Ringbuffer geschriebenen Zeichen zugreifen können.

So ein Ringspeicher-FIFO-Puffer ist eine reine Datenspeicherstruktur: Daten reinstopfen und Daten rausholen.

Die Verarbeitung müssen dann andere Routinen Deines Programms erledigen. Eine möglicherweise sinnvolle Erweiterung für den Ringpuffer, wenn Du bis zum Auftreten eines bestimmten Zeichens \r auslesen möchtest, jedoch ohne dieses Zeichen auszulesen, wäre eine "peek" Funktion für eine kurze Vorausschau des nächsten Zeichens im Puffer (oder ob das Zeichen überhaupt im Puffer verfügbar ist), jedoch OHNE das Zeichen dabei auszulesen. Das kann manchmal ganz praktisch sein.

Solche Peek-Funktion läßt sich ohne großen Aufwand realisieren.

Für das Auswerten von Daten im Puffer müßtest Du dann eine neue Funktion schreiben, die die Daten aus dem Puffer rauszieht und weiter verarbeitet. Was da am sinnvollsten ist, hängt ab, was da erkannt und weiter verarbeitet werden soll. Ob man z.B. regelrecht einen "Parser" schreiben muß, der Daten aufwändig analysiert. Oder ob man einfach nur einzelne Worte aus dem Ringpuffer rauszieht in ein Char-Array, auf das man dann z.B. Stringvergleiche und anderes anwenden kann.

Chris72622:
Leider habe ich ja noch immer das Problem, dass ich nicht nur einzelne Zeichen auswerten möchte, sondern (wie in dem unteren meiner beiden hochgeladenen Bilder zu sehen) eine Zeichenkette.

Und die Zeichenkette kommt von der seriellen Schnittstelle?

Dass ich hier in den letzten Wochen schon mehrfach "Kommando-Erkennungsparser für die serielle Kommunikation" gepostet habe, hast Du aber schon gesehen und konntest damit nichts anfangen?

Z.B. von mir in http://arduino.cc/forum/index.php/topic,136027.0.html
Reply #3 on: December 08, 2012, 04:33:25 PM »

Oder von mir zu einer noch spezielleren Auswertung in http://arduino.cc/forum/index.php/topic,137669.0.html
Reply #4 on: December 16, 2012, 07:58:37 PM

Da kommen die Daten über seriell rein und bestimmte "Kommandos" kann das Programm dann erkennen und darauf reagieren.

jurs:
Und die Zeichenkette kommt von der seriellen Schnittstelle?

Dass ich hier in den letzten Wochen schon mehrfach "Kommando-Erkennungsparser für die serielle Kommunikation" gepostet habe, hast Du aber schon gesehen und konntest damit nichts anfangen?

Ja, serieller Eingang.

Mich verwirrt, dass viele "Befehle" in einer Programmiersprache geschrieben sind, die ich nicht in Einklang bringen kann mit dem, was ich in den Büchern über reine Arduinoprogrammierung bisher gelernt habe (z.B. "memset" oder "strstr").

Das sich aus meiner Sicht bei Beiden von Dir verlinkten Codeschnipseln der Buffer innerhalb der setup loop() befindet, kann ich das Ganze nun leider nicht in Einklang mit bisher von Dir "vorgeschlagenen" Funktionsvariante bringen.

Da ich ohne delay() arbeiten möchte, da ich noch anderen Code abzuarbeiten habe, wäre mir die "Funktionsvariante" viel lieber, doch mit dem Umbauen haperts ganz gewaltig. :frowning:

Was "peek" ist, bin ich gerade am ergooglen. :slight_smile:

Ah- wenn ich es mit den "arduinoeigenen Befehlen" lösen wollenwürde, müsste ich vermutlich das hier nutzen, oder:

In meinem Fall würde es aureichen auf Zeichenfolgen zu prüfen (wie "CONNECT" bei dem Kollegen, bloß inkl. Leerzeichen- z.B. "Z 3 0 1").

Vielleicht kann mich ja das hier glücklich machen:

http://my.safaribooksonline.com/book/hobbies/9781449399368/serial-communications/receiving_multiple_text_fields_in_a_s

Das deutsche Buch liegt vor mir; von daher sollte der Knoten sich so langsam mal lösen.. :slight_smile:

Gruß Chris

Die ArduinoIDE benutzt den offiziellen AVR GCC Compiler von Atmel. Dieser hat den gesamten C bzw Großteil von C++ Befehlsatz / Bibiotheken und all diese Funktionen kannst Du verwenden.
Arduino erklärt nicht den gesamten Befehlsatz/ Funktionen.
Grüße Uwe

uwefed:
Arduino erklärt nicht den gesamten Befehlsatz/ Funktionen.

Danke. Das macht es am Anfang wirklich sehr schwierig, wenn man ausschließlich mit Arduino und passend darauf zugeschnittener Lektüre ins Thema Programmieren startet.

Gruß Chris

Chris72622:
Mich verwirrt, dass viele "Befehle" in einer Programmiersprache geschrieben sind, die ich nicht in Einklang bringen kann mit dem, was ich in den Büchern über reine Arduinoprogrammierung bisher gelernt habe (z.B. "memset" oder "strstr").

Deine Bücher "über reine Arduinoprogrammierung" sind nicht das allein Seeligmachende für die C-Programmierung von AVR-Mikrocontrollern.

Arduino ist in erster Linie eine GCC-Entwicklungsumgebung mit vollständigen AVR-libc Libraries, die vollständig vorinstalliert sind. Plus einen kleinen Fliegenschiss an Arduino-spezifischen Erweiterungen bei Preprocessing und Arduino-Libraryerweiterungen.

Zum Programmieren unter Arduino steht Dir die gesamte AVR libc zur Verfügung:
http://www.nongnu.org/avr-libc/

Library Reference: avr-libc: Modules

Mit allen Stringbearbeitungsfunktionen: avr-libc: <string.h>: Strings

Die Links poste ich mal, falls Du nachschlagen möchtest, welche Befehle Dir zum Programmieren zur Verfügung stehen. Wie Du die verwendest, kannst Du auch auf anderen Seiten über C und C++ Programmierung googeln, wenn sie Dir nichts sagen.

Im Gegensatz dazu, dass manche meinen, Arduino wäre ein Mikrocontrollersystem, das sich an Leute mit null Vorkenntnissen wendet, ist Arduino tatsächlich ein Mikrocontrollersystem, das sich zuerst an C/C++-Programmier mit soliden Programmierkenntnissen wendet.

Chris72622:
Da ich ohne delay() arbeiten möchte, da ich noch anderen Code abzuarbeiten habe, wäre mir die "Funktionsvariante" viel lieber, doch mit dem Umbauen haperts ganz gewaltig. :frowning:

Das sind Beispiele mit wenigen Codezeilen für interaktive Programme. Die darin enthaltenen 100ms Delay liegen unterhalb der Reaktionszeiten eines Menschen. Wenn Du nicht-interaktive Programme machst, die in den 100ms, die der Beispielcode wartet, noch tausend andere Dinge erledigen müssen, kannst Du die Kommandos natürlich auch ohne Delay einsammeln, dann wird der Code und die Programmlogik ein paar Zeilen länger.

Chris72622:
In meinem Fall würde es aureichen auf Zeichenfolgen zu prüfen (wie "CONNECT" bei dem Kollegen, bloß inkl. Leerzeichen- z.B. "Z 3 0 1").

Also eine loop die gleichzeitig kurze Kommandos von der seriellen Schnittstelle sammelt und ohne delay andere Dinge erledigen kann während die seriellen Zeichen eintrudeln. Da würde ich mir keine grossen Gedanken über einen eigenen Empfangs-Ringpuffer machen, das ist vergebliche Mühe, denn der serielle Empfangspuffer beim Arduino ist ja bereits vorhanden, ich glaube mit 64 Bytes Pufferspeicher. Da braucht man die Zeichen nur rausziehen und auf die Kommandos abscannen, genau wie in den zwei von mir geposteten Beispielen. Bzw. mit den ganzen Zahlen als Modifikator eines Kommandos dann das zweite Beispiel mit der "CONNECT" Auswertung.

Chris72622:
Das sich aus meiner Sicht bei Beiden von Dir verlinkten Codeschnipseln der Buffer innerhalb der setup loop() befindet, kann ich das Ganze nun leider nicht in Einklang mit bisher von Dir "vorgeschlagenen" Funktionsvariante bringen.

Da schaue bitte nochmal genau hin!
Im CONNECT-Beispiel http://arduino.cc/forum/index.php/topic,137669.0.html wird in setup() nur die serielle Schnittstelle initialisiert, es gibt eine saugeniale Funktion getIntFromString zum Rausziehen von Zahlenwerten aus einem String, die von überall im Sketch verwendet werden kann, und es gibt eine loop(), in der Kommandos laufend ausgewertet werden und die darauf reagiert, dass bestimmte Kommandos kommen.

Das ist der Ansatz als Vorlage, wo Du nur noch das delay() durch eine andere Programmlogik ersetzen müßtest, und dann könntest Du auch Kommandos wie z.B. "Z 3 0 1" damit erkennen und darauf reagieren.

1000 Dank für den ganzen Content!!

Werde mir alles zu Gemüte führen!

Spricht was gegen diese Lösung (Textsendefenster muss CR mitschicken):

boolean x=0;

void setup()
{

Serial.begin(9600);
  
}

void loop()
{

  x=Serial.findUntil("Z 3 0 1","\r");
  Serial.println(x);
  delay(100);
}

Wunder mich, warum es keine Bufferprobleme zu geben scheint. Ist der Arduino-Eingangsbuffer somit ein Ringbuffer und überschreibt automatisch die letzten Zeichen?

Gruß Chris

Chris72622:
Spricht was gegen diese Lösung (Textsendefenster muss CR mitschicken):
...
x=Serial.findUntil("Z 3 0 1","\r");

???

Gestern noch schriebst Du was davon, dass 100 ms delay für Dein Programm nicht OK sind:

"Da ich ohne delay() arbeiten möchte, da ich noch anderen Code abzuarbeiten habe"
Und heute möchtest Du eine Funktion aufrufen, die sämliche Codeverarbeitung bis ins unendliche blockieren kann, jedenfalls so lange bis entweder der Suchstring oder der terminierende String gefunden wird?

Kapiere ich nicht.

Das mußt Du doch selber wissen, wie lange Dein Programm maximal zwischendurch warten darf bis wieder Code ausgeführt wird. Entweder gar nicht, dann mußt Du Dir noch was einfallen lassen. Oder 100 ms (wobei das ggf. auch herabgesetzt werden kann) mit der von mir geposteten Lösung. Oder bis zu unendlich lange bis entweder der gesuchte String oder ein Zeilenende von der seriellen Schnittstelle reinkommt mit "findUntil".

Chris72622:
Wunder mich, warum es keine Bufferprobleme zu geben scheint. Ist der Arduino-Eingangsbuffer somit ein Ringbuffer und überschreibt automatisch die letzten Zeichen?

Solange in den seriellen Eingangspuffer nicht mehr Zeichen reingeschrieben werden als es der Puffergröße entspricht, ohne zwischendurch Zeichen wieder auszulesen, wird gar nichts überschrieben, sondern nur zwischengepuffert.

Das mit den 100ms im letzten Codefetzen war nur fürs Debugging.

Gruß Chris