Shop OBEX P1 Docs P2 Docs Learn Events
Incoming command — Parallax Forums

Incoming command

bboy8012bboy8012 Posts: 153
edited 2009-04-06 23:48 in Propeller 1
I am sending a·message with 2 commands·from C# to the propeller serially like this ("#", 1000, 1500, CR). My question is how do I go about splitting the message. I tried using the gpsIO_mini object well a form of it but no luck. Bytes 0-4 are for the first and 5-9 are the second. Thanks for the input

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-04-05 21:09
    Hello bboy,

    from the info provided by you to it is not clear to me what is the first command ? what is the second ?

    I guess "1000" is the first command "1500" is the second.

    I would scan the string for commas.
    after frist comma first command starts
    after having found the second comma you know the position of second comma - 1 is end of command 1
    position after second comma until CR is the second command

    If the positions are fixed IN EVEREY CASE
    you can use

    Pseudocode

    Command1[noparse][[/noparse] 0] := Commandstring[noparse][[/noparse] 4] ..Commandstring[noparse][[/noparse] 7]
    Command1[noparse][[/noparse] 0] := Commandstring[noparse][[/noparse] 8] ..Commandstring[noparse][[/noparse] 11]

    best regards

    Stefan

    Post Edited (StefanL38) : 4/5/2009 9:30:34 PM GMT
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-05 21:46
    Correct the command values are say 1000, 1500. Not really understanding how you explained coulc you provide and example. I have been testing out various stages of the code, and it seems I am getting stuff, just not the right stuff. here is an example of my debugging.

    PUB readCMD | index
      null[noparse][[/noparse]0] := 0
      repeat
        longfill(cmdBuff, 50, 0)
        repeat while  Rx <>= "#"
          Rx := uart.Rx
          
        cptr:= 0
        repeat while Rx <>= CR
          Rx := uart.Rx
          if Rx == ","
            cmdBuff[noparse][[/noparse]cptr++] := "0"
          else
            cmdBuff[noparse][[/noparse]cptr++] := Rx
            
        'copy_buffer(@messageB, @messageA)
        
            text.Dec(cmdBuff[noparse][[/noparse]0])
            text.Out(13)
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-04-05 22:36
    Hello bboy,

    I would prefer using the Extended_FDSerial-object from the obex.

    inside this object is a method called "RxStr"

    this methods does all the details for receiving a string and store the string into a bytearray

    After RxStr has done this for you you can easily access the bytes in the bytearray as described above

    your codeline

       text.Dec(cmdBuff[noparse][[/noparse]0])
    
    



    shows the first ASCII-code of the 4 received characters "1000"


    It's not really dificult to interpret commands like "1000", "1500"
    it takes 2-4 hours to code (AND TEST!) something like that

    But to be honest: I'm not in the mood to code it right now.

    Do you have a chance to modify the C-code of the sending device that it sends SINGLE bytes ?
    this would make things easier

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-06 06:09
    From your C# pseudo code line you gave us ("#",1000,1500,CR), I'd like to know whether you're really sending what you expect. "#" seems to be a one character string # followed by number 1000, number 1500 and a character Carriage Return. In C# notation I would expect that it sends the two numbers as binary data, with no commas send at all.

    My starting poind would be:
    Receive all data without changing anything and echo it to a display to check if you really get what you expect.
    If you receive the right data it's easy to split it up in seperate strings.
    For example: if you receive a comma, you can immediately replace it with a 0 in the receive buffer, which is stringend in SPIN.
    Then the buffer-adress points to the first string, which is the #
    2nd string-adress := buffer-adress + strlen(buffer-adress)+1
    3rd string-adress := 2nd string-adress + strlen(2nd string-adress)+1
    CR string-adress := 3rd string-adress + strlen(3rd string-adress)+1
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 13:50
    As I start to look at the results from this:
    PUB readMessage | index, throttle
      repeat
      
        repeat index from 0 to 10
          inBuffer[noparse][[/noparse]index] := uart.rx
        throttle := conv.DecimalToNumber(@inBuffer[noparse][[/noparse]0])
        text.Dec(throttle)
        text.Out(13)
    

    It is giving me the random numbers like this 105601000 which is the to slider positions on the C# form. But the positions are coming once every three times I move them. Attached is the file·for more insight. Thanks MagI02 I will try that method, thanks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-04-06 14:28
    hello bboy,

    I put your code into my PPDB and started analysing it.

    I'm willing to help but in a special manner.
    I want you to learn debugging

    If somebody else would like to help in a more dircect way feel free to do it.

    Post me a suggestion how you can ANALYSE the received string BYTE BY BYTE

    if the analysing does not work post me a question


    As a hint: Do you have an working example where the DecimalToNumber-method is working properly ?
    analyse this example byte for byte

    best regards

    Stefan

    Post Edited (StefanL38) : 4/6/2009 5:35:03 PM GMT
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 19:32
    The DecimalToNumber worked with the above code when it was just one string i.e. "1000".
    PUB RecieveData | index, oldPulse
      repeat
      
        repeat index from 0 to 4
          inBuffer[noparse][[/noparse]index] := uart.rx
        uartPulse := conv.DecimalToNumber(@inBuffer[noparse][[/noparse]0])
        text.Dec(uartPulse)
        text.Out(13)
        if (uartPulse <> oldPulse)
            'text.Dec(oldPulse)                                                 'If uartPulse changes for set for new pulse
            servo.set(throttlePin, uartPulse)
            
        else
          'text.Dec(oldPulse)                                                    'If values dont change throttle stays the same
          servo.set(throttlePin, oldPulse) 
          oldPulse := uartPulse
    
    

    The incoming number was 4 bytes, and the inBuffer array was 5 bytes giving it the extra zero it needed to terminate that string. This worked flawlessly when I moved the slider on my C# form it the numbers that prop output was the same. My problem is with comma delimited commands. But now when that I have added an extra command, and the commas, I get random output. i.e.

    slider postions, (1276, 1490)·I get 1276014901. My first thought is the array sizes. But I ultimately want to get away from using the DecimalToNumber method, and create my own. Let me start the process from scratch to learn what is happening. I will post what I have in like an hour.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 20:43
    Started all over using Extended_FDSerial, going to learn the basics of this.
      repeat
        uart.RxStr(@cmdBuff)
        text.Dec(@cmdBuff)
        text.Out(13) 
    
    

    Results:

    4268
    4268
    4268
    4268
    ...
    



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 20:55
    First problem was using text.Dec(@cmdBuff) instead on text.Str(@cmdBuff) Fixed.
    results were what I wanted, minus the comma. I·guess the rxStr() removes them for you?·Next problem is how to get @cmdBuff[noparse][[/noparse]0] only to display the first command instead of the whole command?

    PUB readMessage3 | throttle, yaw
      repeat
        uart.RxStr(@cmdBuff)
        throttle := @cmdBuff[noparse][[/noparse]4] 'displays values when move slider
        yaw := @cmdBuff[noparse][[/noparse]0] ??????? displays 15001000 want to display 1500
        text.Str(throttle)
        text.Str(String(","))
        text.Str(yaw)
        text.Out(13)
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (bboy8012) : 4/6/2009 9:10:35 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-06 21:11
    Hi bboy,

    I don't understand why you convert it from integer to string on C# side and then you convert it back from string to integer on propeller side and complain about the conversation. As long as the data send is only to be read by processors you simply can send raw binary data. This has several advantages:
    No conversion needed
    fixed size
    shorter messages

    Say your numbers are in a range of 0-65535 you only transfer 2 bytes per number.

    I don't know what other data you want to transfer. So, it might make sense to send one byte in front showing which data comes and then the two numbers in this case. If you send other data as well you give that data package another number.

    All in all this would make 5 bytes for this package.

    That's what you call a protocoll.
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 22:30
    The reason I did it this way, is this is how someone showed me how to receive it. I havent yet learned to receive bytes. Also there are only 2 ways to send data from C# as a string or a byte array. I have tried to figure out how to receive arrays of byte but not yet have figured it out.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • bboy8012bboy8012 Posts: 153
    edited 2009-04-06 23:48
    @MagI02,
    After rereading you reply, I get ya. I guess this is just to verify the correct values are coming through. Of course I could do it on the C# side, which I will, but seeing as I got this far and only thing left for me to do is figure out how to get just the first bit of the command I am done. But I am going to do what you suggested once i am comfortable sending data from PC to prop. Still a beginner!

    @All
    Another question, how do I just get the first say 4 bytes of an array?
    PUB readMessageStr
      repeat
        uart.RxStr(@cmdBuff)
        throttle := @cmdBuff[noparse][[/noparse]4]
        yaw := @cmdBuff[noparse][[/noparse]0]  <---gives whole value need only first four values
        text.Str(throttle)
        text.Str(String(","))
        text.Str(yaw)
        text.Out(13) 
    


    Have tried yaw := @cmdBuff[noparse][[/noparse]0] + 1, and understand it just shifts it one.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sign In or Register to comment.