Searching \ for 'Auto adaptive(?) serial routine' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/io/serials.htm?key=serial
Search entire site for: 'Auto adaptive(?) serial routine'.

Truncated match.
PICList Thread
'Auto adaptive(?) serial routine'
1995\11\25@075208 by mauricio

flavicon
face
Hi everybody,

In one of my applications, I need a serial RX/TX routine capable to
'recognize' the speed of the serial line, so it can adjust itself to
that speed (eg. I have a '84 based 'host' to which I want to attach
few 'terminals' working at 1200, 2400, 4800, 9600 baud).
Did anybody try something similar?
Any ideas on how to determine the RX speed, possibly without loosing
a byte of data?

Thanx,

Max

1995\11\26@165816 by Peter Jennings

picon face
I have done such a thing for other processors, but not the PIC (yet).

In general, all you have to do is time the start bit and use the
count as the time delay for sending and receiving bits. It is
necessary to carefully craft loops that are symmetric for
time determining, sending and receiving. No big deal really.

The first byte detected needs to be one with a space after the
start bit, so you are restricted in what characters can be used
for the rate detection. After that, any character can be received.
'*' 02Ah is a popular choice.

If you only send the right characters, I suppose you could do
speed determination on every byte, but it is more usual to only
check on the first character received after a reset or other
external indication. You could use the DTR as an indicator.

{Quote hidden}

--                                 .....peterjKILLspamspam@spam@netcom.com

1995\11\27@000958 by Joel Carvajal

flavicon
face
On Sat, 25 Nov 1995, Mauricio Culibrk wrote:

> Hi everybody,
>
> In one of my applications, I need a serial RX/TX routine capable to
> 'recognize' the speed of the serial line, so it can adjust itself to
> that speed (eg. I have a '84 based 'host' to which I want to attach
> few 'terminals' working at 1200, 2400, 4800, 9600 baud).
> Did anybody try something similar?
> Any ideas on how to determine the RX speed, possibly without loosing
> a byte of data?
>
> Thanx,
>
> Max
>

I haven't tried it myself but a lot of people have done that already.
However, I'm not sure what do you mean by "..without loosing a byte of
data?".  Usually, you connect to something (host) that is already sending
data, for synchronization with whoever wants to connect.  The data usually
is such that you could actually try all possible baud rates (brute force,
but you could think of other techniques) and then when the expected data
is finally received, you inform the host that you are know synchoronized
with his baud rate.  So in that case, you do lose some bytes of data  but
its OK.  Those data are for, as I said, to,let you synchronize with the host.

To summarize, in order to connect to a host at his baud rate, the host
must send a "synchronization" data.  Of course you must know the data.
You then adjust your baud rate until you receive the correct data.  When
you finally is in "harmony" with your host, inform him, and the
rest of the communication then proceeds.

Hope I was of help.  Good luck!

1995\11\28@082426 by Andrew Warren

flavicon
face
Mauricio Culibrk wrote:

> In one of my applications, I need a serial RX/TX routine capable
> to 'recognize' the speed of the serial line, so it can adjust
> itself to that speed (eg. I have a '84 based 'host' to which I
> want to attach few 'terminals' working at 1200, 2400, 4800, 9600
> baud). Did anybody try something similar? Any ideas on how to
> determine the RX speed, possibly without loosing a byte of data?

Joel Carvajal <joelspamKILLspamTDS.PFI.NET> replied:

> To summarize, in order to connect to a host at his baud rate, the
> host must send a "synchronization" data.  Of course you must know
> the data. You then adjust your baud rate until you receive the
> correct data.  When you finally is in "harmony" with your host,
> inform him, and the rest of the communication then proceeds.

Mauricio:

If you're sending standard ASCII using no parity, 8 data bits, and 1
stop bit, you don't need to send a string of known synchronization
data at the start of your transmissions as Joel suggests.

Instead, you can simply start a timer at the first HI-to-LO
transition (the start bit), then check the timer at every LO-to-HI
transition.  Set the timer up so that it'll time out after slightly
more than the length of 9 bits at your slowest baud rate (>7.5
milliseconds for your 1200 baud rate).  I'd probably set the timer
to expire in 8.192 milliseconds; if I used the RTCC and were running
at 4 MHz, I'd set the prescaler to divide-by-32 so that the timer
could be contained in just one byte.

When the timer expires, the value it contained at the last LO-to-HI
transition will be the time between the leading (falling) edge of the
start bit and the leading (rising) edge of the stop bit.  A simple
table-lookup will tell you what baud rate you're receiving.

This technique works because the MSB is never set in standard ASCII,
so the leading edge of the stop bit will always be visible.

Note that this technique will NOT work if there's no delay between
one character and the next; the second character must not be
transmitted until at least 8.192 milliseconds after the start of the
first character.

-Andy

Andrew Warren - .....fastfwdKILLspamspam.....ix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geopages.com/SiliconValley/2499

1995\11\29@102333 by mauricio

flavicon
face
Thanx to all that responded to my questions.

Max

1995\11\29@143824 by Lee Jones

flavicon
face
Mauricio Culibrk wrote:

> In one of my applications, I need a serial RX/TX routine capable
> to 'recognize' the speed of the serial line, so it can adjust
> itself to that speed (eg. I have a '84 based 'host' to which I
> want to attach few 'terminals' working at 1200, 2400, 4800, 9600
> baud).

I meant to reply earlier and got busy.  Sorry.

There are both synchronous and asynchronous serial communications.
With sync serial, a separate wire provides a clock transition in
the middle of each data bit.  No such thing as baud rate detecting.
I'll assume you mean _async_ serial comm.

With asynchronous serial, the data is sandwiched in between a start
bit and a stop bit.  Normally, there are 8 data bits between as in
the following diagram:

  0  marking     !---:''':''':''':''':''':''':''':''':
                 !   :   :   :   :   :   :   :   :   :
  1  spacing  ---!   :...:...:...:...:...:...:...:...:---:
                 Start 0   1   2   3   4   5   6   7  Stop

RS232 specified the physical properties of the interface.  This
includes voltages.  At the transmitter, logic 0 or "spacing" is
+5 to +25V while logic 1 or "marking" is -5 to -25V.  Marking and
spacing are terms that date back to Teletype days.

RS232 receiver must accept -25 to -3 or +3 to +25.  Range between
-3 and +3V is supposed to be used for hysteresis to reject noise.
Lots of receiver chips do NOT handle the -3V to +3V range correctly.
Their rejection band is about 1/2 a volt somewhere around 0V.

Note that the transmitter side minimum output is specified as a
higher voltage than the minimum specified at the receiver to allow
resistive drop in the wire.  Also, it's a 1-wire voltage based
interface, so you need a ground wire.  And be carefull of current
flows between the equipment on the ground wire -- particularly if
the two ends are located some distance from each other.

Normally an async RS232 interface is idle and marking (-5 to -25V).
When a character is transmitted, the start bit guarantees a low to
high transition (from marking to spacing).  The stop bit is used to
guarantee that (irrespective of the data) in a continuous stream of
characters, the line will be driven back down to the marking state
before the next start bit is sent.

When you see the leading edge of a start bit, you should wait 1/2
bit time and then sample again.  If the line is back at marking,
then you ignore it as noise.  This helps reject noise pulses of up
to 1/2 bit time.


The "baud rate" is the number of bits per second when the line is
running continuously.  The difference between bits per second and
baud rate is that baud rate may vary from 0 bps to maximum.  Thus
the baud rate is the correct term for an async line while BPS (bits
per second) is correct for a sync line.  [Misuse of this term is a
pet peeve of mine.]  So for 1200 baud, each bit is 1/1200 second wide.

The data bits are sent LEAST significant bit first.  Originally,
Teletypes used 7 data bits(*).  The 8th bit (data bit 7 above)
was used for a parity bit.  With inclusion of the parity bit, if
you counted up all the 1's data bits, you got an odd number (for
odd parity) or an even number (even parity).  Now the 8 data bits
are all used for sending 1 octet (aka byte) from the computer.

For example, an ASCII J (capital J, dec 74, octal 112, hex 4A) is:

  0  marking     !---+---!   !---!   !---+---!   !---!
                 !       !   !   !   !       !   !   !
  1  spacing  ---!       !---!   !---!       !---!   !---
                 Start                                Stop
  ASCII J (4A hex) =   0   1   0   1   0   0   1   0

While, an ASCII A (capital A, dec 65, octal 101, hex 41) is:

  0  marking     !---!   !---+---+---+---+---!   !---!
                 !   !   !                   !   !   !
  1  spacing  ---!   !---!                   !---!   !---
                 Start                                Stop
  ASCII A (41 hex) =   1   0   0   0   0   0   1   0

Now a more direct reply to your question.  I assumed you wanted to
sense baud rate because you weren't in control of both sides of the
communications link.  And at power up, the other end might have
changed and be at an unknown rate.  And I assume that you are NOT
using a built-in USART (like in the PIC 16c65 or 16C74).

So I'm assuming you have a 1 bit input watching the received async
data line.  You can look at the start bit width to determine baud
rate -- ASSUMING the first data character cooperates.  Note that the
example of A above allows this, the J does not (result would be off
by a factor of 2).

As a cross-check, you use the measured bit time to check for a stop
bit at the expected location.  If the stop bit is not at a marking
state, then you have a framing error or data overrun.  Maybe it was
noise or whatever, but you have to try again.

So you can auto-sense baud rate if the low order bit of the first
character is a 1 (50% probability).  Luckily, common characters that
people use to "wake up" a system are all odd (i.e. have a low order
bit of 1) like carriage return (13 dec, 0D hex), escape (27 dec, 1B
hex), or control-C (03 hex).

This also shows why, without knowing ahead of time what the first
character is, you cannot auto-detect baud rate without the possibility
of loosing a character.

Hope this long discussion wasn't too boring and is helpfull.

                                               Lee Jones

(*) Way, way back the Teletypes used 5 data bits, but I'll ignore
   that for this discussion.  Early Teletypes at 110 baud also
   used 2 stop bits -- but everybody uses 1 stop bit now.

-------------------------------------------------------------------
Jones Computer Communications             EraseMEleespam_OUTspamTakeThisOuTfrumble.claremont.edu
509 Black Hills Dr, Claremont, CA 91711         voice: 909-621-9008
-------------------------------------------------------------------

1995\11\29@163614 by rdemay

flavicon
face
> In one of my applications, I need a serial RX/TX routine capable
> to 'recognize' the speed of the serial line, so it can adjust
> itself to that speed (eg. I have a '84 based 'host' to which I
> want to attach few 'terminals' working at 1200, 2400, 4800, 9600
> baud).

Alright,
  I've read a few of the suggestions on an autobauding, almost
everyone included a critical point on the subject.   But I didn't
see one that included all of key considerations (especially
importance of what the data stream looks like).

1.  Is first character known?  If so the baud rate can be determined
by measuring the time from beginning of start bit to
first bit that is a mark (logic 1).  Based on where this bit is
located in the character you can determine the baud rate --
i.e. if it's bit 0, then the measured time is the width of 1 bit.
With this method you won't lose any characters.

2.  If the first character is unknown, you must consider what
the data stream "looks like"? Is the stream continuous? Are the
characters "back to back"? (It's very simple to transmit data at
9600 baud without any space between charaters)  Is there
a pattern (CR/LF after every 80 characters for example)?

If characters are are at least 8.33milliseconds apart (1 character
at 1200 buad), then measuring the time from start bit to stop
bit will work (with 8.33 millisecond timeout of course).  You
always lose one character with this method.

Worse Case: If the characters are continuous, back to back and with no
pattern (and first character unknown), ahhhhhh ---- what
in the world are you going to do with this anyway (just
kidding)?  If this is the case, it's rather difficult to get in sync
and determine the baud rate (data better not be critical!).
You can try keeping track of the shortest 1-0-1 width time
(obvious limit this to .104 milliseconds --1/9600).   For
example: a 1-0-1 width of .208 ms, can't be 1200 & 2400 baud
but can be 4800 or 9600, so you assume 4800 until you measure
one of .104 ms.  You will need to get in sync with the start bit
as well (stop bit must line up on every character -- if not
try again).


As you can see, several methods of autobauding will work, but
you need to know what the datastream looks like before you
can determine which method is best.

:)

Rod
rdemayspamspam_OUTbb-elec.com

1995\11\29@170329 by Przemek Klosowski

flavicon
face
  Worse Case: If the characters are continuous, back to back and with no
  pattern (and first character unknown), ahhhhhh ---- what
  in the world are you going to do with this anyway (just
  kidding)?  If this is the case, it's rather difficult to get in sync
  and determine the baud rate (data better not be critical!).

I suppose in that case you have to collect a second or so of data, run a FFT
and select the lowest frequency :^)

1995\11\30@082152 by mauricio

flavicon
face
Hi!

Thanx to Rod, Lee, Andrew and all others who spend their time to answr me...
Basically, I had the same idea to detect the baud rate, with respective
limitations (known first byte....). As I said, I wont't loose any
byte of async serial data, so I just wondered if there are some tricks...

Thanx again,

max

More... (looser matching)
- Last day of these posts
- In 1995 , 1996 only
- Today
- New search...