Shop OBEX P1 Docs P2 Docs Learn Events
reading unstable RS232 ( Rx w/ timeout) — Parallax Forums

reading unstable RS232 ( Rx w/ timeout)

janbjanb Posts: 74
edited 2006-07-31 22:57 in Propeller 1
Hi,
I'm playing with 2-way serial transmision between host and my mobile robot.
It happeds often signal is too weak do to·the distance or obstacles and·a timeout capability for
Rx is·a handy option to start recovery procedure for the robot.

The Simple_Serial packet provides a rx() method which hangs cog forever
if nothing is comming in.
Below·is a modified version rxtm(maxCnt) which works like rx() except it returns -1 if· cnt spends more than 'maxCnt' cycles in this method. It took me a while to overcome cases when cnt wraps around, but now it runs for 30 minutes w/o problems.

A simple test·program·runing on 2 cogs sending and reading values at different frequencies over a pair of pins is attached
Jan


PUB rxtm(maxCnt) | t, b,t0,t1 'aborts on timeout· after 'maxCnt' ticks
' negative value is returned on timeout
't1 holds time out limit (>>2)
't0 holds t start to allow compensation if cnt wraps around

'' Receive a byte; blocks program until byte received
·
· t0 := cnt>>2·· ' degrade time resolution to handle easier wrap around
· t1:= t0+ (maxCnt>>2)
· if started and rxOkay
··· dira[noparse][[/noparse]sin]~·························· ' make rx pin an input
··· repeat while· ina[noparse][[/noparse]sin]<>inverted··· ' wait for start bit········
····· t:=cnt >>2
····· if t<t0·················· ' compensate for wrap around of cnt
······· t+=$4fffffff
····· if t1<t·················· ' checks for time out
······· return -1·············· ' terminates method, report error code
··· t := cnt + bitTime >> 1···························· ' sync + 1/2 bit
··· repeat 8
····· waitcnt(t += bitTime)···························· ' wait for middle of bit
····· b := ina[noparse][[/noparse]sin] << 7 | b >> 1······················ ' sample bit
··· waitcnt(t + bitTime)······························· ' allow for stop bit
··· return (b ^ inverted) & $FF························ ' adjust for mode and strip off high bits

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-07-30 21:55
    Jan, it's usually better to use the difference between two times for testing purposes rather than an expected time. It would be unusual to have to deal with a time interval approaching 2^31, but CNT can wraparound anytime. Better to do something like:
      timeout := maxCnt + cnt   ' This gives us a future time (possibly wrapped around)
    ...
        repeat while ina[noparse][[/noparse]sin] <> inverted
          if timeout - cnt ~> 31   ' Checks for timeout - cnt less than zero in signed arithmetic
            return -1
    
    


    This isn't the same as:
          if timeout < cnt
    
    


    because of the way signed/unsigned comparisons work when cnt wraps around.

    Post Edited (Mike Green) : 7/30/2006 10:04:35 PM GMT
  • janbjanb Posts: 74
    edited 2006-07-31 22:00
    Hi,
    this is tricky, let me try to understand it better.
    'If' needs a boolien value, so did you meant

    if ( timeout - cnt ~> 31 )<0
    ....
    ?

    Also, there are 2 case when the counter time wraps around:
    - when cnt does it or
    - when cnt is still positive but cnt+timeout is already negative.
    That is why I did '>>2' instead of '>>1' so it handles both cases.

    But I'll experiment with the '~>' operator
    thanks for the feedback
    Jan
  • Mike GreenMike Green Posts: 23,101
    edited 2006-07-31 22:57
    The arithmetic right shift converts a negative number into TRUE. In SPIN, TRUE is defined as -1 and FALSE is defined as 0 although, for most cases, any non-zero value is considered to be TRUE. There are some programs that use a logical value (TRUE/FALSE) as a bitmap and they can get into trouble since a non-zero value may work with an IF statement, but is not TRUE.

    The expression (timeout - cnt) will have its sign bit set if cnt has passed timeout, but is still within 2^30 clock ticks. The "~> 31" operator just fills the whole word with the sign bit, converting it to TRUE/FALSE (-1/0).
Sign In or Register to comment.