Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an Arduino Mega communicating with a Bluetooth adapter through one of the auxiliary hardware serial ports. It works, but there appears to be a corruption rate of approximately 1 in 200 small packets. In other words, about 0.5% of the packets are being corrupted, it seems. I have the option of configuring the serial mode on both ends. While I cannot decrease the baud rate for bandwidth reasons, I do have enough room to enable parity or a larger stop bit if that would help.

Granted the corruption is on the serial line and not on the Bluetooth, if I enable parity, will this actually decrease the corruption rate? Or will the corrupt bytes simply be dropped without being re-sent? In other words, what happens when the hardware detects a bad byte?

share|improve this question
    
"Granted the corruption is on the serial line" in the somewhat unlikely case that is actually true, you have fundamental problems in your system which you should be trying to solve. With no information about the nature of the "corruption", we can't even rule out a programming mistake (not uncommon when juggling multiple serial devices) at this point. Understanding exactly how the actual data differs from the expected may be a key guide to what is actually wrong. – Chris Stratton Feb 22 at 6:56
    
You seem to be detecting corruption. How are you detecting corruption? – slebetman Feb 22 at 8:04
    
The Bluetooth protocol for serial communication has several encoding layers to avoid corruption. You might have a race condition in your code that is giving this. What does the ISR load look like? What baudrate and message frequency? And what is the communication "environment"; distance, electronics, wifi, etc. – Mikael Patel Feb 22 at 9:33
    
You could consider adding Hamming code. This will double the message size but you can get 1 bit error correction and 2-bit error detection. – Mikael Patel Feb 22 at 9:47
    
@ChrisStratton, I have only one serial interface enabled on the Arduino. – Michael Feb 22 at 11:46
up vote 3 down vote accepted

Parity doesn't, and was never intended to, decrease corruption.

All parity does is allow you to DETECT errors. If you detect errors, you still have to handle them.

Parity in memory is usually fatal - your code or data is corrupt, the solution is to halt the box, to stop this corruption (in memory) getting on to disk.

When used in communication (as it is here), parity errors usually mean you have to request a re-transmit (or, if acknowledgements are sent back, fail to send an acknowledgement and wait for an automatic re-transmit).

Also, be aware that the relevant error rate is per bit, not per packet. If a small packet (very small!) is 20 bytes, and there is corruption 0.5% of those packets, this indicates a 0.5% / 20 bytes per packet / 8 bits per byte (assuming 7 data bits, 1 parity bit, for example). This comes out to 0.003% errors.

Note that parity checks only work for 1-bit errors - in fact, a 2-bit error (in the same byte), the parity change will cancel out, and it will look ok.

An alternative to requesting re-transmits, is to use forward error correction - send redundant data (reducing your bandwidth). A very easy scheme is to send each packet twice (halving your bandwidth). You still need error checking (or some checksum) - if two packets are different, you still need to know which one was right. Checksums, on a more complex device, could let you try each combination, but for an Arduino, this would probably be too expensive (the code would take up sizable space, which an Arduino may, or may not, have spare).

All of this is usually written into higher level protocols (TCP, used for most internet file transmission, ZModem file transfer used for modems prior to the Internet). Other protocols, such as internet radio, will use either forward error correction, or will accept the occasional glitch.

share|improve this answer
    
My packets are actually quite small. The largest one is around 18 bytes. The ones in question are something like 7 bytes. I have not looked into the corruption closely enough to know what type of corruption it is. I do not know, for example, whether there is a missing or extra byte, or whether one or more bytes are corrupted. My protocol was designed around corruption from the start, so it is not a big deal. I just wanted to know whether parity would help. I actually come from the network world, so that side of things I know very well. The electrical stuff is where I have limited experience. – Michael Feb 22 at 6:14
    
By not looking into the nature of the corruption, you are wasting everyones time as we cannot tell you if parity would help. Voting to close. – Chris Stratton Feb 22 at 13:55
1  
@ChrisStratton, Wasting everyone's time? I think not. This discussion about parity is important. You seem to be assuming the problem is not in the serial. Whether or not the problem in my case is in the serial is completely irrelevant to the hypothetical case that it is. I am not asking others to solve my problem. I was simply asking whether parity or a longer stop bit would decrease corruption caused by a low quality serial connection. The answers so far are quite educational for many people. SE is not just about solving the OP's problem. – Michael Feb 22 at 14:07
    
Your question cannot be answered without knowing if you are getting altered characters or missing ones. Note that substituted is not the same as altered. Questions insufficienctly specific to be answerable are off topic here - this is not a discussion forum. – Chris Stratton Feb 22 at 14:08
    
@ChrisStratton, I agree that my particular case would require more information to give a definitive answer, but the hypothetical question about parity can, and seems to have been, answered as-is. If it matters to you, my data so far suggests that specific bytes are being corrupted, hence the bad nonce values on otherwise successfully returning ping responses. Perhaps I will do further testing later, but so far I feel the answers here have been helpful and informative. – Michael Feb 22 at 14:15

Parity by itself does not reduce the error rate, it is used to detect errors. It is up to higher level protocols to determine what to do when the error is detected.

To answer your question about stop bits, going to two might help. The extra stop bit adds a 1-bit-time gap between characters and gives the receiver a little more time to sync up with the transmitter. If the baud rates are a little off between the sender and receiver, it would make it more likely that errors would be limited to one character rather than a whole string of them. That said, the 2 stop bit option is mostly a relic from the days of mechanical Teletype machines. These days it is usually better to make sure both clocks are at the correct frequency.

Have you determined where the errors are occurring - in the serial connection between the Mega and the BT adapter, in the BT link itself, or at the other end? With short wires, correct baud rates (check for the correct clock frequency), a good ground, and correct logic voltages, the raw error rate in the serial connection should be extremely low. I would focus on finding the source of the errors before trying to correct them.

share|improve this answer
    
If this is true that parity itself is only for indication, then I can understand why it is often disabled by default these days. I would rather use a hash to check for data integrity than a single bit anyway. I guess parity is just a vestige of the olden days. As for the source of the errors, I have no idea. I am relatively new to serial, and I am very new to programming for Bluetooth (BLE). The wires are indeed short, and the ground is definitely good. The voltage may be a little off, but that may not be worth messing with since the Mega likes 5V and there are other pins using 5V input. – Michael Feb 22 at 6:24
    
The thing is, I actually started with software serial, which was giving me a packet corruption rate of around 20% (only barely affected by baud rate). Now that the corruption rate is more like 0.5% by using hardware serial, I am pretty happy with it overall. I just wanted to make sure I was not missing any tricks to make it extra clean. – Michael Feb 22 at 6:28
    
@Michael - that strongly suggests that what you actually have is a mistake in your program. – Chris Stratton Feb 22 at 7:00

I am guessing that the problem is that your clock is not 100% divisable to produce exactly 115200. If so it makes sense that communication sometimes fail.

See this question for more details, in particular the link to WormFood's AVR Baud Rate Calculator.

share|improve this answer
    
That is very interesting actually. According to WormFood (which I had actually referenced in my initial implementation over USB virtual serial), 76800 would be an ideal high baud rate for a 16MHz CPU. Unfortunately, the HM-10 Bluetooth controller does not have any options between 57600 and 115200. When I used USB, I had the baud at 125000 (16MHz divided by 128), which seemed to work very well. – Michael Feb 22 at 13:49

Parity checking will only let your code detect a corrupted byte, and not very well at that. Assuming your primary goal is to get packets transferred reliably, you'd be better off to add a checksum to each packet sent, testing the checksum when the packet is received, and asking the transmitter to re-send a failed packet. Since you only expect 1 packet in 200 to be retransmitted, your bandwidth shouldn't take a big hit.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.