Serieller Monitor : Zeichenweise einlesen und ausgeben

Hallo,
ich bin gerade dabei, ein Programm zu schreiben, das maximal 16 Zeichen vom seriellen Monitor einlesen soll. Werden mehr als 16 Zeichen eingegeben, soll der Rest verworfen werden und nur die ersten 16 Zeichen wieder ausgegeben werden (16 deshalb, weil ich damit später ein LCD ansteuern will).
Leider gibt das Programm immer alle Eingaben zurück, nicht nur die 16 gespeicherten Zeichen.

char Line1[16] = {'\0'};
int i=0;
int received = 0;

void setup() {
  // put your setup code here, to run once:
   Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:  
 while (Serial.available() > 0)
  {
    if (i < 16)   //Solange Puffer noch nicht voll
      Line1[i] = Serial.read();  //Speichere Zeichen in Puffer
    else    //Wenn Puffer voll
      char rx_lost = Serial.read(); //Lese Zeichen aber nicht speichern  
    i++;
    received = 1;   //Flag auf "Nachricht erhalten" setzen
  }

  if (received == 1)
  {
    if (i > 15) //Nicht mehr als 15 Zeichen ausgeben
      i = 15;
    Line1[i] = '\n';  //Letztes Zeichen ist Zeilenendezeichen
    
    for (int a=0; a<i;a++)
    {
      Serial.print(Line1[a]); //Zeichen ausgeben....
      Line1[a]='\0';          //und im Puffer gleich wieder löschen
    }
    received = 0;   //Nachricht ausgegeben, also Flag zurücksetzen
    i=0;          //Buffer-Counter zurücksetzen
    
    
  }
}

Könnt ihr mir sagen, wo der Fehler liegt ?

Vielen Dank !

Da stecken ein paar richtige Ideen drin, aber insgesamt ist es etwas seltsam

Außerdem muss ein Array für 16 Zeichen 17 Byte haben, damit noch Platz für den Terminator ist

Was man auch beachten muss ist dass die serielle Schnittstelle sehr langsam ist. Man kann das also nicht wirklich in einer while-Schleifen einlesen. Sondern man muss eine Einlese-Funktion immer wieder aufrufen bis das Endzeichen ankommt.
Unten sieht du auch eine while-Schleife, aber in den meisten Fällen wird da nur ein Zeichen pro Durchlauf eingelesen

const int SERIAL_BUFFER_SIZE = 17;
char serialBuffer[SERIAL_BUFFER_SIZE];

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

void loop()
{
  if (readSerial(Serial))      //liefert true wenn das LF eingelesen wurde
  {
    Serial.print("Empfangen: "); Serial.println(serialBuffer);
  }
}

bool readSerial(Stream& stream)
{
  static byte index;

  while (stream.available())
  {
    char c = stream.read();

    if (c == '\n' && index > 0)       //wenn LF eingelesen und String länger als 0 ist
    {
      serialBuffer[index] = '\0';     //String terminieren
      index = 0;
      return true;                    //melden dass String fertig eingelesen wurde
    }
    else if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)   //solange noch Platz im Puffer ist
    {
      serialBuffer[index++] = c;    //Zeichen abspeichern und Index inkrementieren
    }
  }
  return false;        //noch nicht fertig
}

aus deiner Erklärung, das habe ich vorhin auch gesehen. aus meiner sicht ist es nicht gut das while zu nutzen, weil es die loop() aufhält. und ein problem habe ich bemerkt, wenn man keinen wert sendet, sondern nur '\n'. wenn '\n' erkannt wurde sollte man den index nochmal prüfen, ob er größer 0 ist. wenn nicht, dann auch ein return false.

Was soll da aufhalten? Wenn keine Zeichen mehr im Puffer sind bricht while sofort ab. Und wenn mehr Zeichen im Puffer sind werden die direkt ausgelesen. Das ist auch nur der Fall wenn loop() selbst länger als die Übertragung eines Zeichens dauernd. In den meisten Fällen wird man ein Zeichen lesen und dann erst mal nach loop() zurückkehren

Und das trifft auch nur auf Serial zu. Man kann obigen Code auch verwenden um z.B. eine Zeile von einer SD-Karte einzulesen. Da ist dann praktisch das in einer while-Schleife zu erledigen

und ein problem habe ich bemerkt, wenn man keinen wert sendet, sondern nur '\n'. wenn '\n' erkannt wurde sollte man den index nochmal prüfen, ob er größer 0 ist. wenn nicht, dann auch ein return false.

Es kommt auf die Anwendung an welches Verhalten da erwünscht ist. Manchmal will man eine leere Zeile erkennen, aber es gibt auch Situationen wo das nicht schön ist

wenn im loop z.b. noch andere aufgaben laufen, die man nicht unbedingt aufhalten sollte.
wenn serial leer ist, ist es klar, aber wenn mal ne ladung wartet, dann kann es schon etwas zeit kosten.

Da werden ein paar Bytes umkopiert. Das ist alles. Was Zeit kostet sind die Funktionsaufrufe. Und wenn die dein Programm merkbar verlangsamen hast du andere Probleme