Go Down

Topic: Serial parsing with Serial Proxy (Read 2561 times) previous topic - next topic

MobileWill

Jul 14, 2011, 06:55 pm Last Edit: Jul 14, 2011, 07:31 pm by MobileWill Reason: 1
I am working on a security robot that has a speakjet shield. I have modified the sparkfun speakjet example to look for '/' and parse that as a command instead of text to speak.

It works great with usb and xbee. My problem is when I use serial proxy to make the xbee IP addressable (using tinker proxy build). The first time is works correctly but the send time it will speak the command instead of seeing it as a command.

I had a hard time getting the parsing to work originally. It has been great since but now I am working on my control app/website and I found this bug.

Here is the code I am using to parse incoming command/text from the serial port. Which currently is a Xbee, will be Wifi Shield later on. But it looks like it is a code problem as it works without serial proxy.

I am sure this code can be written better but this is how I got it work at all.

Code: [Select]

//Function: getMessage(char *)
//Description: Retrieves a string from the Serial port. Doesn't return the string until a carriage return character is detected.
//Inputs: None
//Outputs: char * message - The message received on the serial port.
//Returns: Nothing
//usage: getMessage(english_sentance);
void getMessage(char * message, char * message2)
{
   char cmd[5]="";    //Array to hold the code char during serial read
   char in_char=0;    //Create a character to store the incoming byte from the serial port.
   int i = 0;
   int value = 0;
   char cmd1[1]="";
   
   
   //Wait for a character to come into the serial port (Old way, causes code to stop here)
   //while(Serial.available() <=0);

   //Check for charcter from Xbee/Wifi and if not resume to main loop else process charcaters
   if (Serial.available())
   {
       
   //Copy the incoming character to our variable.
   in_char=Serial.read();
 
   if (in_char == 0x2f)
   {
     while(in_char != 0x0D)
     {
       while(Serial.available() <= 0);
       in_char = Serial.read();
       cmd[i] = in_char;
 
       i++;
     }
     cmd[i]='\0';
     
     cmd1[0] = cmd[0];
           
     for (int x = 0; x <= i; x++)
     {
      cmd[x] = cmd[x+1];
       
     }

     
     value = atoi(cmd);
     
     
     pCmd(cmd1[0], value);    
     
     
     
   }
   else {
   //For SpeakJet Phrases
   //Keep retreiving characters until the 'end of sentance(0x0D)' character is received.
   while(in_char != 0x0D){
       if (in_char == 0x5C)
       {
         for(int i = 0; i <= 2; i++){      //Change to look for digits, would allow shorter codes
         while(Serial.available() <=0);    //Now wait for the next character...
         in_char = Serial.read();    
         cmd[i]=in_char;
         }
   
        int code = atoi(cmd);  //convert code from char array to single int
        *message++=code;  //put code inline with message
        while(Serial.available() <=0);
        in_char = Serial.read();
       }
       else {
       *message++=in_char;    //Every time we receive a character we should add the character to the message string.
       *message2++=in_char;
       while(Serial.available() <=0);    //Now wait for the next character...
       in_char = Serial.read();            //and copy it to the variable again.
   }
   }
  *message='\0';    //Strings must end with a Null terminator so we need to add this to our message.
  *message2='\0';

   speak();
   }  
 
   }
   return;
}


So basically it looks at the first char to determine if its a command or not. So serial proxy must being doing something different to cause the If statement not to see it as a /.

Thanks for the help. After this I can work on my robot control app and website.

I am using these parts.

http://www.sparkfun.com/products/9799

with

http://www.sparkfun.com/products/9811

Tinker Proxy site that has source
http://code.google.com/p/tinkerit/wiki/TinkerProxy

Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

I am thinking it might better to talk directly to the serial port from asp.net. I saw that it is possible. I still prefer the above but I could plug the Xbee to my VM and have the web server talk directly.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Code: [Select]
    char cmd1[1]="";
Why a one element array? What's wrong with
Code: [Select]
char cmd1;

Code: [Select]
    if (in_char == 0x2f)
      while(in_char != 0x0D)
    while(in_char != 0x0D){
        if (in_char == 0x5C)

Drat. Left me cheat sheet at home. What's a 0x2f? There is no key on my keyboard with that symbol on it. 0x5C? 0x0D? That's a '\n' isn't it?

AWOL

Code: [Select]
while(Serial.available() <= 0);
        in_char = Serial.read();
        cmd[i] = in_char;
 
        i++;

Let's hope "i" doesn't get too large.
Like 1.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
Let's hope "i" doesn't get too large.
Like 1.

Why would i == 1 cause a problem? cmd is a 5 element array.

MobileWill

#5
Jul 14, 2011, 09:32 pm Last Edit: Jul 14, 2011, 09:34 pm by MobileWill Reason: 1
0x2f is '/' which is my char to check to see if the rest of the input is a command. Is that isn't there then it is text to speak.

Not sure why I did cmd1[1]. I can change that but I don't think it will make a difference.


cmd is just for the /f4 which is move forward speed 4. pcmd function handles that.

cmd1 separates the command 'f' from the value 4 to be passed. And then I remove the '/' from cmd.

I am sure there is a better way to handle this.

I realize i need to go back and comment  rename variables as this was my first attempt and I left it once it worked till now.


Edit:

The speak function also looks for text with \<digits> for sounds codes for the speakjet.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

AWOL

Oops!
Read "cmd1" as "cmd".
Apologies.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

MobileWill

No problem. I will have to clean that up. I dont' usually do that.

So what do you guys think? Have asp.net talk to serial port or maybe change the char for command? Its really weird. My robot will actually say "slash f" lol. It has to be the way that the serial to ip proxy software handles characters.

Is there another way I can check for command character?
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

The forward slash may have significance to some software along the way. Is there some other character you could use? Semi-colon maybe? Or question mark?

The reason I asked about the 0x2f value was that it is much easier (for me) to understand code that uses actual ascii characters in the if tests. The compiler doesn't care.

MobileWill

Thanks. I will try another character.

I know what you mean, I had just used the hex because the code was based on an example. So I would just use single quotes


Code: [Select]
if (in_char == '#')


Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

PaulS

Quote
So I would just use single quotes

Just like that.

MobileWill

So I tired a few different characters and nothings work. The funny thing it works the first time after a reboot.

Okay did some messing around and I think what is happening the speak function isn't ending or somewhere the code is waiting. My robot has a lcd with sensor output and I noticed after i send a command using serial proxy it stops updating. If I send another command it updates once. So something is causing the serial input to be waiting.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

On a side note, would the functions run faster if I didn't have it recreate the array's every iteration?  This function is called from loop continuously. Or maybe move this code to the loop()? I do have speed problems in reacting to a object not being fast enough.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

#13
Jul 15, 2011, 04:44 am Last Edit: Jul 15, 2011, 05:04 am by MobileWill Reason: 1
I think it is hanging up here

Code: [Select]
//Check for charcter from Xbee/Wifi and if not resume to main loop else process charcaters
   if (Serial.available())
   {


Since it works the first time and then after that is goes back to the loop and then gets stuck somewhere.

I think that it things the serial is available and then since there isn't a '/' it goes to the speak part and waits for text.

There must be something with serial proxy causing the serial to be triggered as available.

Does serial.available mean there is data to receive?

Would my function work without the serial.available and just constantly read the serial port or is there a better way because that would probably slow things down.



Edit: I added this and now it works every other time.

after  speak();
Code: [Select]
 
    in_char=Serial.read();


Edit:
So I did a work around, not very clean but it works.

After speak();
Code: [Select]
speak();
   if (Serial.available())
   {
    in_char=Serial.read();
    }


Which still causes it every other command but if I send a Carriage Return before I send a command it works. With the if statement above it doesn't affect the commands if I am not using serial proxy and talking directly to the serial port.

If I get some time I might peak at the serial proxy source and see if I can figure it out. It didn't affect my first robot but it was much simpler.

I guess I found a bug in serial proxy.

Thanks for all the help it got me thinking looking in the right direction. This will get my by for now.

If anyone has a better work around let me know.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

MobileWill

Now I am seeing another problem.

I am not seeing the return data in asp.net, I do when I telnet to serial proxy.

Here is my code in vb.net for the website.

Code: [Select]

    Protected Sub btnCamera_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCamera.Click

        clientSocket.Connect(serverIP2, serverPort2)

        Dim serverStream As NetworkStream = clientSocket.GetStream()
        Dim outStream As Byte() = System.Text.Encoding.ASCII.GetBytes(vbCrLf + cmdCamera + vbCrLf)
        Dim inStream(10024) As Byte
        serverStream.Write(outStream, 0, outStream.Length)
        serverStream.Flush()
        serverStream.Read(inStream, 0, CInt(clientSocket.ReceiveBufferSize))
        Dim returndata As String = System.Text.Encoding.ASCII.GetString(inStream)
        lblReturn.Text = returndata
        clientSocket.Close()

    End Sub


It was displaying the data returned but now I get nothing. I doubt the asp.net code would cause the problem. I might need a better solution to my work around. I don't know.
Current Projects:                    Arduinos:
Security Robot Tank               Uno
Security Robot II 4WD            Mega2560

http://mobilewill.blogspot.com

Go Up