Go Down

Topic: Kommunikation PC und Arduino (Read 1 time) previous topic - next topic

kucky

Jul 14, 2011, 11:50 am Last Edit: Jul 14, 2011, 05:55 pm by kucky Reason: 1
Liebe Leute,
auch wenn ich hier vielleicht dieselbe Frage nochmal stelle. Ich kapier´s nicht. Mein Sohn hat mir ein kleines Consolenprogramm in C# geschrieben, mit dem ich meinen Bot per Bluetooth fernsteuern möchte. Und das klappt mit "einfachen Zeichen" wie 1 und 2. Nun möchte ich aber sprechenden Code erzeugen, und somit Zeichenketten, die von der Console gesendet werden, auswerten. Die Console arbeitet einwandfrei.

Hier der Code:

messageConsol ist als String global deklariert.

Code: [Select]
void SerialRead_Keyboard(){
char incomingSign;
bool messageComplete = false;

   messageConsol = "";

 if (Serial.available() > 0)
 {
   while((Serial.available() > 0) & (!messageComplete))
   {
incomingSign = Serial.read();
delay(1);
if (incomingSign != '\r'){
messageConsol += incomingSign;
}
else {
//messageConsol += '\0';
messageComplete = true;
Serial1.print("messageComplete = true - ");Serial1.println(messageConsol);
}
   }
//    messageConsol = "";
 }
}


Bis hier alles OK. Die Variable messageConsol zeigt das was sie soll. Dann die Auswertung:

Code: [Select]
void ConsolSystemState(void){

Serial1.print("ConsolSystemState,void - ");Serial1.println(messageConsol);  // bis hier alles OK

for (int i = 0; i < 2; i++)  {
 strcpy_P(systemBuf, (char*)pgm_read_word(&(system_table[i])));
 Serial1.print("System Buffer - ");Serial1.print(systemBuf);              // auch hier noch alles in Butter
 Serial1.print("system_table[i] - ");Serial1.println(i);                       // auch das stimmt

 if (messageConsol == systemBuf)  {            // Hier liegt der Hase im Pfeffer glaub´ ich
 remote.systemControl = true; //????? is this important?
 Serial1.print("ConsolSystemState, match - ");Serial1.println(messageConsol);
 switch(i){
 case 0:

....... usw.


Bis hierhin
"Serial1.print("system_table - ");Serial1.println(i);" ist wieder alles OK. Aber die Abfrage "if (messageConsol == systemBuf)" liefert kein Ergebnis mehr, das heißt, die Switch/case wird nicht aufgerufen, obwohl "messageConsol" und "systemBuf" lt. der Kontrollausgaben übereinstimmen.

Der Vollständigkeit halber die PROGMEN Deklaration:

prog_char system_0[] PROGMEM = "System_Sleep";
   prog_char system_1[] PROGMEM = "System_WakeUp";
   prog_char system_2[] PROGMEM = "System_Reset";

   PROGMEM const char *system_table[] =
   {
     system_0,
     system_1,
     system_2,
   };
   char systemBuf[14];

Was mache ich falsch?
Gruß
Kucky

pete62

Wie schon vermutet liegt der Fehler im Vergleich der beiden Strings. Das geht nur über die Funktion strcmp().
Code: [Select]
if (strcmp(messageConsol, systemBuf)  == 0)

kucky

Hallo Pete62,
Danke für die schnelle Antwort.
Wenn ich aber strcmp benutze, gibt es die Meldung "cannot convert 'String' to 'const char' for Argument '1'. Hab´ das auch schon mal vertausch versucht.
Gruß Kucky

kucky

Ich noch mal,
könnte das der Grund sein?

http://www.arduino.cc/en/Reference/PROGMEM
Code: [Select]

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

PROGMEM const char *string_table[] = // change "string_table" name to suit
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5 };

char buffer[30];  // make sure this is large enough for the largest string it must hold

anschließend geht es so weiter

Code: [Select]
for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println( buffer );
delay( 500 );
}


Ich habe nun von diesen Domainen (prog_char string_0[] PROGMEM = "String 0" aber 5 verschiedene, die ich alle nach obrigem Muster gemacht habe. Aber woher weiß die Variable char buffer[30] das sie zu dem darüberliegen Construkt gehört? Ich habe die auch schon mal in einen anderen Codeteil verschoben, Compiler sag OK.

Beispiel für eine der anderen Domänen:
Code: [Select]

    prog_char system_0[] PROGMEM = "System_Sleep";
    prog_char system_1[] PROGMEM = "System_WakeUp";
    prog_char system_2[] PROGMEM = "System_Reset";

    PROGMEM const char *system_table[] =
    {
      system_0,
      system_1,
      system_2,
    };
    char systemBuf[14];


Gruß Willi

kucky

Also das mit der Variablen ist geklärt. Das restliche Rätsel bleibt.

kucky

Hallo zusammen,
ich glaub ich hab´s hinbekommen.
Von der PC-Console kommen Zeichen in der Form von z.B. "Camera_Right\r"; Diese werden im Programm wie folgt empfangen und verarbeitet:
Code: [Select]

char consolMessage[30]; (global)

void SerialRead_Keyboard(){
char incomingSign;
bool messageComplete = false;
static int i = 0;

    for( int y = 0; y <= 30; y++){
    consolMessage[y] = '\0';
    }
  if (Serial.available() > 0)
  {
    while((Serial.available() > 0) & (!messageComplete))
    {
incomingSign = Serial.read();
delay(1);
if (incomingSign != '\r'){
consolMessage[i] += incomingSign;
Serial1.print("incomingSign - ");Serial1.print(incomingSign);Serial1.print(" - i - ");Serial1.println(i);
i++;
}
else {
messageComplete = true;
Serial1.print("messageComplete = true - ");Serial1.println(consolMessage);
i = 0;
}
    }
  }
}


Anschließend werden die Message wie folgt ausgewertet:
Code: [Select]

void ConsolSystemState(void){
char systemBuf[14]; (aus einer PROGMEN table)
Serial1.print("ConsolSystemState,void - ");Serial1.println(consolMessage);

for (int i = 0; i <= 2; i++)  {
  strcpy_P(systemBuf, (char*)pgm_read_word(&(system_table[i])));
  Serial1.print("System Buffer - ");Serial1.println(systemBuf);
  Serial1.print("system_table[i] - ");Serial1.println(i);

  if ((strcmp(consolMessage, systemBuf)) == 0)  {
 
  Serial1.print("ConsolSystemState, match - ");Serial1.println(consolMessage);
  switch(i){
  case 0:
  remote.systemControl = SYSTEM_SLEEP;
  Ausgabe1((char*)"ConsolSystemState sleep - \0", 9, i, 9, 9);
  break;
  case 1:
  remote.systemControl = SYSTEM_WAKEUP;
  Ausgabe1((char*)"ConsolSystemState wakeup - \0", 9, i, 9, 9);
  break;
  case 2:
  remote.systemControl = SYSTEM_RESET;
  Ausgabe1((char*)"ConsolSystemState reset - \0", 9, i, 9, 9);
  break;
  }
  }
}
}

Die einzelnen Ausgaben sind nur für´s Debugging!!

Es funktioniert einwandfrei. Ich bin mir aber fast sicher, dass man das besser machen kann. Z.B. das Löschen des char arrays. Lt. den Forenexperten reicht ein einfaches "consolMessage[0] = '\0';". Bei mir ging das nicht. Es kamen Zeichenketten heraus, die mit Steuerzeichen o.ä. anfingen, und am Ende kamen Teile der erwarteten Zeichen.
Gruß Willi

pete62

Hallo Willi,

anstatt das ganze array mit nullen zu füllen, müßte es reichen, nach Empfang des '\r' Zeichens ein '\0' Zeichen an den consolMessage String anzuhängen. Allerdings darf man dann nicht die empfagenen Zeichen mit += addieren, sondern muß zuweisen mit =:
Code: [Select]

if (incomingSign != '\r'){
consolMessage[i] = incomingSign;
Serial1.print("incomingSign - ");Serial1.print(incomingSign);Serial1.print(" - i - ");Serial1.println(i);
i++;
}
else {
consolMessage[i] = "\0';
messageComplete = true;
Serial1.print("messageComplete = true - ");Serial1.println(consolMessage);
i = 0;
}

Gruesse Peter

kucky

Hallo Peter,
werde ich heute abend versuchen. Vielen Dank erst einmal.

Gruß Willi

kucky

Hallo Peter,
es geht. Vielen Dank.
LG Willi

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview