Max Baud Rate for Arduino Uno

Dear All,

I have a sensor which is interfaced with Arduino Uno and output is transmitted over usb-serial. I want to achieve the baud rate of 921600bps (max. in Windows). So, I changed the crystal to 14.7456 Mhz in hope that I'd get the required baud rate with almost 0% error.

But since then, my Uno's is unknown device to Window.

What should I do so it is recognized/run at Windows again and I can get 921600bps? Should I change Bootloader (which one, Atmega8 or Atmega328 ? and how...16Mhz resonator at Atmega328 is still intact) or should I make an another Arduino circuit with 14.7456Mhz on breadboard and upload the modified files by making the Uno as ISP? I have FTDI breakout board & USBasp programmer.

Thanks!

My impression is that the Atmega8U2 processor has been damaged.

Try a loop-back test with a different USB cable...

Don't know what happened but I couldn't get success with the new crystal with Arduino. Also, I realised that, it not the only thing that has to be taken care of but also the 16 Mhz resonator at atmega328 has to be changed as well (in my opinion). The tx/rx from atmega328 goes to atmega8 and then to Computer after ttl->rs232 protocol conversion in atmega8 itself. The resonator is really small and hard to solder.

I have replaced the old crystal, 16 Mhz and now it working/recognised once again by Windows. I suppose, I should make a another circuit with atmega328 with 14.746 Mhz crystal on breadboard. Then, I should think about ttl->rs 232 conversion.

I have checkout FTDI breakout with 921600 bps with 16 Mhz, it does not work and hangs (though FTDI claims that it does work upto 1 Mbps) but Arduino connection does.

Could MAX232 ttl->rs232 convert at say, 921600 bps? Which chip can be used here for ttl->rs232 for this baud rate, if MAX232 could not?

Thanks!

I have checkout FTDI breakout with 921600 bps with 16 Mhz, it does not work and hangs

Loop-back test?

Operating system?

Custom program or Serial Monitor or other terminal application?

Are you trying to get data into a PC efficiently as possible? Or do you really need exactly 921600bps to communicate to some other device?

I did a loop back test but as I said, arduino was not recognised as usb device so no com port at OS and no possibility to communicate, though Atmega328 seems to work fine as it could output the data on tx line which I could read by FTDI breakout. So, bootloader of atmega8 seems to be a problem.

OS is Window 7. I usually prefer Realterm & Teraterm for data monitoring over serial.

About the purpose, I have several Avago optical navigation sensors which I have to tests for performance and collect the data. The Serial Port interface of sensor has 2 Mhz as max. frequency. For your reference, ADNS 6090 (one of the sensor I am using): http://www.avagotech.com/docs/AV02-1362EN

Now, I wish to send some register addresses and retrieve some values in a continuous loop in bit banging way. The values I am interested are, Delta X, Delta Y, Shutter Value and Surface Quality. All are 8 bit register (Only one of sensor has 16 bit for Delta X and Delta Y, which are broken down as Delta X_L & Delta X_H, both 8 bit so double write & read effort). Register read is sequential.

Now, doing some maths, if 2 Mhz clock has 0.5 usec per cycle. If 8 bit is written (arduino->sensor)and then 8 bit is read (sensor->arduino), a total of 16 cycles of 8 usec for sensor. So, data is available at Arduino with 125 Khz (for a single register readout). Then Arduino must be using some 8 cycles or 1 cycle of 62 nsec each per register for sending data->tx line and assume sampling frequency by nyquist to be double of data available frequency. then question is how much baud rate should be sufficient? About 230.4 Kbps?

If you change the crystal frequency on either chip you will run into problems, and need to modify the firmware of both chips. Also, don't worry about 0% error, none of the standard baud have 0% error. Most UARTS can tolerate a certain amount of error. Ideally UARTs sample bits in the center of the bit. They align themselves at the beginning of the start bit. You can calculate how much shift should be tolerated in a standard 10 bit RS232 'byte'.

First, if you are using the Serial.begin(baud) function, you are asking for trouble with the different crystal on the Atmega 328. The Arduino environments assumes a 16MHz clock. By changing the crystal, you change the baud that is calculated.

Second, if you change the xtal on the Atmega8 (which if I read correctly, is what you did), you are messing up the USB timing. USB requires a specific freq that is generated by a PLL. You would have to change the firmware on the Atmega8 to modify the PLL settings to generate a correct clock for USB.

Third, FTDI is an interesting thing. USB does not work like serial. The host must poll the device at a given interval. If the buffers on the FTDI chip are full before the device is polled, things stop working. I have a write-up on my blog about FTDI latency and stuff.

You are right about "some" baud rate error. But someone told me that the maximum permissible error for rs232 for any baud rate is 5%. And, the baud rate I am aiming has a error of 7.8%. As the data would be used for further research and publication so I can't simply ignore that large error.

I came to know earlier that changing one crystal won't work. I had to change both, crystal and resonator. And, I have to make changes to the bootloader file of both uControllers, compile them and upload them. Only then they could work. So, now I am planning to make Arduino with 14.7456 Mhz crystal on breadboard and then burning the updated bootloader by making Uno as Arduino ISP. Then I will just take the data over RS 232 with FTDI, MAX or some other chip that works.

I have checked FTDI breakout again with different baud rates. It works upto 230400bps, above that 460800bps or 921600bps results in some characters stream. I have changed buffer, delay and so on as you suggested on your blog but still no success.

Do you have any idea, why this is happening?...the chip is FT232RL, it support upto 1Mbps then why it doesn't work above 230400bps?

Do you have an o-scope or something that you can verify you are generating the correct baud? Or if you have a counter and send 0xAA or something. FTDI chips are quite versatile, and you can do some crazy stuff on them, like bit banging protocols. Also, the FTDI chip might have a clock generation that doesn't work out to some nice multiple of 921600bps. You might have to try to get closer to 1Mbps, or dig more into FTDI if that is the route you want to go.

To be honest, I've never gone above 230000 baud before on something like an Atmega328 UART serial interface. It almost sounds like you just need a different piece of hardware. If you are spending this much time on modifying hardware, have you thought of something else? You could use an LPCXpresso board with the LPC1343 target. $20, comes with decent IDE. There is example code for using it as a HID device over USB. 72MHz uController, Arm Cortex M-3, SSP, but development is in naked C.

Maybe not completely your question but I have succeeded in using the standard serial in sketches at 230400 and 345600 baud. Higher non standard baudrates worked also
see - http://arduino.cc/forum/index.php/topic,61381.msg444421.html#msg444421 -

The reason why you may be off max 5% is that the first bit is sampled in the middle (50%) of the bitsignal. After one startbit and 8 databits this has drifted 95% = 45% closer to one edge, so only at 5% near the edge. At 6% deviation you get 96% = 54% and you are sampling the wrong bit. :frowning: Bigger deviations are even worse...

@ilektron
I started with AVR atmega128 but couldn't made it work with sensor. Arduino worked without much complication. Since then I have wrote code for all sensor with Arduino and they work fine. Only after going through some more detail that they might be a problem with baud rate error. Changing codes and getting used to new hardware would need more time effort which is not possible for me at the moment.

As I said, I am getting data around 125Khz so I think 230400Bps should do just fine. Though I will have a look into FTDI chip if something could be done. I also heard that MAX232 can do well upto 250kbps. Moreover, I have a Bluetooth module, which output a max. 1 Mbps...just need to set baud rate though AT command and see, if it works or not.

@robtillaart
Yes, that's why I thought of making some effort as to avoid the baud rate error.

Also, I just noticed that Teraterm could open port at any baud rate so as you said, if I change the baud rate at Arduino to be 16 Mhz friendly (under 5% error) then there shouldn't be any problem? If that could be done than no need to change the crystal, problem solved.

The baudrate is the rate at which the bits are clocked out. Remember that for a byte you normally need a startbit and between bytes there is some time. In practice you need to divide the baudrate by (10 .. 10.5) to get the nr of bytes.
When receiving bytes you need to process the bytes too, so in practice you will seldom reach the maximum speed.

Today, I did some tests on non-standard baud rates with Arduino. It seems, Arduino can communicate with non-standard baud rate which has divisor like 250Kbps, 500Kbps, 1Mbps etc. I tested upto 1 Mbps with Arduino USB-Serial.

In test, Arduino has to send registers data from sensor to serial/RS 232. Realterm was used to open port with non-standard baud rate and some data was captured in txt for visual inspection & verification. Data was consistent & expected, no deviations seen on visual verification.

So, my problem seems to be solved. :slight_smile:

Thank you all for valuable suggestions. If someone has more thought on it, please let me know.

What was the max baudrate you reached?
Did you test both send / receive?
Can you post your testcode for those who find this thread interesting at a later moment?

I tested once again at max of 2Mbps. Even this seems to work without a problem.

I am receiving the data from the sensor. Arduino must send the data of 4 register readout & last one, 1 pin state...the data look like this ";51,255,65,2,0;" ...where ";" separates the whole iteration. "51" is product ID of sensor. On visual inspection of captured txt file, that Product ID was consistent in captured files of size of 24 KB, 35KB and 40KB.

I will post the codes for all the sensor on my webpages (which are under construction).

I tested once again at max of 2Mbps. Even this seems to work without a problem.

You added a point on my TODO list as this would be a speed that could be acceptable in an IRQ routine. Would send a long in 2usec
Still wiondering if receiveing would work too at such speed.

Looking continuous on the screen, I can see a lag every 2-3 sec on Teraterm in which the lines are updated. It may be related to the buffer.

Now, a new question came to my mind. Ok, I can set the 1Mbps - 2Mbps on these terminal but am I really getting these transfer rates?

If I do some maths, I have "51,255,65,2,0;" data packet, each of which is 10 Bytes, and in 2 second, the txt file becomes around 25KB = 25000 * 8 bit = 200000 bits, so the transfer rate is indeed 100Kbps instead of 2Mbps!

Any thought?

Still wiondering if receiveing would work too at such speed.

Well keep in mind that if you are using interrupts that interupts are disabled while inside your ISR, and if the recieve characters are screaming in the receiver pin with interrupts disabled, dropping characters are possible.

Lefty

2Mbs = interrupt occurring at 200Khz (assuming 1 start, 1 stop, 0 parity) , which gives you 16Mhz/200Khz = 80 clock cycles in between interrupts. If assume single cycle instructions, after saving and restoring context for the ISR, reading the data, and whatever else you need to do, you are looking at not a lot of time.

I understand a continuous stream at this speed is beyond Arduino's caps, but if bursts of data could be send this fast it opens up possibilities.

If I do some maths, I have "51,255,65,2,0;" data packet, each of which is 10 Bytes, and in 2 second, the txt file becomes around 25KB = 25000 * 8 bit = 200000 bits, so the transfer rate is indeed 100Kbps instead of 2Mbps!

Any thought?

numbers look quite realistic to me. It just means that you are communicating approx 5% of the time (rest of the time using for measurements, math, formatting etc)

Confirmed 2Mbit on Arduino 2009 ==> win7/64 realterm.exe

100K chars took 594 msec @ 200000 baud = 168350 bytes/second = 5.94 microsec/byte

Note this test sketch leaves no room for additional math so I consider this speed as an upper limit.

void setup()
{
  Serial.begin(2000000);   
  
  unsigned long t1 = millis();
  for (long i=0; i< 10000; i++)
  {
   Serial.println("12345678");  // 10 bytes incl \r\n  
  }
  unsigned long t2 = millis() - t1;
  
  Serial.println();
  Serial.println(t2);  
}

void loop()
{
}
1 Like