Shop OBEX P1 Docs P2 Docs Learn Events
Trying to receive a long STRING via ExtendedFDSerial.SPIN — Parallax Forums

Trying to receive a long STRING via ExtendedFDSerial.SPIN

DavidMDavidM Posts: 626
edited 2008-04-09 04:13 in Propeller 1
HI,

I am having trouble receiving a string back from the UMP3 Player.

I am sending the UMP3 a command "PC V" which asks for the units software version info.

This string I think is up to 24 characters long plus a delimiter character at the end">"

I am using the ExtendedFDSerial Object as follows

Serial.RxStrTime (20,000, rxData)

The reason I have 20000 for the timeout ( which I believe is 20 seconds) is that the SD Card of the UMP3 player needs time to LOAD before any commands are recognized. The manual says up to 20 seconds, but it usually is about 3-5 seconds. Anyhow, this isnt the problem,

Q1) the problem is I am trying to get the data ( the string from the rxdata) back to my main program.

here is my method for initilising the MP3 Player of which I want to get the PlayerVersion info string and display it on my LCD ( which I have just figurered out).
Just as a note I can send commands to the ump3 player such as play stop etc and this works fine, so everthing is connected and functioning.
I am using a pointer to the "PlayerVersion" variable which is defined in my main object by using @PlayerVersion which is defined as


MAIN OBJECT
 
VAR
  BYTE PlayerVersion[noparse][[/noparse]25]
PUB
 IF (uMP3.Init (rxpin,txpin,0,baudrate,@PlayerVersion)==TRUE)
  '' then show the player version variable on an LCD display   
  '' else show that there is no player found





My uMP3 Object

VAR

  BYTE RxData[noparse][[/noparse]25]

PUB Init ( vRxPin, vTxPin, 0, vBaudRate, PtrPlayerVersion) : Status

 Serial.Start ( vRxPin , vTxPin, 0, vBaudrate) : Status | rxData
 Serial.SetDelimiter (">")
 Serial.RxFlush
 Serial.Str(STRING("PC V"))
 Serial.Str(STRING(13)

 Serial.RxStrTime(20_000,RxData)
 IF (rxdata<>0)'' check if there is any data
  Status :=True
  '' do something here with the actual rx data to get it back as a string to the PlayerVersion variable"<---- THIS IS THE PART I NEED SOME HELP WITH [img]http://forums.parallax.com/images/smilies/smile.gif[/img]
 ELSE
 Status :=FALSE
RETURN Status





Any help would be great as I am totally confused with strings and SPIN!

regards

DaveM

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2008-04-08 18:39
    Hello David,

    in SPIN strings are seen as a "chain" of bytevalues inside the RAM. These bytevalues are the ASCII-codes of the characters of the string

    In programming you can access such a "chain" with an array like you defined it

    VAR
      BYTE PlayerVersion[noparse][[/noparse]25]
    
      Serial.Str(STRING(13)  '<--- here one closing-bracket is missing does this compile ?
    
    



    RxStrTime can receive a string with maximum 15 bytes like the comment of the method says

    for a string of 25 bytes you have to change some values inside the
    file FullDuplexSerial.spin which is used by the Extended_FDSerial-object
    AND the datain-array AND inside RxStrTime

    This is not trivial but you can do it.

    Then for receiving the string by RxStrTime the parameter of the methodcall has to be the POINTER to that string

    
       Serial.RxStrTime(20_000,PtrPlayerVersion)
    
    




    another solution depending on your baudrate might be to use a loop that receives single bytes and transfers these bytes to your array PlayerVersion


    accessing the bytes in the array looks like this


    
      PtrPlayerVersion := @PlayerVersion
      index := 0
    
      repeat until receivedByte == Delimiter
        receivedByte := Serial.Rx
        byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index] := receivedByte
        index++
    
      byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index - 1] := 0 ' finish with a zero instead of delimiter
    
    
    



    byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index] is an absolute adressing

    PtrPlayerVersion := @PlayerVersion means store RAM-ADRESS of bytearray PlayerVersion in variable PtrPlayerVersion

    byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index] := receivedByte

    means store value of variable receivedByte at RAM-Adress PtrPlayerVersion + index

    example

    bytearray PlayerVersion is located in the RAM at adress 20.480

    index has value 5

    variable receivedByte contains the value 65 (ASCI-code for "A")

    then byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index] := receivedByte

    stores the value 65 at RAM-adress 20.480 + 5 = 20.485

    and if you want to show this "A" on the LCD you have to code

      index := 5
      LCDSerial.tx(byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]index])
    
    




    or if you want to show the whole string

    LCDSerial.Str(PtrPlayerVersion)

    in SPIN strings can only be represented by bytearrays
    and you are accessing them via the POINTER to the RAM-Adress where the bytearray is stored

    this explanation is semi-extended

    if you have more questions about feel free to ask again

    best regards

    Stefan

    Post Edited (StefanL38) : 4/9/2008 7:53:25 AM GMT
  • DavidMDavidM Posts: 626
    edited 2008-04-08 22:02
    Hi Stefan!


    thanks for the extensive explanation! I really appreciate it.

    A1) I left accidently left off the closing bracket , as I had to retype my code into the browser.

    MODIFY the FD SERIAL OBJECT - OPTION

    Maybe not for me just yet, Unless someone else has done this? Is there a reason that its only 15 bytes?

    I like your second option where I just receive one byte at a time. I am running at 9600 baud so this should work.

    Also.

    There is another command for the MP3 player that gets a "list of songs" from the player, this can contain a lot of data so I will try out your "One byte at a time approach.

    In regards to the LCD , I have my own code which works so I am not worried about that.

    Again thanks for the great explanation!

    Regards

    Dave M
  • groggorygroggory Posts: 205
    edited 2008-04-08 22:08
    If you're using this semi-convoluted process on a regular basis to output to the LCD, you should probaly make a method that does it for you. Create some reusable code smile.gif
  • DavidMDavidM Posts: 626
    edited 2008-04-08 23:31
    Hi groggory

    I am not sure what you mean, I already have my own object that has all the commands for working with my LCD. Which is totally re-usable, I also said that the LCD was not the problem


    Thanks

    Dave M
  • DavidMDavidM Posts: 626
    edited 2008-04-09 04:13
    HI,

    Ok I have it all working.

    Lesson Learned

    Always check that you are sending the right command to the serial device before calling for help!

    I was using "PC V" when it should of been just been "V" , !!! Silly me.

    I used the index increment method you suggested and received 1 byte at a time.

    But I still was getting gibberish on my LCD as it did not like receiving a byte "String"

    This was fixed by using the following code..

    and for the LCD

    LCD.DisplayString (@PlayerVersion, 1, 1) <-- I had to use a pointer here as well!!

    and I received more data than I needed so I CUT-OFF the remaining data by setting the 6th byte to 0

    byte[noparse][[/noparse]PtrPlayerVersion][noparse][[/noparse]6] := 0

    I also managed to get the directory listing from the SD card using the same code!

    Thanks for the help

    Regards
    Dave M
Sign In or Register to comment.