Shop OBEX P1 Docs P2 Docs Learn Events
Looking for ideas for identifying the start of a serial input into Prop — Parallax Forums

Looking for ideas for identifying the start of a serial input into Prop

DiverBobDiverBob Posts: 1,108
edited 2008-12-14 22:17 in Propeller 1
Before I start coding I want to come up with a process for downloading serial data into a prop so I don't end up going down too many blind alleys.

What I have is a serial source (a seperate PIC processor performing 10-bit ADC). I will be sending 3 seperate ADC result sets (numbers ranging from 0 to 1023) at 1 second increments. I am trying to figure out is the best way to transfer the data and have the prop be able to properly identify which one of the 3 sets of data it is recieving and then store the value in the appropriate global value. I have one cog exclusively devoted to recieving the data into the variables where the other cogs can read the value as needed. I wrote some spin code for recieving and storing a single value but need to come up with some ideas for recognizing multiple items. I thought I'd ask if anyone else has run across an elegant·solution in their travels?

Since I am only concerned with the ADC numbers, I thought to first send a character like 'a' followed by comma, first number, comma, second number, comma, third number. (ex.: a,40,523, 1023). Then I could use the 'a' to key as the leadin in spin to determine where my location in the serial stream. That should be fairly easy to code at the PIC and in spin.

If anyone has a better idea I would love to hear it! (examples are nice too if you can point me to existing code!)

Bob Sweeney

Comments

  • Jay KickliterJay Kickliter Posts: 446
    edited 2008-12-14 03:04
    I started a very similar thread today. I got a bunch of good responses: http://forums.parallax.com/forums/default.aspx?f=25&m=313208
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-12-14 03:56
    Hexadecimal is usually easier to encode and decode than decimal (i.e. no division required). You could easily transmit and receive a string like this (three hex digits per 10-bit value):

    !1AF265007
    
    
    


    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Just a few PropSTICK Kit bare PCBs left!
  • AribaAriba Posts: 2,687
    edited 2008-12-14 04:23
    Because you have 10 Bit values from the ADCs you can break the value in two 5bit parts, and use Bits 5,6 or 7 to indicate the begin. So you can send it all in binary:
    Bit 7  6  5  4  3  2  1  0
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    1 │ 1│ 0│ 0│A9│A8│A7│A6│A5│
      └──┴──┴──┴──┴──┴──┴──┴──┘
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    2 │ 0│ 0│ 0│A4│A3│A2│A1│A0│
      └──┴──┴──┴──┴──┴──┴──┴──┘
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    3 │ 0│ 0│ 0│B9│B8│B7│B6│B5│
      └──┴──┴──┴──┴──┴──┴──┴──┘
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    4 │ 0│ 0│ 0│B4│B3│B2│B1│B0│
      └──┴──┴──┴──┴──┴──┴──┴──┘
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    5 │ 0│ 0│ 0│C9│C8│C7│C6│C5│
      └──┴──┴──┴──┴──┴──┴──┴──┘
      ┌──┬──┬──┬──┬──┬──┬──┬──┐
    6 │ 0│ 0│ 0│C4│C3│C2│C1│C0│
      └──┴──┴──┴──┴──┴──┴──┴──┘
    
    1) wait for a byte with Bit7 set (=byte1)
    2) read the next 5 bytes
    3) calculate ADC values:
       ADC A: value = (byte1 & $1F) << 5 + byte2  
       ADC B: value = byte3 << 5 + byte4  
       ADC C: value = byte5 << 5 + byte6  
    
    



    Andy
  • T ChapT Chap Posts: 4,223
    edited 2008-12-14 04:42
    Create an array the size of the data you want to read, no header ('a') needed. Using Full Duplex serial, set the first byte read to RX as shown below, so it waits until a byte shows up. Set the next read to a read 'time', which waits a specified amount of time before continuing. This way, you always know where the first byte starts since it waits for data. Do what you need to do with the data in the array, then run the method again. Time your send device to not send faster than the reader can deal with the info. Send the data in a fixed length format for each a value, even if 0's.

    
    VAR 
        ResponseArray1[noparse][[/noparse]64]    'set this to whatever size you need
    
    PUB Main
           Repeat
              ReadData 
              ' do something with ResponseArray1[noparse][[/noparse]0] - ResponseArray1[noparse][[/noparse]63] 
              
    PUB ReadData   |  i, val   read whatever comes in up to i.e.  64 
    
         ResponseArray1[noparse][[/noparse]0] := ser.rx  'read first byte:  wait here for first byte to show up
         i := 1               'increment pointer
         Repeat 63                      'look for more up to i.e. 64 total bytes
           Val :=  ser.rxtime(2)       'read more,  wait 2 ms before quitting if no byte shows up
           ResponseArray1[i] := Val
           i := i + 1  
    [/i]
    

    Post Edited (TChapman) : 12/14/2008 4:52:50 AM GMT
  • DiverBobDiverBob Posts: 1,108
    edited 2008-12-14 18:37
    Thanks everyone for the ideas. I particularly like the idea from Andy (Ariba) - It is easy to implement on the transmitter side and to code in spin. I will be going to the workshop and try some it out and see how well it works. Since this project is battery powered I am keen on using sleep cycles, slow·data transfer rates·and minimizing the number of active cogs.

    Bob Sweeney
  • KenBashKenBash Posts: 68
    edited 2008-12-14 21:52
    I put together a board that had three Prop Chips on it and I came up with a communication protocol that let all three processors share data back and forth in a 96 byte buffer. The com function was started with a sync pulse holding the clock line ( signal generated by one of the props ) low for a count of 10 ( plenty of time for the other processors to recognize it and sync to the start ) Then each processor had 32 bytes that they could send out each in turn. These could be flags, data blocks, whatever you wanted to communicated back and forth between processors. Something similar might easily work for communicating with your sensor chips. ( you can put in error detection if you want. ) It wasn't a GREAT com scheme for large numbers of processors or sensors, but for a small group of processors you want to know what each other is doing, it worked pretty good on only two pins each. It wasn't very fast since I wrote it in Spin, but it was fast enough for what I needed and could easily be put into assembly.

    ( my code is buried away somewhere but I'll dig it up if someone wants to try it )


    ( you should be able to do the same thing with the standard RS-232 function as well... if one "Master" chip controls who can talk when )

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    " Anything worth doing... is worth overdoing. "

    ··············································· ( R.A.H. )
    ····································
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-12-14 22:17
    You can also do this asynchronously without the clock line. Just hold the serial data line low for at least 10 bit times (a BREAK) to signal the boundary between data clusters.

    Of all the ideas presented here (including my own), I like Ariba's the most.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Just a few PropSTICK Kit bare PCBs left!
Sign In or Register to comment.