How to detect when a serial byte begins?
Erlend
Posts: 612
I want to begin listening at a running asychronious transmission (GPS NMEA) at any time, then return as soon as a specific valid NMEA sentence is detected and decoded. So, when I write the code for a simple RX I begin wondering; how can the code 'know' when a byte transmission begins - the start bit looks like any other bit. I have not tested my code yet, but if it just works, I still need to know how.
Erlend
PRI RxB(rxPin) | t, rxByte, isThere isThere:= FALSE DIRA[rxPin]:= 0 REPEAT 10000 'Give it a fair amount of tries/time IF INA[rxPin]== 1 isThere:= TRUE 'Test for bit input QUIT IF isThere 'Quit trying when input detected t:= CNT + bitDur/2 'Set synch point half a bit duration late REPEAT 8 'to miss the start bit, and then read 8 data bits WAITCNT(t += bitDur) 'by sampling each bit duration time interval rxByte:= INA[rxPin]<< 7 | rxByte>> 1 'keep reading and setting latest bit as bit 7, OR'ing onto previous bits read WAITCNT(t += bitDur) 'let the stop bit pass RETURN rxByte & $FF 'allow only 8 lowest bits ELSE RETURN FALSE
Erlend
Comments
The idle state of the line is HIGH. So when the line goes LOW then you know you have a start bit.
Then, after clocking in 8 data bits one expects one or two stop bits. Which are HIGH. And the process begins again.
Having said all that. I do sometimes wonder how things get in sync when data is arriving continuously, back, to back, and the receiver happens to start listening halfway through the data.
Exactly! Mustn't there be some code to wait for a long idle (High) to signify a byte could be next? What happens if the first thing sensed is a High-Low transition in the middle of a byte transfer - who's to know if that is not and Idle-Start transition?
Erlend
Btw, Happy Christmas to the Forum!
I can imagine that a continuous stream of data with one stop bit looks like:
LOW, D0, D1, D2, D3, D4, D5, D6, D7, HIGH, LOW, D0, D1, D2, D3, D4, D5, D6, D7, HIGH.....
In which case I can imagine any device listening to that being able detect the character frames. Even easier with two stop bits.
If you do happen to start in the middle, say at D3, D4, which happen to be HIGH, LOW, you will attempt to receive an incorrect character. But then the stop bit will likely be wrong. So you know to try again.
Do good old fashioned real UART chips do that?
Of course, often there is a higher level protocol working on the line. Which enforces request/response, uses NAK/ACK and CRC etc. So all the problems get taken care of.
Tracy Allen kindly showed me the various parts of an asynchronous transmission.
I don't know if you're aware many (most?) serial objects written in Spin/PASM for the Propeller use two stop bits.
Erlend
Edit: Actually, I parse the sentence as it comes in. So that means throwing away everything, one byte at a time, until I see the "$". Endedit
Erlend
BTW, I'm pretty sure the first test should look for a "0" instead of "1".
Continuous async transmission without pauses would range from extremely rare to non-existent, and if it did exist would probably have some form of unique start and/or stop sequence such as the "GP" characters in a NEMA sentence.
-Phil
It should. When the signalling is non-inverted, anyway. Thanks, now fixed.
Erlend
Erlend
Erlend
Any pauses or extra stop bits, shift the possible start bit, and eventually things sync-up.
FWIR, GPS NMEA does have gaps - you can check with the string length and repeat time.
Couldn't resist
I just listen on /dev/ttywhatever, and all works well.
The Toledo Model 8132 scale indicator, the second ever in the industry with a microprocessor at its heart, was infamous for this. Toledo uses the same protocol to this day but all their more modern indicators pause between frames.
LOL, I knew there would be at least one. There are always exceptions to the norm. That's why I rarely say never.
-Phil
In practice, what was done was that the receiving UART powered up instantaneously, while the transmitting device had to boot even if it did so very quickly, so there was always a quiet period before the blast of data when the system was started.
Parts of the system being started one at a time was a failure mode they just didn't test or care about.
Erlend
You can also get continuous transmission if each byte is interrupt driven; the overhead to update the buffer is usually a trivial fraction of a byte frame duration, even on a circa 1980 device like the Toledo 8132. This was extremely common in 1980's era CPU-UART interfaces. In fact it wasn't until the late 1980's that UARTs emerged sporting multi-byte buffers, because those PC's were doing things like disc access that held them up for longer than the ever decreasing (because of increasing baud rate) serial frame lengths.