mein Name ist Wolfgang und ich komme jetzt öfter
Ü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
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;
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;
}
}
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.
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.
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.
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
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;
}
}
auch bei deinem Beispiel fehlt wieder der Index von incomingByte
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...
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