Serial communication receive with timeout - howto?
ted1
Posts: 3
Hi!
I am trying to modify Simple_Serial.spin to allow for timeout-handling (.Rx-call should timeout after 0.5 second of no data)
So I basically need to replace waitpeq() with my own routine for the waiting for a start bit
I was thinking about something like the code shown at the bottom (a modification of the Rx routine)
The problem is that the reception is unstable. Some characters are OK, some are garbage.
So I suspect that the repeat-loop for the start bit is too slow when the baudrate is 19200.
At 9600 baudrate it goes much better.
I was thinking about replacing the repeat-loop with assembly, but don't see how.
Do anyone see something wrong with my code?
Has someone maybe made serial I/O with timeout already?
Thank's!
I am trying to modify Simple_Serial.spin to allow for timeout-handling (.Rx-call should timeout after 0.5 second of no data)
So I basically need to replace waitpeq() with my own routine for the waiting for a start bit
I was thinking about something like the code shown at the bottom (a modification of the Rx routine)
The problem is that the reception is unstable. Some characters are OK, some are garbage.
So I suspect that the repeat-loop for the start bit is too slow when the baudrate is 19200.
At 9600 baudrate it goes much better.
I was thinking about replacing the repeat-loop with assembly, but don't see how.
Do anyone see something wrong with my code?
Has someone maybe made serial I/O with timeout already?
Thank's!
PUB rxTimeout: rxByte | t if rxOkay dira[noparse][[/noparse]sin]~ ' make rx pin an input t := cnt + (clkfreq / 2) ' timeout is 0.5 sec repeat until (ina[noparse][[/noparse]sin] == 0) OR (cnt > t) ' repeat until start bit or timeout t := cnt + bitTime >> 1 ' sync + 1/2 bit repeat 8 waitcnt(t += bitTime) ' wait for middle of bit rxByte := ina[noparse][[/noparse]sin] << 7 | rxByte >> 1 ' sample bit waitcnt(t + bitTime) ' allow for stop bit rxByte := (rxByte ^ inverted) & $FF ' adjust for mode and strip off high bits
Comments
1. Timeout detection handels also cnt overflows (wrap arounds).
2. Does not read the bits in if timout
3. Tries to compensate the delay from the timout detection with reducing the half bit time delay at begin to 1/4 bittime.
You need to play with this value to hit the right window inside the bit (1/3 or 1/8 or so).
This is not tested!
Andy
FullDuplexSerial really was much better. It works nicely now at 19200 bps.
Although a little difficult for our RS485 half duplex (2 wire) connection (LTC1487 chip), where we use only one propeller-pin for both Rx and Tx.
We had to specify an unused pin for the "unused" direction and reset the cog (call FullDuplexSerial.start) in order to switch traffic direction.
Ariba, your sample code would probably work, but we feel more comfortable with highspeed assembly for this purpose.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
I've been modifying FullDuplexSerial to be able to handle half duplex stuff. Here's an untested version (I'll be debugging it next week) to think about. There's an extra mode bit (%10000). If that's set, the transmit side of things shuts off when its buffer goes from non-empty to empty. When the buffer goes from empty to non-empty, the transmitter gets turned on again and stays on as long as there's something in the buffer. You need to use mode %1000 also because the receiver side is still running and sees anything that's transmitted. In this version, the buffer size is also adjustable at compile-time.
Typically, you'd put a string in the buffer and use "txflush" to wait until the buffer is empty and the last character is finished being sent (and the transmit side is turned off).
John Abshier
No problem, I thought you have a reason to use SimpleSerial. An Assembly serial driver is always the way to go, if you have a free cog.
Andy
Your FullDuplexSerialMG.spin, line 120 does not compile. It complains about the reference to randomSeed.
Is it ok to just remove this line?
Is seems like some debug stuff.