Pages: [1]   Go Down
Author Topic: Trouble with String or character array comparison.  (Read 4850 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Greetings,

I've been having some trouble with developing the beginnings of a simple wireless communication protocol. I want one module to have a piece of data to transmit, while the other will receive it once it is in range after some handshaking. The stationary module will transmit "Hello!" over and over. When the other module has received this twice, it will send back an acknowledgement. Then the stationary module will send a piece of data until it receives confirmation that it was received. After all of this it will stop transmitting.

That's a bit of background information about my goals. In part of my code I need to count how many "Hello!"s have been received, and am trying to do so with a comparison. The comparison NEVER triggers, even though I print it out right before I do the comparison and it appears equivalent to what I'm comparing it against. I've tried using strings with strcmp and also Strings with .equals(), but the same thing happens in both cases.

All of the code is a bit messy as I've been tinkering with it a bunch and it's really a very rough draft to begin with, so please pardon my mess. ^^; Here is a portion of the code from one module:
Code:
int inByte = 0;
int inputSize = 0;
char incomingByte;
String command = "";
int helloCount = 0;
int coord = 0;
String hello = "Hello!"; //Previously used for a string .equals comparison attempt as double quotes are character arrays.
void setup()
{
  Serial.begin(9600);
}

void loop()
{
 
  if(Serial.available() > 0){
      incomingByte = Serial.read();
      if(incomingByte== 10){
        processCommand(command);
        //Serial.println(command);
        command = "";
      }
      else{
        command += incomingByte;
      }
  }
}
void processCommand(String theCommand){
  char myCmd[128] = ""; //create a character array to hold the converted String
  Serial.println("Processing command");
  theCommand.toCharArray(myCmd,128); //Convert the String to CharArray.
  //Serial.println(strcmp(myCmd, "Hello!"));
  Serial.println(myCmd); //This prints "Hello!"
 if(strcmp(myCmd, "Hello!") == 0){
   Serial.println("Got the Hello"); //This code is never reached.
   helloCount++;
   if(helloCount >= 2){
    Serial.print('Y'); //Say hello back.
   delay(1000);
   }
 }
 else{
  if(theCommand[0] > 47 && theCommand[0] < 58 && helloCount >= 2){ //decimal (coordinate)
   char * tempPointer;
   theCommand.toCharArray(tempPointer, 20);
   coord = atoi(tempPointer);
   Serial.println(coord);
   Serial.write('T'); //say thanks
   delay(1000);
   helloCount = 0;
  }
}
}
And here is the code from the stationary module:
Code:
int state = 0;
//0 = hello!, 1 = coordinate, 2 = finished.
int incomingByte;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if(state == 0){
    if(Serial.available() > 0){
      incomingByte = Serial.read();
      if(incomingByte == 'Y'){ //They said hello back.
       state = 1;
       }
    }
    else{
      delay(1000);
      Serial.println("Hello!");
        }
  }
  if(state == 1){
   if(Serial.available()>0){
    incomingByte = Serial.read();
    if(incomingByte == 'T'){ //They said thanks.
     state = 2;
    }
   }
   else{
      Serial.println("5");
      delay(1000);
   }
  }
  if(state == 2){
    delay(1000);
    Serial.println("I've done my time. End.");
  }
}

Some additional information: I'm using xBee series 1 wireless modules on arduino uno boards in their standard communication mode (ie, not command mode). I know that they are able to communicate with each other, and I even know that one of my boards is receiving "Hello!", but the comparison doesn't trigger.

This one has had me stumped for a while. Any insights would be greatly appreciated.

-Pher
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50115
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't see what the problem is, but processCommand() is unnecessarily complicated. You could just use
Code:
if(theCommand == "Hello!")
without the need to extract the data to a char array.

Code:
  char myCmd[128] = ""; //create a character array to hold the converted String
  Serial.println("Processing command");
  theCommand.toCharArray(myCmd,128); //Convert the String to CharArray.
If you are going to immediately overwrite the contents of myCmd, what is the point in assigning it an initial value?

Code:
   char * tempPointer;
   theCommand.toCharArray(tempPointer, 20);
This absolutely, unequivocally, will NOT work. tempPointer does NOT point to any space to unload the character array to.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your suggestions, PaulS. I suppose you're right. There really is no point to assign that character array something if I immediately overwrite it. The pointer also requires an address of somewhere to point, so thanks for that as well.

 Attempting the comparison in the form if(theCommand == "Hello!") was my first attempt, but didn't appear to work.
I just changed it to:
Code:
Serial.println("Processing command");
  Serial.println(theCommand);
 if(theCommand == "Hello!"){
   Serial.println("Got the Hello"); //This code is never reached.
   ...
   }

When I view the code running in the serial monitor all I get over and over is:
"Processing command
Hello!"
It still never manges to reach the portion of code where it prints "Got the Hello". Peculiar.  smiley-confuse
« Last Edit: February 27, 2011, 07:55:46 pm by pheria » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50115
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This suggests that there are non-printing characters embedded in the string.

Try adding this before the comparison:
Code:
int sLen = theCommand.length();
for(int s=0; s<sLen; s++)
{
   Serial.print("theCommand[");
   Serial.print(s);
   Serial.print("] is {");
   Serial.print(theCommand[s]);
   Serial.print("} which has an ascii value of ");
   Serial.println(theCommand[s], DEC);
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great idea, PaulS. However, after running it that doesn't appear to be the case either.

The serial monitor prints this repeatedly:
"Processing command
Hello!

theCommand[0] is {H} which has an ascii value of 72
theCommand[1] is {e} which has an ascii value of 101
theCommand[2] is {l} which has an ascii value of 108
theCommand[3] is {l} which has an ascii value of 108
theCommand[4] is {o} which has an ascii value of 111
theCommand[5] is {!} which has an ascii value of 33
theCommand[6] is {} which has an ascii value of 13
Processing command
Hello!

theCommand[0] is {H} which has an ascii value of 72
theCommand[1] is {e} which has an ascii value of 101
theCommand[2] is {l} which has an ascii value of 108
theCommand[3] is {l} which has an ascii value of 108
theCommand[4] is {o} which has an ascii value of 111
theCommand[5] is {!} which has an ascii value of 33
theCommand[6] is {} which has an ascii value of 13"

I even attempted to change the comparison to if(theCommand == ("Hello!" + '\n')), but get the same result mentioned above.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Got it!
Carriage returns (ASCII 13) != line feeds (ASCII 10), for one thing. So checking if(theCommand == "Hello\n") didn't work.

When I change the comparison to if(theCommand == ("Hello!\r")), my comparison triggers. Thanks a lot for your insights PaulS. Cheers. =]
Logged

Pages: [1]   Go Up
Jump to: