Go Down

Topic: Auto Detect Baud Rate (Read 3653 times) previous topic - next topic

retrolefty

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: [Select]
/*
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


jwatte


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.

Graynomad

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

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Nick Gammon

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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Graynomad

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
Rob Gray aka the GRAYnomad www.robgray.com

retrolefty

#20
Mar 30, 2012, 04:38 pm Last Edit: Mar 30, 2012, 04:40 pm by retrolefty Reason: 1

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


Go Up