Pages: [1] 2   Go Down
Author Topic: Serial parsing with Serial Proxy  (Read 2239 times)
0 Members and 1 Guest are viewing this topic.
Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//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

 
« Last Edit: July 14, 2011, 12:31:39 pm by MobileWill » Logged

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

http://mobilewill.blogspot.com

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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

http://mobilewill.blogspot.com

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 637
Posts: 50299
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
    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?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26495
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while(Serial.available() <= 0);
        in_char = Serial.read();
        cmd[i] = in_char;
 
        i++;
Let's hope "i" doesn't get too large.
Like 1.
Logged

"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.

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 637
Posts: 50299
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: July 14, 2011, 02:34:46 pm by MobileWill » Logged

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

http://mobilewill.blogspot.com

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26495
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops!
Read "cmd1" as "cmd".
Apologies.
Logged

"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.

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

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

http://mobilewill.blogspot.com

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 637
Posts: 50299
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
if (in_char == '#')


Logged

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

http://mobilewill.blogspot.com

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 637
Posts: 50299
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So I would just use single quotes
Just like that.
Logged

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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

http://mobilewill.blogspot.com

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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

http://mobilewill.blogspot.com

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think it is hanging up here

Code:
//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:
 
     in_char=Serial.read();

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

After speak();
Code:
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.
« Last Edit: July 14, 2011, 10:04:02 pm by MobileWill » Logged

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

http://mobilewill.blogspot.com

Monterey CA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Addicted to Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
    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.
Logged

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

http://mobilewill.blogspot.com

Pages: [1] 2   Go Up
Jump to: