Shop OBEX P1 Docs P2 Docs Learn Events
serial question — Parallax Forums

serial question

OwenOwen Posts: 100
edited 2007-04-18 20:35 in Propeller 1
Hi-
I want to send an array of longs from a host computer to the propellar without knowing how long the array is(the array size will almoste always overflow the serial buffer). How can I store the data in an array on the propellar while data is still coming in from the host computer without missing any data? what would be a good way to confrim that all the data was recieved? anyone have any example code of somthing like this?

Thanks,
Owen

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-14 21:56
    The beauty of the Propeller is that is has multiple processors. The FullDuplexSerial serial I/O driver is buffered (15 bytes) and the actual receive/transmit routine runs in its own cog. Take a look at the Extended Full Duplex Serial driver in the Propeller Object Exchange (ww1.parallax.com/Default.aspx?tabid=65) which will simplify your input decoding process. The FullDuplexSerial driver comes with the Propeller Tool as well and, as is true for many I/O drivers and other contributed programs, most of the documentation is in comments in the source program

    The Propeller is fast enough to receive information from the host computer probably up to 230KBaud, but certainly 115KBaud and can store it as fast as it arrives using one cog for the serial I/O driver and one for the main program.

    The best way to verify the received data is to include some kind of checksum or cyclic redundancy check (CRC) along with the data. Do a websearch on "wiki crc". You'll get en.wikipedia.org/wiki/Cyclic_redundancy_check which should lead you to more information than you probably want.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-14 22:03
    A good way to send an indefinite length table is to send it a hunk at a time, say up to 16 longs, each hunk with a checksum. The host computer should know at least what the size of a hunk is when it's sent and that size could be included in the message. The Propeller would receive the hunk knowing the size and verifying the checksum, store it, and send a short confirmation message to the host, ideally a hunk number (1 to n). The host would verify this and send the next hunk. If you expect errors, send the hunk size twice or once, then its complement or negated (for error checking).
  • OwenOwen Posts: 100
    edited 2007-04-14 22:46
    so to store the data would i just have a loop that takes one long at a time using ExtendedFullDuplexSerial.rxdec and then put it into an array then go back and get the next long repeating untill I recieve some kind of end of block byte? then check to see that I did recieve all the data expected and tell the host to send the next block of data? does anyone have an example of this? also is there any way to have an array that does not have a defind size so that it would adjust to the size of the serial data that comes in?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-14 23:16
    There are no such arrays in Spin. You have a couple of choices ...

    1) Declare the array to be the size of the largest possible array and use only as much of it as you need

    2) Since the Propeller loads programs and creates stack space from the "bottom" of memory upwards, you can do your own allocating of memory from the end of memory ($7FFF) downwards. The first long would be put at location $7FF4 and the next at $7FF0 and so on. You'd initialize a variable to $7FF4 and decrement it by 4 each time something is stored (by: long[noparse][[/noparse] location ] := value). The only problem is that this will eventually run into the space being used for the stack. There are ways to detect this, but it's much better to account for a maximum amount of data.

    You've got the right general idea. It's your task to try your hand at writing the program. I don't think you'll find a ready made example. If it helps, write a first version in a descriptive sort of language somewhat like what you did in the previous post, but a bit more detailed, then flesh out each statement in turn and see what you get.

    How were you going to do the host computer side? Start with that language if you're comfortable with it, then slowly translate in stages into Spin.
  • OwenOwen Posts: 100
    edited 2007-04-15 17:11
    I havn't gotten as far as sending an indefinite length table yet but I have run into a few question while trying to send a table of 20 random numbers between 0 and 1000 to the propellar, store them in an array and send them back to the host. I'm trying to use serial.rxcheck so the propellar knows when there is data to put in the array and when there is no more data, but I never get the same numbers back to the host. one question i have is if you use serial.rxcheck and don't store the return is the byte that was sent lost? how could I check for serial data without losing information while I check for it? If i wasn't trying to receive longs from the host maybe this would be easier. thanks again for all the help!
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    OBJ
      serial               : "Extended_FDSerial"
    
    Var
    long SerialBlock[noparse][[/noparse]100]
    
    PUB Main | i, k
      serial.start(12,11,%0000,115200)    
      serial.rxflush
    
      dira[noparse][[/noparse]10]:=1    "program running LED
      outa[noparse][[/noparse]10]:=1
    
      repeat 
        i:=0
        k:=0
        repeat while serial.rxcheck == -1
    
        repeat until serial.rxcheck == -1
          serialBlock[i]:=serial.rxDec 
          i:=i+1
    
        repeat k from 0 to i
          serial.dec(SerialBlock[noparse][[/noparse]k])      
          serial.str(string(","))
    
    [/i]
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-15 18:56
    Owen,
    Download a copy of BoeBotBasic from the Propeller Object Exchange and look at the BB_FullDuplexSerial.spin object. It's a slightly modified version of the FullDuplexSerial driver. In particular, look at "rxpeek". This would do what you want and you can cut and paste it from BB_FullDuplexSerial.spin to the copy of FullDuplexSerial.spin that you're using for your program.
  • OwenOwen Posts: 100
    edited 2007-04-16 18:00
    thank you Mike for pointing me to the BoeBotBasic rxpeek serial method. Now i'm not throwing away bytes as I check for them, but I am having trouble with overflowing the buffer when I sent a block of data. Is there a way to check if the buffer is full before writing to it when using serial.dec to send data? that would be a better way to avoid overflow rather than just slowing down my loop with a waitcnt command right?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-16 18:15
    The transmit buffer should not be able to overflow. The transmit routine is supposed to wait
    for room to be available before putting another character into the buffer (take a look at it).
    What seems to be happening?
  • OwenOwen Posts: 100
    edited 2007-04-16 18:26
    well i'm sending 20 longs from the host and the propellar is suposed to store them in an array and then send them back to the host. the data makes it back to the host correctly untill the propellar is suposed to have sent the 17th byte then there is a gap in the data. I just figured i was overflowing the buffer because the buffer is 16 bytes. now i'm not sure what the problem is... I'll take a closer look at FullDuplexSerial and see if I can see how it prevents a buffer overflow.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-16 18:39
    If you want to play with increasing the buffer sizes, you can change them to any powers of two. To change them to 32 bytes each, change the array declarations, change all "$F" constants in "rxcheck" and "tx" to $1F, change "and t2,#$0F" in the assembly section a bit after the label "receive" to "and t2,#$1F", change "and t3,#$0F" to "and t3,#$1F" a bit after the label "transmit", and change "add txbuff,#16" to "add txbuff,#32" a bit after the label "entry".
  • mirrormirror Posts: 322
    edited 2007-04-16 22:28
    I made a similar change to FullDuplexSerial, which can be found here:
    http://forums.parallax.com/showthread.php?p=644816
  • M. K. BorriM. K. Borri Posts: 279
    edited 2007-04-18 20:35
    Same here, I use a 128bit buffer to talk with a xbee radio modem (very handy because I have a propstick and I can get the 3.3v directly from there).

    What I ended up doing was using a "buffersize" constant at the beginning of my fullduplexserial, would that help any? I wish I could make it variable on the fly, but no luck there yet.
Sign In or Register to comment.