Shop OBEX P1 Docs P2 Docs Learn Events
FullDuplexSerial - receiving and displaying bytes — Parallax Forums

FullDuplexSerial - receiving and displaying bytes

xanatosxanatos Posts: 1,120
edited 2013-07-06 11:22 in Propeller 1
I've been racking my brain trying to figure out how to get FullDuplexSerial to receive some bytes sent from a Basic Stamp BS2px, and just (for now) display them via the PST window.

In searching through probably over 50 posts so far, I'm as confused as ever... but I found a post ( http://forums.parallax.com/showthread.php/140157-Storing-and-Using-Byte-Received-with-FullDuplexSerial ) in which there was some very helpful info - but I'm still not quite able to make this work.

Here's some code as it stands now (with extraneous stuff deleted - let me know if you need to see the full code - but be forewarned - there's a lot of it!)

In the BS2px:
      FOR tankNum = 1 TO 127
	DEBUG DEC3 tankNum, CR
        SEROUT SpinRX, T9600, [DEC3 tankNum]
      NEXT

And that works just fine and I've verified with an LCD that the SEROUT is working. No issue there.

But in the Propeller:
VAR

  byte EMArray[10]                             

OBJ
  pst           : "Parallax Serial Terminal"
  fds           : "FullDuplexSerial"

PUB Main

 fds.start(22, 27, 0, 9600) 

 repeat 127
   fds.rxflush
   EMArray[0] := fds.rx
   pst.dec(EMArray[0])
   pst.str(string(" "))
   pst.str(string(13))


The 10 setup for EMArray was arbitrary since for the purposes of getting this started I am only using EMArray[0] - once I get that going I'll set that up accordingly.

Two issues with the code I've got now - First, I'm unsure how to pace the fds.rx with the BS2's SEROUTs - or if I should read in ALL the 1 to 127 tankNums into an array, then parse the array out (assuming I have enough longs left to do that) - or if I should set up a handshaking/flow control arrangement to read one SEROUT in the loop at a time.

The second issue is that the above Spin code is contained in a loop. It hangs after about 6 iterations of the loop - as I'm sure you can see from looking at the code piece there :-) If I just comment out the EMArray[0] := fds.rx line, the loop runs through to completion, but of course just prints zeros to the PST window.

This is - obviously - my first time working with FullDuplexSerial, as is just about everything I've had to learn on this project.

Thanks for any corrections/directions you might be able to provide.

Comments

  • SRLMSRLM Posts: 5,045
    edited 2013-07-04 19:53
    Why not do something like this:
    OBJ
      pst           : "Parallax Serial Terminal"
      fds           : "FullDuplexSerial"
    
    PUB Main
    
      fds.start(22, 27, 0, 9600) 
    
      repeat 
        pst.char(fds.rx)
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-07-04 20:10
    SRLM wrote: »
    Why not do something like this:
    OBJ
      pst           : "Parallax Serial Terminal"
      fds           : "FullDuplexSerial"
    
    PUB Main
    
      fds.start(22, 27, 0, 9600) 
    
      repeat 
        pst.char(fds.rx)
    

    You also need to start PST.

    Serial objects require an accurate clock. Make sure you're setting the clock mode.
    CON
     
      _CLKMODE        = XTAL1 + PLL16X                     
      _XINFREQ        = 5_000_000
    
    
    OBJ
      pst           : "Parallax Serial Terminal"
      fds           : "FullDuplexSerial"
    
    PUB Main
    
      fds.start(22, 27, 0, 9600) 
      pst.start(9600)  ' assuming this is the baud you want
    
      repeat 
        pst.char(fds.rx)
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-07-04 20:18
    You could save some memory by using two instances of the same serial object.

    Here's the same code using only PST.
    CON
     
      _CLKMODE        = XTAL1 + PLL16X                     
      _XINFREQ        = 5_000_000
    
    
    OBJ
      pst           : "Parallax Serial Terminal"
      fds           : "[COLOR=#ff0000]Parallax Serial Terminal[/COLOR]" '"FullDuplexSerial"
    
    PUB Main
    
      fds.[COLOR=#ff0000]StartRxTx[/COLOR](22, 27, 0, 9600) 
      pst.Start(9600)  ' assuming this is the baud you want
    
      repeat 
        pst.char(fds.[COLOR=#ff0000]charIn[/COLOR])
    

    Alternatively you could use two instances of FullDuplexSerial.
  • xanatosxanatos Posts: 1,120
    edited 2013-07-05 05:06
    Hi,

    PST is started and working and clkmode & xinfreq are set. I haven't shown my setup for PST because it's working and displaying a lot of stuff from other areas in the code I have running. Here's my OBJ block:
    OBJ
      pst           : "Parallax Serial Terminal"
      Socket        : "W5100_Indirect_Driver"
      SDCard        : "S35390A_SD-MMC_FATEngineWrapper"
      Request       : "Request"
      Response      : "Response"
      str           : "StringMethods"
      rtc           : "S35390A_RTCEngine"
      nums          : "Simple_Numbers_plus"   
      sntp          : "SNTP 2.01"
      fds           : "FullDuplexSerial"
    

    Everything else in here is working perfectly - better than I could have hoped given my very limited understanding of Spin - thanks to some folks on these forums.

    For clarity, here's the selected setup lines extracted from all the other code:
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000
    
    PUB Initialize | id, size, st  
    
      pst.Start(115_200)
      pause(200)
    
      rtc.RTCEngineStart(29, 28, -1)  
      pause(200)
    
      fds.start(22, 27, 0, 9600)
    

    All I'm needing to do here is read the bytes sent from the BS2 into some sort of variable/array, so that I can then place those values into the appropriate locations in an email that gets sent out. Writing to the PST is only for me to verify that I have actually gotten the real data, and the loop counter that the BS2 runs as a data source is only just a test setup to provide a known data stream via SEROUT so I know for certain when I see the data that I have the BS2's actual data.

    Here's a segment of code from within the email routine (which works perfectly with the exception of reading any BS2 data with FullDuplexSerial at the moment). Note within the code my block of comments describing what I am actually trying to do and where:
          'Content Type
          StringSend(id, string("Content-Type: text/plain; charset=us-ascii", 13, 10, 13, 10))
          pause(wait)
       
          rtc.readTime
          
          Mo := rtc.clockMonth
          Dy := rtc.clockDate
          Yr := rtc.clockYear
          Hr := rtc.clockHour
          Mn := rtc.clockMinute
          Sc := rtc.clockSecond
    
          repeat tankNum from 1 to 32                    ' Increase to 128 for live version!
    
    '*******************************************************************************************
    ' Here is where I want to read in a line of data from the stamp via its SEROUT to
    ' the propeller's FullDuplexSerial.  I have a flow control set up so that it will read out one
    ' line at a time if need be.  There are a total of 128 lines to be read, each consists
    ' of a 3 digit tank number, and a 4 digit ADC value.
    
    ' What I thought should work was something like this:
    
    '        fds.rxflush
    '        EMArray[0] := fds.rx     'Tank Number
    '        EMArray[1] := fds.rx     'ADC Level byte 0
    '        EMArray[2] := fds.rx     'ADC Level byte 1
    
    ' And then for my initial testing I could print the EMArray values to PST to show if I received
    ' valid data.  But ultimately, these values are going to go into the email building lines below, which
    ' is a loop that runs 128 times - building 128 data lines, each with the above tank number,
    ' date/time stamp, and the live ADC data from the BS2.  Note that the clock and email functions
    ' all already work perfectly, I'm just trying to get the BS2's data and insert it into the email:
            
            StringSend(id, string("GHBWM Data,"))   ' Hardcoded ID Fields
            StringSend(id, nums.decn(tankNum, 3))        ' Dynamically generated Tank Number
            StringSend(id, string(","))               
            StringSend(id, nums.decn(Mo, 2))             ' Dynamically obtained Time and Date from RTC.
            StringSend(id, string("/"))
            StringSend(id, nums.decn(Dy, 2))
            StringSend(id, string("/"))
            StringSend(id, nums.decn(Yr, 4))
            StringSend(id, string(" "))
            StringSend(id, nums.decn(Hr, 2))
            StringSend(id, string(":"))
            StringSend(id, nums.decn(Mn, 2))
            StringSend(id, string(":"))
            StringSend(id, nums.decn(Sc, 2))
            StringSend(id, string(","))
            StringSend(id, string("0000", 13, 10))       ' Raw ADC Level Data. <<<<<<< This is going to be data from the BS2.
            pause(50)  
                  
          outa[24] := 0    '' Set BS2 Email Request line back to 0 for the next 9 minutes.
       
          'Quit conversation
          StringSend(id, string(".", 13, 10))
          pause(wait)
    
    .... many more lines of working stuff
    

    So to sum it up in the shortest possible description - read in SEROUT data from a BS2 in the form of three bytes, for each successive iteration of a loop in the Propeller's Spin program, storing those bytes temporarily for placement in the body of an email.

    Everything else is working, I'm just not seeming to grasp how to use FullDuplexSerial in this capacity, and I'm also not sure about what, if any, flow control or handshaking needs to happen between the stamp and the Propeller's serial lines. Currently I just have the stamp wait until the Propeller tells it it's time to start SEROUTing...

    Thanks for any help. I know I'm close but ... not close enough.

    Dave

    PS., In terms of saving memory, once this is all working, I'm taking PST out entirely anyway - commenting out the 100+ pst.str lines that are in there now and commenting it out in the OBJ block, just in case I need it at a later date :-) Only FDS will remain active.
  • ratronicratronic Posts: 1,451
    edited 2013-07-05 09:56
    Dave I use a flag to mark the beginning of my data. For example you could put a Do Loop on your Basicstamp code and transmit your flag bytes before your data. I'm using $FF & $FA to mark the beginning of the data in this example but you could use any values you want.

    EDIT: You should pick flag bytes that most likely won't be in your incoming data string in that sequence.
    Con
                                                               
      _CLKMODE = XTAL1 + PLL16X                              
      _XINFREQ = 5_000_000
       
    Var
      byte EMArray[127]
        
    Obj
      pst : "parallax serial terminal"
       fd : "fullduplexserial"
                    
    Pub Main | i
      fd.start(22, 27, 0, 9600) 
      pst.start(9600)
      
      repeat
        repeat until fd.rx == $ff
          if fd.rx == $fa        
            repeat i from 0 to 126 
              EMArray[i] := fd.rx 
      
        repeat i from 0 to 126
          pst.dec(EMArray[i])
    
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-07-05 10:32
    I have a small derivative of FDS that I call fullduplexserial64 as it has bigger buffers (that is always a problem for out-of-the-box FDS) and it includes a method called rjdec() that allows me to "print" decimal values in a fixed field. The method allows for field with and a pad character (usually "0" or " "). Like you, I came from the BASIC Stamp and tend to use a lot of formatted output.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-07-05 10:36
    It looks like your sending your data as ASCII characters, correct? While sending data this way is slower since it usually require more characters per data value it can make receiving the data easier since you can include control characters in your data stream.

    As with most programming tasks there are many ways to receive data and parse out the various values. One method I've used is to monitor the incoming data from within the PASM section of the serial driver and increment a flag when an end of message character is received. My main loop can then wait until a complete data packet has been received before parsing the message. Here's a link to a version of a multi port serial driver using this end of message flag technique.

    I've also modified Tracy Allen's improved four port driver to included an end of message flag. If you're interested in using this technique yourself, I'll find this improved version, clean it up a bit and post it if you'd like.

    I think the more common way of parsing data is to just read it as it comes in. You'll still need beginning and end markers and you'll also need some way of separating the data fields. It looks like you're using commas slashes and semicolons as field separators. Or are these field separators part of the entire message you wish to forward?

    Now that I look a bit more at your code, it looks like you just need to receive two values from the BS2? Since it appears thewe are being sent as ASCII characters you still have the need of a start of message character(s), flied separators (unless data is fixed length) and end of message character (optional if data fields are fixed width). You'll need to add these characters to your BS2 output code.

    I just noticed JonnyMac's post. An alternative to using field separators is to send the data with a fixed field length. You'll still need some sort of identifier to mark the beginning of your message.

    If one doesn't use ASCII characters (or a fixed length message) then the size of the data packet is usually sent as part of a header section of the message. Dynamixel servos use this type of message packet. This has the advantage of being able to send a byte sized value in one character. Ratronic has a object in the OBEX (I've used many times) to communicates with Dynamixel AX-12 servos that illustrate this type off protocol.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-07-05 10:57
    Dave,
    Congrats on making it so far!

    One trouble with FDS is that its receive buffer is too small, only 16 bytes, and that buffer becomes overrun by data from the BS2SX faster than the Prop is taking it out for retransmission. Take Duane's advice from post #4 and use two instances of PST.

    The default buffer size for PST is 64 bytes, which is better, but you can change it to get a little more leeway in your timing. In the code listing for PST you will find the buffer size defined in the CONstants section, like this.
    BUFFER_LENGTH = 64                                   
           'Recommended as 64 or higher, but can be 2, 4, 8, 16, 32, 64, 128 or 256.
    
    If you have Prop memory to spare, you can change that too 128 or 256. That will take space for both instances of PST, and PST does not allow for separate values for the rx and tx buffers.

    In your original spin code, there is no need for rxFlush. That is trashing characters that are arriving from the 'SX. Also, there is a mismatch between what you are sending (3 ascii decimal digits per tank, fixed fields, no separator) and what you are receiving on the Prop (1 byte fds.rx that you print out as a decimal value). If you can fit the tank values in individual bytes, that would in fact allow the entire record from 127 tanks to fit in a 128 byte serial buffer, so the Prop could take all the time it wants to process the packet.
  • xanatosxanatos Posts: 1,120
    edited 2013-07-05 13:15
    I ****ING DID IT! :-)

    I took out my old QuickStart board, loaded it with FDS, PST and then wrote a little looping program to take the BS2 data in, and I just sat on it and tried stuff shotgun style, until it started to make sense. I just logged on now to report my success and I see that several of you have been enormously kind in offering assistance, and I can't begin to tell you how good it feels to feel like I wasn't working without a net after all.

    I did discover remember (since I did set that var up to be a word in the stamp code) that my level data was really going to be a word, not a byte, and that was part of my problem.

    The BS2 doesn't transmit characters as ASCII - that much I knew. But I did have to bit-bang the two bytes back together to reconstitute the original number.

    When I run the two codes below, I get the real live numbers out on my PST window - including the correct, reconstituted TankLevel value.

    WOO HOO!!! Lord, that felt good! :-)

    I'm sure that there is probably a much more efficient way of doing this - but dang it, it works and I actually understand it! :-)

    BS2 test program:
    ' -----[ PROGRAM DESCRIPTION AND DEV STATUS ]------------------------------
    '
    '  File....... SEROUT_FDS_TEST.bs2
    '  Purpose.... Develop clean comms between BS2 SEROUT and Propeller FullDuplexSerial.spin
    '  Date....... July 5, 2013
    '
    '  {$STAMP BS2}
    '  {$PBASIC 2.5}
    '
    ' =========================================================================
    ' -----[ I/O Definitions ]-------------------------------------------------
    
    SpinEM          PIN     0                ' Spinneret - HIGH pulse triggers email routine  ( outa[24] := 1 )
    SpinRX          PIN     1                ' Stamp TX to Spinneret RX
    SpinFC          PIN     2                ' Flow Control for Spinneret/BS2 comms ( if ina[25] == 1 )
    
    ' -----[ Constants ]-------------------------------------------------------
    
    #SELECT $STAMP
      #CASE BS2, BS2E, BS2PE
        T2400       CON     396
        T9600       CON     84
        T19K2       CON     32
      #CASE BS2SX, BS2P
        T2400       CON     1021
        T9600       CON     240
        T19K2       CON     110
      #CASE BS2PX
        T1200       CON     3313
        T2400       CON     1646
        T4800       CON     813
        T9600       CON     396
        T19K2       CON     188
        T38K4       CON     84
    #ENDSELECT
    
    ' -----[ Variables ]-------------------------------------------------------
    
    x               VAR     Byte             ' Loop Counter
    i               VAR     Word             ' Shows how many runs... antici[ating I'll need a lot!
    TankLevel       VAR     Word             ' ADC Output of Gems Sensor Data
    tankNum         VAR     Byte             ' Tank number, x - 127.
    EMFlag          VAR     Bit              ' Flag for mail sending, set by Spinneret
    
    ' -----[ Initialization ]--------------------------------------------------
    
    INPUT SpinEM
    EMFlag = 0                     ' 0 = Email not being called; 1 = Spinneret calling for tank data for the email.
    OUTPUT SpinFC
    SpinFC = 0
    DEBUG CLS, HOME
    i = 0
    PAUSE 10
    
    ' -----[ Program Code ]----------------------------------------------------
    
    Main:
    
      EMFlag = SpinEM                                         ' SpinEM (P24) sets EMFlag to 1 when it's email time.
      SpinFC = 0 'EMFlag                                      ' Sets pin to 1 to let Spinneret (P25) know that it's ready
    
      i=i+1
    
      FOR x = 128 TO 159 '128 to 255 for full system of 128 tanks   (143 for first bank only, 159 for 2 banks...)
    
        'SpinEM is from Spinneret
        'SpinFC talks TO Spinneret
        'SpinRX is data out to Spinneret
    
        TankLevel = 1234
    
        IF EMFlag = 1 THEN         ' EMFlag should only be 1 for the duration of one full scan cycle
            tankNum = x-127
            'DEBUG DEC i, " ", DEC3 tankNum, " ", BIN TankLevel.BYTE1, " ", BIN Tanklevel.BYTE0, CR
            SEROUT SpinRX, T9600, [tankNum, TankLevel.BYTE1, TankLevel.BYTE0]
            'SEROUT SpinRX, T9600, [tankNum]
        ENDIF
    
      NEXT
    
      PAUSE 500
    
    DEBUG HOME
    
    GOTO Main
    
    

    Propeller Spin Code (a lot of stuff is commented out - remnants from the original sections from whence it came):
    {{
    Dave Xanatos' Fervent Last Ditch Effort to figure out how to make FDS read from a BS2.  5 July 2013.
    }}
    
    
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000         
    
    DAT
    
    VAR
      byte mSent[1]     
      byte EMArray[10]                         
      
    OBJ
      pst           : "Parallax Serial Terminal"
      str           : "StringMethods"
      nums          : "Simple_Numbers_plus"
      fds           : "FullDuplexSerial"
    
    PUB Initialize | id, size, st
    
      mSent := 0
      dira[24] := 1  '' Sets 24 to output - this sends pulse to BS2 to request SERDATA OUTPUT for emailing      
      dira[25] := 0  '' Sets 24 to input - Possible data ready kind of thing.  Flow control?
    
    
      pst.Start(115_200)
      waitcnt(clkfreq/5+cnt)
      
      fds.start(22, 27, 0, 9600)
      waitcnt(clkfreq/5+cnt)
      
      Main
      
    PUB Main | tankNum, xpin, TOCount, TankLevel
       
    pst.str(string(13, "START", 13))
    
    ' Quickstart p22 = connector p23
    ' Quickstart p27 = connector p28
    ' Quickstart p24 = connector p25
    ' Quickstart p25 = connector p26 
    
    ' Pin 22 = Serial RX (level shifted for 5v interface)
    ' Pin 27 = Serial TX (***NOT*** level shifted for 5v interface - Must use 3.3k resistor.)
    ' Pin 24 = Pulse Out to request, set to LOW in init block, goes HIGH on initial request.
    ' Pin 25 = Input, set in init block, used for flow control.
    
     '   TOCount := 0    '' Timeout Counter.  Set up so that if BS2 doesn't respond in a given time, it skips the send.
     '   outa[24] := 1   '' Request data be sent from BS2 (SpinEM)
     '   xpin := 0       '' This will be set high when BS2 responds it's ready.
    
    '    repeat while TOCount < 10
    '      if ina[25] == 0  '' Look for BS2 to say it's done scanning and ready to do the data send.
    '        waitcnt(clkfreq/5+cnt)       
    '        TOCount := TOCount + 1
    '      elseif ina[25] == 1
    '        TOCount := 10
            xpin := 1
              
        if xpin == 1
    '      pst.str(string(13, "email", 13))   
    
          repeat tankNum from 1 to 32                    ' Increase to 128 for live version!
            'Tell stamp to send 1 line
    '        outa[24] := 0   '' Tell BS2 (SpinEM) to get send a dataline   
            'Receive bytes
            fds.rxflush
            EMArray[0] := fds.rx
            EMArray[1] := fds.rx
            EMArray[2] := fds.rx
    
            TankLevel := (EMArray[1]*256)+EMArray[2]
            
            pst.dec(tankNum)
            pst.str(string(" "))    
            pst.dec(EMArray[0])
            pst.str(string(" "))
            pst.dec(EMArray[1])
            pst.str(string(" "))    
            pst.dec(EMArray[2])
            pst.str(string(" "))
            pst.dec(TankLevel)    
            pst.str(string(13))    
    '  
    '        pst.str(string(" "))
    '        pst.str(string(13))
            
            'outa[24] := 1   '' Tell BS2 (SpinEM) to hold for next byte   
            'Parse bytes
          
           ' waitcnt(clkfreq/5+cnt)       
    '        outa[24] := 1   '' Request data hold from BS2 (SpinEM)   
                  
        '  outa[24] := 0    '' Set Email Request line back to 0 for the next 9 minutes.
       
       
        else
          pst.str(string(13, "NO EMAIL", 13))
    
       
        waitcnt(clkfreq/5+cnt)
    
    main
    
    

    You can't imagine the relief. This has to be fully done, tested to the ends of the Earth and installed by July 15th. This was the last piece I wasn't getting to work. While I have to play a little with getting the start points of the data to synchronize a little better - that's the easy part.

    **** THANK YOU ALL AGAIN, KNOWING THAT THE HELP IS THERE IS IMMEASURABLY REASSURING ******

    Some questions will follow as soon as I finish celebrating! :-)

    Dave
  • xanatosxanatos Posts: 1,120
    edited 2013-07-05 13:43
    OK...

    Tracy - So I don't need fds.rxflush? The incoming data will write over the old stuff with no possibility of corruption, correct?

    Also, the way I'm doing this comm between the stamp and the bs2px is that I have the propeller request one line at a time - I have some flags set to toggle pin states between the two devices. The stamp can possibly be busy doing a scan loop of all 128 sensors, which takes about 8 seconds, so I have the stamp set a pin high when it has seen the request for the data and reports ready to send. Then the propeller tells it to send and resets the flag, so when the BS2's loop comes around again, it holds before sending the next data line. This process continues until all 128 data lines have been loaded.

    Is that dumb? :-) Is there a less "brute force" way of doing that? It goes pretty quickly by human standards (takes about 3 seconds for 32 scans, so I'm guessing 12 seconds for all 128.)

    In any case, in this way I only use three bytes plus a word to reconstitute the level value back to human-readable original, on the fly as I build the body of the email. There doesn't seem to be any issue with buffer size or timing by doing this. Am I missing a possible future gotcha?

    Ratronics - reading your post regarding flag bytes - that sounds like it would help me make sure my data received is properly aligned, especially if I go with some sort of array that reads all 128 data lines at once (that would be three bytes per data line actually, one byte for the tank number, and two bytes for the level data, plus a byte for the flag byte. But then my question is - since one of those three bytes (tanklevel.byte0) can be anything from 00 to FF... how can I make a unique byte flag? :-)

    More questions I'm sure, but for now I can breathe again! Now to integrate this with the "real" program :-)

    THANKS!

    Dave

    PS., I find myself astounded at how simple and obvious some of this stuff looks *once you're on the side of understanding*. I hope I never forget how it looked to me before I made that transition. It's like being in a different universe.
  • ratronicratronic Posts: 1,451
    edited 2013-07-05 15:55
    There are many ways to go about what you are trying to do. I'm not sure the example I posted is the way you want to proceed. You have to keep in mind when the Stamp starts transmitting and when the Propeller starts receiving. Also as others have pointed out

    the FullDuplexSerial object only has a receive buffer of 16 bytes. You don't have to use 2 bytes for your flag it could be more to make it more unique. Good luck it looks like your are close to achieving what you are trying to do.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-07-05 16:30
    Dave, my comment about rxFlush applied only to the code in post #1. It does make sense in your more recent approach, where the handshake pin tells the BS2sx to start or stop sending, although that part is commented out, so I guess you are still experimenting! If the buffer is already empty from parsing all the previous data, the rxFlush won't do anything, but it won't hurt. Just be sure to use the rxFlush before telling the BS to transmit.

    There are other ways to check alignment. For example, you expect bytes 0,3,6,9,... to be an increasing sequence with the tank number. The receiver can check and insist on the strict progression. Or, to get a unique alignment tag ($FE), you might encode the level so that the bytes transmitted will be in the range 0-127 instead of 0-255:
    levelByte0 := level // 128
    levelByte1 := level / 128
    level = levelbyte1 *128 + levelByte0 ' allows levels from 0 to 16383.

    The Stamp has flow control capabilities:

    SEROUT SpinRX\flowIn, T9600, timeout, [tankNum, TankLevel.BYTE1, TankLevel.BYTE0]

    That is kind of like the flow control you want to implement in the program loop.

  • xanatosxanatos Posts: 1,120
    edited 2013-07-06 11:22
    Tracy,

    Thank you - I had completely forgotten that the stamps can do flow control in the SEROUT/IN statements - never needed it before. Implementing it now.

    As for alignment, since the tank number should always match the loop count, I'm just having it check to be sure the received tank number == the loop count, and if not, re-request that data line, otherwise, proceed to the next. Simple and since speed isn't really a requirement here, relatively bulletproof.

    92 in the shade here today. Good day to be in programming!

    Thanks again,

    Dave
Sign In or Register to comment.