Pages: [1]   Go Down
Author Topic: serielle Schnittstelle und Terminal  (Read 1165 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

ich fange mit dem ArduinoBoard gerade ein kleines Projekt an.
Neben einigen Probleme, die ich zum Teil schon gelöst habe nun eines bei dem mir so langsam die Ansätze ausgehen.
Also die unten aufgeführte Funktion/Prozedur wird periodisch von loop() aufgerufen.
Mein Problem ist derzeit, dass das erste Zeichen immer extra ausgegeben wird.
Also ich gebe "test" ein. Und es wird mir:
1 t
3 est
geanwortet.
Das liegt doch wohl nicht an dem eingebauten Terminal?
Aber wo bitte ist dann mein Fehler?
Achso, dass der String nicht \0 terminiert ist, ist mir klar mit dem Problem wollte ich mich danach auseinandersetzten. Der erste kurze Versuch wurde vom Compiler boykotiert. smiley

Ich würde mich über Tipps oder Hinweise freuen.

Grüße Oliver

PS:
Was ich zum Schluss eigentlich erreichen möchte, ist dass ich jede Globale Variable später noch anpassen kann.
Sollte es soetwas schon fertig geben. Würde es natürlich die Tiparbeit um einiges erleichtern.
Und wo ich schonmal im PS bin. Gibt es bisher einen Ansatz in der normalen IDE-Sketch-Editor-Terminal Umgebung mit dem Board kontakt aufzunehmen, ohne dass es einen Reset auslöst? Wäre doch schön wenn man das unter den Einstellungen ändern könnte.


Code:
void SerialDebug(){
  char incomingChar;
  char eingabe1S[50] ; // es dürfen maximal 49 Zeichen eingeben werden.
  char eingabe2S[50] ="\0";
  int incomingLaenge;

  incomingLaenge = Serial.available(); //Komplette länge Merken damit später \0 hinzugefügt werden kann.
  if (incomingLaenge > 0){
    for (byte zeichen = 0; zeichen <= incomingLaenge ; zeichen++){
      incomingChar = char(Serial.read());
      eingabe1S[zeichen]=incomingChar;
//      strcat(eingabe1S,incomingChar);
    }
//    eingabe1S[incomingLaenge] = "\0";  // ergibt einen Fehler ?
    
    Serial.print("Ich habe empfangen : ");
    Serial.print(incomingLaenge,DEC);
    Serial.print(" ");
    Serial.println(eingabe1S);
  }
  
}
Logged

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3418
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Verhalten ist völlig korrekt. Die serielle Schnittstelle weiß ja nicht ob und wieviele Zeichen kommen. Dein Programm ruft vermutlich die Funktion sehr schnell hintereinander auf. Sobald das erste Zeichen da ist wird dieses erkannt und ausgegeben. Deshalb ist der nächste Aufruf etwas später dran und deshalb sind dann vermutlich die nächsten 3 Zeichen aufgelaufen.

Darauf musst Du Dich einstellen. Schau Dir mal an wie andere das lösen.

http://www.arduino.cc/playground/Code/Messenger
http://biot.com/arsh/

Gruß,
Udo
« Last Edit: December 27, 2009, 02:49:16 am by udoklein » Logged

Check out my experiments http://blog.blinkenlight.net

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Erstmal danke für die Anregung.
Ich habe mir ersteinmal die Messenger lib ein wenig genauer angesehen.
Und wenn ich mir die Beispiele ankucke wird es dort genauso gemacht wie auch bei mir.

Ich habe meinen Versuch ein wenig abgeändert, und auch mal ein anderes Terminalprogramm getestet.
Hterm finde ich derzeit übrigens recht hilfreich. Selbst der Reset tritt nicht auf bzw kann nach Wunsch selbst eingeleitet werden.

Nun werde ich leicht irre weil ich noch nicht einmal diese kleine Funktion hinbekomme.
Meine Funktion (siehe unten) reagiert nicht auf den letzten if befehl. Ich kann "test" eingeben wie ich will, aber ich habe kein Glück. Was mache ich Falsch? Der richtige Wert wird vor den beiden if's angezeigt. Der "kleine Erfolg" klappt. Ich denke ich stell mich irgendwie zu blöd mit den Strings an.
Wäre über einen Tipp oder Link echt dankbar.

PS:
die if abfragen nach LF, Return oder \0 sind derzeit nicht wirklich wichtig.

Code:
void SerialDebug(){
  byte incomingByte;
  char buffer[50];
  byte bufferzaehler = 0;
 
  while (Serial.available() != 0){
  incomingByte = Serial.read();
   if ( incomingByte == 13) {
     Serial.println("Return");
     break;
   } else if (incomingByte == 10) {
     Serial.println("LF");
     break;
   } else if (incomingByte == 0) {
     Serial.println("NULL");
     break;
   } else {
     buffer[bufferzaehler] = char(incomingByte);
     bufferzaehler++;
   }
  }
  buffer[bufferzaehler]= '\0';

Serial.println(buffer); // nur zum Testen
  if ( buffer[1] == 'e') {
    Serial.println("Wenigstens ein kleiner erfolg.");
  }
  
  if ( buffer == "test" ) {
    Serial.println("Dieser Test ist geglückt");
  }
  
}
Logged

Pittenhart, Bavaria, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 65
Try and fail, but don't fail to try!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

Quote
Meine Funktion (siehe unten) reagiert nicht auf den letzten if befehl. Ich kann "test" eingeben wie ich will, aber ich habe kein Glück. Was mache ich Falsch?

mit messenger sollte es klappen. Bei mir funktioniert das so jedenfalls.


Code:
// Bibliothek für die serielle Kommunikation einbinden

#include <Messenger.h>

// Instanz für serielle Kommunikation erstellen
Messenger message = Messenger();  

void setup() {

  Serial.begin(115200);  // Baudrate einstellen


   // Callback Funktion für serielle Kommunikation
 message.attach(messageReady);  
}

void loop(){

 // serielle Signale vom PC empfangen und auswerten
 while ( Serial.available() ) message.process( Serial.read() );

}

void messageReady() {

  while ( message.available() ) {

    if ( message.checkString("Hallo") )
    {
         Serial.println("Jetzt hat es hoffentlich geklappt");
    }    
  }
}


Gruß Jürgen
« Last Edit: January 03, 2010, 07:23:38 am by neubi » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi! möchte auch die messenger.h verwenden!
wollt nur fragen wie das bei dem adruino mega port aussieht! wie setze ich da die rx tx ports!? da sind ja mehrere drauf!
« Last Edit: January 20, 2010, 01:24:18 pm by sumsi » Logged

Weinsberg, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 770
A Coder's Tale
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Also ich könnte mich irren (mein Arduino ist noch in der Post und ich kanns nicht testen und mit C hab ichs auch nicht so), aber es könnte sein, dass Ersteres deshalb geht, weil "buffer" eine Stelle im Speicher beschreibt, an der 50 "char"s liegen (wurde durch die Definition "char buffer[50];" so festgelegt), also 50 Zahlen mit Werten zwischen 0 und 255. 'e' in einfachen Anführungszeichen wird auch als Zahl interpretiert (im ASCII-Alphabet ist das dann die 101); wenn nun also die zweite Zahl hinter dem Anfang von "buffer" eine 101 ist, dann greift die IF-Klausel, weil "==" zwei Zahlen direkt vergleicht.

Das Problem ist nun, dass "test" mit doppelten Anführungszeichen im Speicher auch eine Liste aus chars ist (das Konstrukt eines Wortes, also "String", ist in C von Haus aus nicht bekannt, soweit ich weiß). Diese Liste ist vier Zahlen lang (eigentlich fünf, weil ganz hinten noch eine 0 steht, quasi als Markierung, dass hier Schluß ist), und "buffer" und "test" sind damit eigentlich keine Wörter sondern Zeiger auf die Anfangspositionen der beiden Listen.

Wenn Du nun beide mit "==" vergleichst, dann vergleichst Du nicht die Inhalte der Listen sondern die genaue Position der beiden Listen im Speicher, und die ist natürlich unterschiedlich.

Funktionieren müsste eigentlich "if (buffer[0]=='t' && buffer[1]=='e' && buffer[2]=='s' && buffer[3]=='t')", aber wie gesagt möge man mich korrigieren, wenn ich falsch liege.
smiley
« Last Edit: February 02, 2010, 02:06:13 pm by Joghurt » Logged

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3418
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sehr richtig erkannt. "test" und buffer sind vom Typ char* und deshalb werden die Pointer verglichen. Und die sind nie gleich. Deshalb vergleicht man strings auch mit strcmp.

http://home.fhtw-berlin.de/~junghans/cref/FUNCTIONS/strcmp.html

Gruß, Udo
Logged

Check out my experiments http://blog.blinkenlight.net

Dresden / Germany
Offline Offline
Sr. Member
****
Karma: 3
Posts: 451
Entwicklungsklaus
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, ich habe das über die PString Library gelöst... das ist wohl mal ein Trunk gewesen von Messenger... sofern ich mich richtig erinnere...

Code:
#include <PString.h>

int z=0;
char temp[12];
PString befehlszeile(temp, sizeof(temp));
int empfangenesbyte;

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


void loop() {

  if (Serial.available()){
  empfangenesbyte=Serial.read();
  
  
  
  
  switch (empfangenesbyte) {
    
    case 63:
        befehlszeile.begin();
        empfangenesbyte=0;
        break;
  
    default:
        befehlszeile.print(char(empfangenesbyte));
  
                          }
   }




  if (befehlszeile.length()==11){
  
    
  if (temp[0] == '#' && temp[10] == '#') {
    Serial.println(befehlszeile);
    Serial.println("Befehl empfangen.");
  }
  else
  { Serial.println("Nutzdaten");
Serial.println(befehlszeile);  
}
  
    befehlszeile.begin();  
  }
 

Somit kann ich alles Mögliche übertragen, allerdings wenn dort in einem Abstand von 10 Zeichen Dopelkreuze vorkommen, wird der Inhalt zwischen den Doppelkreuzen als Nutzdaten interpretiert...

Da das ganze in den PString"puffer" läuft... geht auch nichts verloren.
Sofern nicht schneller Daten anliegen als der Arduino abarbeiten kann... dafür müßte man noch einen Readystate einbauen...

War nur ein Versuch, aber vielleicht für Dich auch ein Ansatz...

Lieber Gruß
ChrisS
Logged

Sturmfabrik - mediale Dienstleistungen
www.sturmfabrik.de

Pages: [1]   Go Up
Jump to: