Serial error rate (Hardware)

I'm losing bytes when I send data from the Arduino to the PC... is this normal?

I seem to lose about 1 out of every 2000 bytes, with a pretty random distribution.

No, this is not normal.

What else is going on on the PC? What baud rate are you using?

I seem to lose about 1 out of every 2000 bytes, with a pretty random distribution.

It depends on what you are running at the PC end. Hyperterminal is quite prone to doing this where as Terra Term isn't.

I'm using a program I've written in C, pretty much all data is coming from the Arduino. I only send 2 bytes to the Arduino. I have tried lots of baud rates: 500, 9600, 38400, 115200, 1000000, 2000000, 3000000.

I'm sending data pretty fast, but the dropped bytes happen even when I delay each byte by a full millisecond.

It looks like the serial drivers on your PC are a bit wonky. I can't see the Arduino miss sending data so it must be the receive end.

Sorry I can't be more helpful.

Yeesh, nevermind, I found it.... stupid programming mistake.

When I read from the serial port I looped through the buffer and found all my 3-byte messages and then copied any remaining bytes to the beginning of the buffer to be processed on the next go-round. When I read from the serial port the next time I just offset the read() after the old bytes... almost... I was accidentally offsetting by both the current extra bytes and the extra bytes from the previous read...

I now lose 1 in several hundred million bytes at 195Kbyte/sec(2Mbaud)... which is very reasonable for an asynchronous serial port with no flow-control.

Thanks for letting me know this problem wasn't normal... It's hard to trust a platform you aren't familiar with.


Now to get my 3Mbaud connection working this well... I still get pretty high error rates (1 in 50000 bytes goes missing). I'm not certain if this is because: - I'm pushing the limits of the FTDI chip. It maxes out at 3Mbaud - I'm pushing the limits of the Amtel328... it maxes out at 4Mbaud @ 16Mhz - My frequency divider may be crap; it's made from stuff I had laying around. I need a real oscilloscope...

A common misconception is that an N baud connection implies that you are transmitting N bits per second. No, the baud rate only refers to the width of the bits within each byte. At 3Mbaud, each bit is 1/3,000,000 of a second in length. Once a byte has been transmitted, there is no guarantee that the next byte will immediately follow on its heels. You could send 1 byte every 10 seconds at a nominal 3Mbaud bitrate, but really only be getting an effective rate of 10 bit per second.

What I'm getting around to is that your problem is not due to "pushing the limits of the Atmel328". The slowest processor in the world can transmit at 3Mbaud as long as it is connected to a UART that can transmit a byte at that bit rate. You won't get 3 million bits per second, but you will get 3Mbaud.


3Mbaud is pushing the limits of the USART that is in the AMTEL328.

The Amtel328/168 can only generate a baud rate of 1/8th the system clock(16mhz=2Mbaud), to go higher you have to use an external clock. The fastest you can go with an external clock is 1/4th the system clock.

The 328's manual warns against going to close too the maximum external clock

"Note that fosc depends on the stability of the system clock source. It is therefore recommended to add some margin to avoid possible loss of data due to frequency variations."

To run at 3Mbaud I'm dividing the 12Mhz clock from the FTDI chip down to 3Mhz and feeding that to the Arduino's USART. 3Mhz doesn't evenly divide into 16Mhz. The pulses in a serial frame should be 5.3333 CPU clocks long at 3Mbaud for a 16Mhz Arduino, but they are likely alternating between 5 and 6 clocks.

Anyhoo... only getting garbage every 50000 bytes doesn't sound too bad after thinking about the rounding that is happening.

I'm getting an effective datarate of 290kbytes/sec at 3Mbaud.

Thinking this through further... it may be better to use 2.6666Mbaud by dividing the 16Mhz system clock by 6. The FTDI chip internally runs at 48Mhz, which can do 2.6666baud by sampling every 18clocks.

Cutting the speed by 12% would be worth improving the reliability several fold.