Go Down

Topic: HELP (Read 847 times) previous topic - next topic

stbeckea

Feb 17, 2012, 10:52 am Last Edit: Feb 17, 2012, 11:33 am by stbeckea Reason: 1
Hallo,
bin neu hier und nicht wirklich fit mit Arduino.
Habe hier den Anfang eines codes, er soll mir einfach zeichen abholen und in einem array speichern.
jedoch zählt die variable incount nur mist und die abfrage nach dem übertragungsende funktioniert nicht. kann mir jemand weiterhelfen?


Code: [Select]

// LED 1-8 <-> Port PD0 - PD7
int ledPin1 = 0;    
int ledPin2 = 1;  
int ledPin3 = 2;  
int ledPin4 = 3;
int ledPin5 = 4;    
int ledPin6 = 5;  
int ledPin7 = 6;  
int ledPin8 = 7;
//int freq;               // Frequenzwert_Nutzer
long breit = 0;            // Breite_Nutzer_ zu schaltende LEDS inkl Winkel
long pulse = 0;            // Dimmerwert_Nutzer
long wi_pos = 0;           //Winkelposition

unsigned int baud_rate = 57600;  // Serielle Bautrate
char inchar[12];                 // Ankommende Werte_Seriell
byte incount = 0;                 // Anzahl ankommende Werte
int anz_in = 0;                   // Weitergabevariable anzahl ankommende Werte
int s_done = 0;                   // Serielle Verbindung beendet
long inmin = 0 ;                 // Minimalwert serielle Eingabe
long inmax = 0 ;                 // Maximalwert serielle Eingabe  
int  insign = 0 ;                // Vorzeichen Eingbe
int invalue = 0 ;               // Serieler Empfangswert, dezimal
long to_switch = 0;

int zyklus;          //INT1_Zyklus, Abfrage für OVL
int limit;           //Timer Compare Wert

//Testausgänge
int  INT_1_test = 0;
int  INT_2_test = 0;

//Methoden


void seriell();                                         //Abfrage, Speichern, Berechnung -> COM PORT
/*
long calc_value(long inmin, long inmax);                //Berechnung Zyklus
long set_LED(long inmin, long inmax, long wi_pos);      //Zuweisung LED ON
long set_Winkel (long inmax);                           //Winkelposition
*/


void setup()
{
 // initialize the serial communication:
 Serial.begin(baud_rate);
 
 pinMode(ledPin1, OUTPUT);   // sets the pin as output
 pinMode(ledPin2, OUTPUT);   // sets the pin as output
 pinMode(ledPin3, OUTPUT);   // sets the pin as output
 pinMode(ledPin4, OUTPUT);   // sets the pin as output
 pinMode(ledPin5, OUTPUT);   // sets the pin as output
 pinMode(ledPin6, OUTPUT);   // sets the pin as output
 pinMode(ledPin7, OUTPUT);   // sets the pin as output
 pinMode(ledPin8, OUTPUT);   // sets the pin as output

 pinMode(INT_1_test, OUTPUT);  //TestPin_ Int1
 pinMode(INT_2_test, OUTPUT);  //TestPin_ Int2
 
 //Vorbereitung der Verbindung
 Serial.flush();               //Löschen des Buffers
 invalue = 0;

 

}



void loop()
{
 seriell();
}



void seriell()
{
 if (Serial.available() > 0)          //Daten ankommend?
 {
   inchar[incount] = Serial.read();   //Datenbyte abholen
   
   //TeST
   Serial.print("Inchar: ");
   Serial.println(inchar[incount]);
   Serial.print("Incount: ");
   Serial.println(incount);
       
     
   if ((inchar[incount] ==13) || (inchar[incount] == 10))    // Ist Übertragung abgeschlossen?
   {
     if (incount > 1)
     {
     s_done = 1;                                             // Bestätigung  für weitere Verarbeitung
     anz_in = incount;                                       // Weitergabe, Anzahl der Daten
   
     Serial.print("IncharKomplett: ");
     Serial.println(inchar);  
     Serial.print("Anzahl: ");
     Serial.println(anz_in);
     }
    incount = 0;                                              // reset Zähler  
   }  
   
   else if (inchar[incount] == ' ')                          // löschen der Leerzeichen
   {
     Serial.flush();
   }
 }
 else incount = incount+1;                                    // Datenzähler erhöhen
}


MueThoS

Du benutzt für deine LEDs auch pin 0 und 1
Das liegt aber auch die Serielle Schnittstelle drauf!
Das solltest du ändern

mkl0815

Zum einen bitte den Code in die "#" Tags einfassen, das macht das Lesen leichter.
Als nächstes fällt auf, das Dein Code folgendes macht:
Code: [Select]

 if (Serial.available() > 0)          //Daten ankommend?
 {
      ....
 }
 else {
     incount = incount+1;
  }

Damit wird also "incount" immer dann erhöht, wenn gerade keine Bytes an der seriellen Schnittstelle ankommen. Ich glaube das ist nicht das was Du möchtest. Leider erklärst Du nicht was das Ziel Deines Programms ist.
incount ist von Typ "byte". Zählt also von 0 bis 255 immer munter durch, wenn gerade keine Daten ankommen. Wenn dann Daten ankommen, hat "incount" dann irgendeinen zufälligen Wert zwischen 0 und 255, was vermutlich der "Mist" ist, den Du meinst :-)
Grundsätzlich gilt bei der Fehleranalyse: Weniger ist Mehr!
Also erstmal den Code auf das Wesentliche abspecken und nur das in einen Sketch packen. Das ist wesentlich übersichtlicher und man findet den Fehler schneller.

stbeckea

sorry bin  wie gesagt noch nicht sehr foren erfahren.
also das programm soll zunächst nur die werte abholen. (ich habe es teils aus einem vorgehenden übernommen)
im weitern sollen die werte gefiltert werden,
also zb. Wxxx = erster wert Bxxx zweiter wert usw.

den rx/tx habe ich übersehen, schon geändert und auch noch nicht verwendet...

incount+= ist auch geändert, zählt jetzt richtig


leider verstehe ich die abfrage des eingabeendes nicht richtig also:

Code: [Select]


if ((inchar[incount] ==13) || (inchar[incount] == 10))    // Ist Übertragung abgeschlossen?
    {
      if (incount > 0)

MueThoS

die 10 ist der Zeilenvorschub
die 13 der Wagenrücklauf
in ASCII
Also sozusagen das return

Wenn ich mich nicht irre

stbeckea

hmhm, das habe ich auch schon gelesen, leider funktionierts dann nicht. mal weitertesten

danke schonmal

stbeckea

Nun da ich den Code ein wenig geändert habe... kommt mein incount fat richtig an, leider zählt er sobal das array inchar[13] voll ist weiter nachdem er ca 50 schritte übersprungen hat, und erst nach ca 100 schritten kommt die ausgabe der zeichenanzahl und der zeichen
Code: [Select]



// LED 1-8 <->Port PB0-PB1 Port PD2 - PD7
int ledPin1 = 8;     
int ledPin2 = 9;   
int ledPin3 = 2;   
int ledPin4 = 3;
int ledPin5 = 4;     
int ledPin6 = 5;   
int ledPin7 = 6;   
int ledPin8 = 7;
//int freq;               // Frequenzwert_Nutzer
long breit = 0;            // Breite_Nutzer_ zu schaltende LEDS inkl Winkel
long pulse = 0;            // Dimmerwert_Nutzer
long wi_pos = 0;           //Winkelposition

unsigned int baud_rate = 57600;  // Serielle Bautrate
char inchar[14];                 // Ankommende Werte_Seriell
byte incount = 0;                 // Anzahl ankommende Werte
byte anz_in = 0;                   // Weitergabevariable anzahl ankommende Werte
int s_done = 0;                   // Serielle Verbindung beendet
long inmin = 0 ;                 // Minimalwert serielle Eingabe
long inmax = 0 ;                 // Maximalwert serielle Eingabe   
int  insign = 0 ;                // Vorzeichen Eingbe
long invalue = 0 ;               // Serieler Empfangswert, dezimal
long to_switch = 0;

int zyklus;          //INT1_Zyklus, Abfrage für OVL
int limit;           //Timer Compare Wert

//Testausgänge
int  INT_1_test = 12;
int  INT_2_test = 13;

//Methoden


void seriell();                                         //Abfrage, Speichern, Berechnung -> COM PORT
/*
long calc_value(long inmin, long inmax);                //Berechnung Zyklus
long set_LED(long inmin, long inmax, long wi_pos);      //Zuweisung LED ON
long set_Winkel (long inmax);                           //Winkelposition
*/


void setup()
{
  // initialize the serial communication:
  Serial.begin(baud_rate);
 
  pinMode(ledPin1, OUTPUT);   // sets the pin as output
  pinMode(ledPin2, OUTPUT);   // sets the pin as output
  pinMode(ledPin3, OUTPUT);   // sets the pin as output
  pinMode(ledPin4, OUTPUT);   // sets the pin as output
  pinMode(ledPin5, OUTPUT);   // sets the pin as output
  pinMode(ledPin6, OUTPUT);   // sets the pin as output
  pinMode(ledPin7, OUTPUT);   // sets the pin as output
  pinMode(ledPin8, OUTPUT);   // sets the pin as output

  pinMode(INT_1_test, OUTPUT);  //TestPin_ Int1
  pinMode(INT_2_test, OUTPUT);  //TestPin_ Int2
 
  //Vorbereitung der Verbindung
  Serial.flush();               //Löschen des Buffers
  invalue = 000;

 
  //Initialisierung Timer

  //init_timer1(zyklus);
  //stopISR_COMPB();
  //startISR_OVF;
}



void loop()
{
  seriell();
}



void seriell()
{
  if (Serial.available() > 0)          //Daten ankommend?
  {
    inchar[incount] = Serial.read();   //Datenbyte abholen
   
    //TeST
    Serial.print("Inchar: ");
    Serial.println(inchar[incount]);
    Serial.print("Incount: ");
    Serial.println(incount);
       
       
    if ((inchar[incount] ==13) || (inchar[incount] == 10))    // Ist Übertragung abgeschlossen?
    {
      if (incount = 13)
      {
      s_done = 1;                                             // Bestätigung 
      anz_in = incount;                                       // Weitergabe, Anzahl der Daten
     
      Serial.print("IncharKomplett: ");
      Serial.println(inchar); 
      Serial.print("Anzahl: ");
      Serial.println(anz_in);
     
       
      }
      incount = 00;                                            // reset Zähler   
    } 
   
    else if (inchar[incount] == ' ')                          // löschen der Leerzeichen
    {
      Serial.flush();
    }
    else incount = incount+1;                                 // Datenzähler erhöhen
  }
                                     
}



mkl0815

Ich würde das Einlesen der Daten und die Ausgabe des Ergebnisses trennen.
Aktuell passiert in Deinem Code folgendes:
Code: [Select]

    if ((inchar[incount] ==13) || (inchar[incount] == 10))    // Ist Übertragung abgeschlossen?
    {
      if (incount = 13)
      {
      s_done = 1;                                             // Bestätigung 
      anz_in = incount;                                       // Weitergabe, Anzahl der Daten
     
      Serial.print("IncharKomplett: ");
      Serial.println(inchar); 
      Serial.print("Anzahl: ");
      Serial.println(anz_in);
     
       
      }
      incount = 00;                                            // reset Zähler   
    } 

Das äußere if-Statement prüft ob die Zeichen mit dem ASCII-Wert 10 oder 13 übertragen wurden. Wenn ja, wird das als Zeilenende und damit als Ende der Übertragung erkannt.
Dann wird aber nicht geprüft ob das Zeichen ein newline (ASCII-Wert 13) ist, sondern ob incount den Wert 13 hat, also 13 Zeichen übertragen wurden. Abgesehen davon hast Du "incount = 13) gesetzt, das ist aber eine Zuweisung, kein Vergleich (incount == 13).
Das äußere if-Statement schlägt auch zu, wenn das Zeichen "10" übertragen wurde. Dabei wird dann incount einfach auf 0 gesetzt (incount = 00;) Kommt als nächstes Zeichen dann ein Newline (13) dann wird anz_in auf incount gesetzt und damit auf 0 und nicht auf die eigentlich gezählte Länge.
Den Code
Code: [Select]

else if (inchar[incount] == ' ')                          // löschen der Leerzeichen
    {
      Serial.flush();
    }
    else incount = incount+1;                                 // Datenzähler erhöhen
  }

verstehe ich auch nicht ganz. Vor Version 1.0 der IDE wurden mit Serial.flush() alle noch im Puffer vorhandenen seriellen Daten gelöscht. Damit würdest Du bei einem Leerzeichen in der Mitte Deiner Daten auch den ganzen schon übertragenen Rest löschen. Ab Version 1.0 der IDE sorgt Serial.flush() nur noch dafür das alle gepufferten Ausgabedaten übertragen weden. Das hat also auf das Lesen Deiner Daten keinen Einfluss. Außerdem ist ''' ein leerer String. Ein Leerzeichen wäre ' '. Wenn es nur darum geht, Leerzeichen zu ignorieren, dann würde ich folgendes machen:
Code: [Select]

if (inchar[incount] != '  ')                          // Leerzeichen ignorieren
    {
        incount++;                                    // Datenzähler erhöhen
    }

Also immer wenn es KEIN Leerzeichen war, den Zähler erhöhen. Wenn es ein Leerzeichen war, dann bleibt der Zähler wie er war und das nächste Zeichen überschreibt das Leerzeichen im Array.

stbeckea

danke für dei antwort,
also eigentlich funktioniert das ganze halbwegs wie es soll, leerzeichen löschen funktioniert auch.
ich habe die eigangsvariable auf 5 zeichen begrenzt, die abfrage nach incount ==13  heißt jetzt incount >0, also: sind zeichen da?

das problem ist das der zähler incount nicht stoppt wenn die eingabe beendet ist, er zählt weiter bis irgendwo und zufällig stoppt er und die verarbeitung geht weiter...
keine anhung woran das liegen könnte

mkl0815

dann poste doch nochmal den aktuellen Code.

Go Up