reading unstable RS232 ( Rx w/ timeout)
janb
Posts: 74
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
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
This isn't the same as:
because of the way signed/unsigned comparisons work when cnt wraps around.
Post Edited (Mike Green) : 7/30/2006 10:04:35 PM GMT
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
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).