Pages: 1 [2]   Go Down
Author Topic: Auto Detect Baud Rate  (Read 2478 times)
0 Members and 1 Guest are viewing this topic.
Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16542
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to give the thread a update to help future searchers, below is the sketch I played with over a year ago to do auto-baud rate, based on the assumption that the first detected incoming character does contain a valid detectable single bit width pulse, such as a 'U' suggested.

Code:
/*
 First stab at a auto baudrate detection function. This uses the pulseIn command
 to determine what speed an unknown serial link is running at. Detects and sets the standard baud
 rates supported by the Arduino IDE serial monitor. Uses character "U" as a test character
 
 I'm sure characters with multible zero bits in a row may fake out proper detection. If data is
 garbled in the serial monitor then the auto baud rate function failed.
 
 This is just a demo sketch to show concept. After uploading the sketch, open the serial monitor
 and pick a random baudrate and then start sending U charaters. The monitor will print out
 what baudrate it detected. It will default to 9600 baud if found a bit
 width too long for a standard rate used by the serial monitor. Note that as written, this is a
 'blocking' function that will wait forever if no character are being sent.
 
 Note that while the serial monitor has a 300 baud option, the Arduino hardware serial library
 does not seem to support that baud rate, at least for version 22, in my testing.
 
 By "retrolefty" 1/22/11
 */
 
int recPin = 0;  //the pin receiving the serial input data
long baudRate;   // global in case useful elsewhere in a sketch
long rate=10000;

void setup()
 {
  pinMode(recPin, INPUT);      // make sure serial in is a input pin
  digitalWrite (recPin, HIGH); // pull up enabled just for noise protection
 
  baudRate = detRate(recPin);  // Function finds a standard baudrate of either
                               // 1200,2400,4800,9600,14400,19200,28800,38400,57600,115200
                               // by having sending circuit send "U" characters.
                               // Returns 0 if none or under 1200 baud 
  Serial.begin(baudRate);
  Serial.println();
  delay(100);
  Serial.flush();
  Serial.print("Detected baudrate at ");
  Serial.println(baudRate);
  Serial.println();
  Serial.print("rate in usec =  ");
  Serial.println(rate);
   


 }

void loop()
 {
 
  if (Serial.available() > 0)
   {
    // get incoming byte:
    int inByte = Serial.read();
    Serial.print(inByte,BYTE);           
   }
 }

long detRate(int recpin)  // function to return valid received baud rate
                          // Note that the serial monitor has no 600 baud option and 300 baud
                          // doesn't seem to work with version 22 hardware serial library
  {
   
   
    /*
    long baud, rate = 10000, x;
  for (int i = 0; i < 10; i++) {
      x = pulseIn(recpin,LOW);   // measure the next zero bit width
      rate = x < rate ? x : rate;

   
    */
   long baud,  x;
   
   for (int i = 0; i < 5; i++)
     {
      while(digitalRead(recpin) == 1){} // wait for low bit to start
      x = pulseIn(recpin,LOW);   // measure the next zero bit width
      rate = x < rate ? x : rate;
     }
  // long rate = pulseIn(recpin,LOW);   // measure zero bit width from character 'U'
     if (rate < 12)
      baud = 115200;
      else if (rate < 20)
      baud = 57600;
      else if (rate < 29)
      baud = 38400;
      else if (rate < 40)
      baud = 28800;
      else if (rate < 60)
      baud = 19200;
      else if (rate < 80)
      baud = 14400;
      else if (rate < 150)
      baud = 9600;
      else if (rate < 300)
      baud = 4800;
      else if (rate < 600)
      baud = 2400;
      else if (rate < 1200)
      baud = 1200;
      else
      baud = 0; 
   return baud;
  }

Lefty

 
Logged

Offline Offline
God Member
*****
Karma: 3
Posts: 813
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure if you received 50 bytes with only the lower bits set to 0 you would be fooled because they would merge with the start bit, but that won't happen with a GPS data stream.

No, that would be the best case, because the low-then-stop-then-start-then-high bit combination will generate a one-bit pattern. But there are certain worst-case patterns. As you say, they are extremely unlikely.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8458
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe I should have said "only the upper bits set to 0", I always forget if it's LSB or MSB first.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's LSB first and here is why: You don't necessarily send all 8 bits. So it makes sense to start with the least significant, and stop when the required numbers of bits are sent.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8458
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, so my original description was correct, if you have all bytes with lower bits = 0 then they are merged with the start bit and will fool the algorithm.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16542
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, so my original description was correct, if you have all bytes with lower bits = 0 then they are merged with the start bit and will fool the algorithm.

Yes, any attempt to assume that there is a valid single bit width avalible for measurement with any single arbitrary character received is simply a flawed algorithm. Trying to measure the complete frame time is also subject to spoofing if using arbitrary characters.

Lefty


______
Rob

« Last Edit: March 30, 2012, 09:40:36 am by retrolefty » Logged

Pages: 1 [2]   Go Up
Jump to: