# Serial data received in wrong bits

I have an RS422 interface set up between an Arduino and a custom-built device. The device is set to transmit a 16-bit header, followed by 66 bytes of data, at a baudrate of 460,800 and at 200Hz. This cannot be changed.

I have read online that the Arduino serial can handle 460,800 bps without a problem. In fact, I have successfully communicated between MatLab and Arduino at that baudrate without problems. I have also confirmed that the device works, as when it is connected directly to the computer, it is read fine.

When I try to read the data using the Arduino, I don't get what is expected. The header I'm supposed to be getting is 0x55AA. I am, however, getting 0xD56A most of the time, but sometimes I get values like 0xB5CA. It seems the second half of each byte is correct, but not the first, and I have some bits going high and some going low when they shouldn't. Because of this, I question the validity of the data being transmitted.

Can someone explain to me why this is happening, and what solutions I can try to remedy this, please?

Thanks

UPDATE: I have looked through with an oscilloscope and I can see the waveform coming out as 0x55AA, as it should be. I have increased the Arduino serial buffer, and changed boards, but the problem persists.

I managed to get it working at a lower baudrate (115,200), but I need to have it set at 460,800. At this lower baudrate, I would get 0x55AA, but as sson as I ramp it up to 460,800, I lose this data and it becomes as mentioned above.

• What makes you think there is only one reason your described symptoms can happen? – PlasmaHH Apr 27 '15 at 12:17
• If you have access to a scope, now is a good time to use it. – user_1818839 Apr 27 '15 at 12:21
• Do you ever get the correct header? – Andy aka Apr 27 '15 at 12:29
• @PlasmaHH I'm not saying there is only one cause, I'm just asking for an explanation as to why this is happening, and how to resolve it. – Tom Apr 27 '15 at 12:55
• @BrianDrummond The scope shows 0x55AA, as it should. – Tom Apr 27 '15 at 13:00

First, let's look at the data you mention:

0x55AA  0101010110101010
0xD56A  1101010101101010
0xB5CA  1011010111001010


As we can see, the data is close, but slightly off. The reasons for serial data being "slightly off" are many, but an obvious one in your particular case is the serial data rate. In order for asynchronous serial data to be received correctly, the original clock must be recreated at the receiving end. A rule of thumb for serial links is that if the clock rates are off by more than 3%, you'll get errors much like the ones you describe.

So at a rate of 460,800 bits/second, that's a little over 2.27$\mu$s per bit. Here's some troubleshooting advice:

1. check the bit rate clocks on both ends and make sure the frequencies are within 3% of each other.
2. keep your wiring as short as possible.
3. check the line termination on both ends to make sure it's got the same impedance as the line.
4. check the received waveform with an oscilloscope. Look for ringing or slow transitions.

You might also consider if there is a CRC in the packet that would at least help you detect an error.

## How to check clocks

First, let me state my assumptions:

1. each side is able to send arbitrary data
2. data is being sent in 8-N-1 form (8 data bits, no parity, 1 stop bit)
3. you can set up either end to send continuously

With that said, let's look at how serial data is typically sent. Let's look at the bytes 0x55, 0x55 as they might be sent on a single-ended (RS-232) data link.

+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+
S   1   0   1   0   1   0   1   0   P   S   1   0   1   0   1   0   1   0   P


In this diagram, S is a start bit and P is a stop bit and the 8 data bits are sent least significant bit first, as is the usual. It should be clear from looking at this that if you measure the frequency of this waveform, it should be exactly half the bit rate.

• There is a checksum at the end of the message, but because I can't get the header correct, I don't particularly trust the rest of the data, including the checksum's value. I have a feeling it is much more likely to be the clock rate. It used to work at a baudrate of 115,200 , but I've had to chanage that. 2.27us is indeed fairly short. How would I go about checking this? – Tom Apr 27 '15 at 13:11

What clock rate do you use?

With an 8 MHz clock I cannot find an acceptable prescaler value for 460800 baud. 14.7456 MHz might do the job ("WormFood's AVR Baud Rate Calculator").