Serielle Eingabe

Hallo,

mein Name ist Wolfgang und ich komme jetzt öfter :slight_smile:
Über Modellflugprojekte bin ich beim arduino gelandet und mache meine ersten Schritte.

Aus eine Buch habe ich mir folgendes als Test für serielle Kommunikation zusammengestoppelt:

char incomingByte[255]={};
int i=0;
void setup(){
Serial.begin(9600);

}
void loop(){
while (Serial.available() >0){
incomingByte*=Serial.read();*

  • i++;*

  • delay(3);}*

  • Serial.print("Empfangen:");*

  • Serial.println(incomingByte);*

  • for(int i=0;i<=255;i++){*
    _ incomingByte*=0;_
    _
    }_
    _
    }_
    Jetzt würde ich erwarten, daß durch "while (Serial.available() >0)"
    nur dann was geprintet wird, wenn auch was nasteht, aber die Anzeige im Monitor läuft mit
    Empfangen:
    Empfangen:
    Empfangen:
    _
    ....*_
    durch. Bei einer Eingabe läuft diese kurz mit durch und verschwindet. Was passt da nicht?
    Dank im voraus.
    Gruß,
    Wolfgang

Hallo Wolfgang,

ich glaube nicht, dass du das Beispiel richtig abgeschrieben hast - das was du gepostet hat macht folgendes:

while (Serial.available() >0)
{

  • incomingByte=Serial.read();*
  • i++;*
  • delay(3);*
    }
    Erklärung: Während seriell übertragen wird: überschreibe die Variable incomingByte mit dem ankommende Byte; inkrementiere Variable i (also um eins erhöhen); warte 3ms;

Serial.print("Empfangen:");
Serial.println(incomingByte);
for(int i=0;i<=255;i++)
{

  • incomingByte=0;*
    }

Erklärung: Gebe "Emfangen:" aus; Gebe Variable "incomingByte" (das als letztes empfangene Zeichen) aus; Während Variable "i" (die mit = 0 auf den startwert 0 gesetzt wird) kleiner als 255 ist wiederholde: überschreibe incomingByte mit 0; inkrementiere Variable "i"

Das macht in dieser Form wenig Sinn. Gerade das raufzählen von "i" ist absolut sinnfrei, die anschließende for-Schleife überschreibt (dank der zurücksetzung von i mit i=0) 256 mal die Variable "incomingByte" mit 0;

Besser ist es z.B folgendermaßen:

// wenn Serielle Daten verfügbar sind
if (Serial.available() > 0)
{

  • // ankommendes Zeichen wird eingelesen und in Variable "incomingByte" geschrieben.*
  • incomingByte = Serial.read();*
  • // Zeichen in Variable "incomingByte" wird mit der Meldung "Empfangen: [ZEICHEN]" ausgegeben*
  • Serial.print("Empfangen: ");*
  • Serial.println(incomingByte, DEC);*
    }

Da der Arduino das eh in einer Schleife (im void Loop()) ausführt gibt er immer dann etwas aus, wenn ein zeichen ankommt. Ist zwar die Quick and Dirty-Lösung, aber funktioiniert.

while (Serial.available() >0){
incomingByte=Serial.read();
i++;
delay(3);}
Das Problem sehe ich, daß Du immer den Index bei der Variablen incomingByte vergessen hast.

Aber das ist eine Interpretationsfrage der Programmidee, dh. Marcus könnte recht haben und ich nicht.
Grüße Uwe

oops. ich hab die deklaration oben garnicht gesehn. stimmt - wenn man nen index verwendet gehts auch - dann mach das ganze sogar sinn. der code müsste dann folgendermaßen aussehn:

EDIT: ich weiß, wieso der index fehlt: ohne CODE-Tag wird das [\i] als kursiv-tag interpretiert

// hier wird das Array erzeugt
char incomingByte[255]={};
int i=0;

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

void loop()
{
    while (Serial.available() >0)
    {
      incomingByte[i]=Serial.read();
      i++;
      delay(3);
    }
 
    Serial.print("Empfangen:");
    Serial.println(incomingByte);

          for(int i=0;i<=255;i++){
      incomingByte[i]=0;
    }
}

Danke für Eure Mühen.

Genau, das Array ist dafür, um eine Zeichenfolge einzulesen, ohne das Array wird Zeichen für Zeichen dargestellt.
Leider läuft die Anzeige auch mit Index einfach weiter durch.

So ganz ist mir noch nicht geholfen.

Jetzt versteh ich, was du meinst. Das Problem is, dass du die ausgabe innerhalb des loops machst und nicht innerhalb der While-schleife. bei meiner ersten version wird z.B. nur ausgegeben, wenn aus serielle Daten übermittelt werden.

void loop()
{
    while (Serial.available() >0)
    {
      incomingByte[i]=Serial.read();
      i++;
      delay(3);
    }

wenn zeichen im Buffer der seriellen Schnittstelle sind bleibt das Programm in der While Schleife bis alle empfangenen Daten heruntergeladen sind

    Serial.print("Empfangen:");
    Serial.println(incomingByte);

          for(int i=0;i<=255;i++){
      incomingByte[i]=0;
    }
}

Falls keine Zeichen im Buffer sind oder der Buffer geleert wurde wird dieser teil ausgeführt und zwar IMMER wieder.
Praktisch wird das bei jedem Durchgang der LOOP() Funktion gemacht.

Wann möchtest Du daß es gemacht wird?
Grüße Uwe

Hallo Marcus, genau, aber Zeichen für Zeichen, nicht der ganze String.

Hallo Uwe, nach Eingabe und Enter einmal den String.

Dank im voraus.

Hallo,

habe ich jetzt was falsches oder auf die falsche Weise gesagt?

Oder bin ich zufällig auf eine kniffelige Frage gestoßen?

Also eigentlich möchte ich nur, daß die Eingabe einmal angezeigt wird (als komplette Zeile) und dann nicht ständig der Standardtext weiterläuft.

Gruß,

Wolfgang

Hallo,

ich weiß ja nicht ob du bereits eine Lösung zu deinem Problem gefunden hast, Wolfgang, aber wenn ich dich richtig verstehe fehlt in deinem code eine zusätzliche Abfrage.

zB so:

if incomingByte[0] != 0 
{
    Serial.println("Empfangen:");
    Serial.println(incomingByte);
}

Also nur wenn auch wirklich Daten empfangen wurden und im array stehen, erfolgt eine Ausgabe :wink:
komplett:

char incomingByte[255]={};
  int i=0;
void setup(){
  Serial.begin(9600);

}
void loop(){
/* array index bei jedem Durchlauf von loop zurücksetzten */
  i =0;

  while (Serial.available() >0){
    incomingByte=Serial.read();
    i++;
    delay(3);}
 
 if (incomingByte[0] !=0)
  {
    Serial.print("Empfangen:");
    Serial.println(incomingByte);
 }

  for(int i=0;i<=255;i++){
      incomingByte=0;
    }
}

Gruß
Thorsten

auch bei deinem Beispiel fehlt wieder der Index von incomingByte :wink:

ich würde es so machen:

int i = 0;
void loop()
{
    while (Serial.available() >0)
    {
        incomingByte[i]=Serial.read();
        i++;
        //delay(3);
    }

    if (incomingByte[0] != 0)
    {
        Serial.print("Empfangen:");
        Serial.println(incomingByte);
       
        for (int b = 0; b <= i; b++)
        {
            incomingByte[b] = 0;
        }

       //EDIT: Hab vergessen "i" wieder auf null zu setzen.
       i = 0;
    }

}

Ich würde das delay(3) drin lassen, da das Programm sonst aller Wahrscheinlichkeit nach noch während der Übertragung der Zeichen vom Computer zum Arduino aus der while aussteigt, weil es die while so schnell durchläuft dass es den Zeichenpuffer im Arduino "leer saugt".

Quasi wie wenn Du Wasser in einen Kanister schüttest und unten ist ein Loch das größer ist als das Loch oben. So ein Kanister wird auch nie voller... :wink:

Ja, da hast du recht - deshalb hab ich es nur kurz auskommentiert - wenn es ohne funktioniert gut, wenn nicht einfach die zwei slashes weg und los geht die lutzi

Danke! Ich kann erst Sonntag testen und werde berichten.

Gruß,

Wolfgang

Yes!! Das war es! Danke!

Also das Problem war dies? "if (incomingByte[0] != 0)"

Ich hätte gemeint, daß das durch "while" abgefangen ist. So kann man sich täuschen.