1
\$\begingroup\$

I am trying to send out large amounts of data at 115200 via UART. I have come across a rather strange problem. I am sending out data in the while loop of the MCU. The MCU is not doing anything else. I am bitbanging UART via a IO pin. I observe that if I open up minicom and then start UART the data is observed correctly. However if I start UART and then open up minicom I dont get the right data. I suspect this has something to do with stop and start bit detection. Since when I randomly open up minicom it takes the stop bit and start bit to be one of the data bits and the data is not correct. This is because the data is being sent out all the time. Does this sound like a reasonable explanation? Or is there something else?

Traces: http://wikisend.com/download/389684/notworking.csv http://wikisend.com/download/977160/working.csv

Not working

This one is the working Working

\$\endgroup\$
  • 2
    \$\begingroup\$ There's nothing magical about start & stop bits in a UART, they're just like data bits. The receiving UART has no way of knowing whether its receiving a start/stop bit or a data bit. Some common ways of dealing with this are to insert delays or use a 'break' character to frame blocks of data (like DMX does). \$\endgroup\$ – brhans Jun 19 '16 at 4:45
  • 1
    \$\begingroup\$ Compare the output of your software UART on a scope to an actual hardware UART (such as whatever you are receiving with). You do not need to add delays, identify and fix what is wrong with your implementation \$\endgroup\$ – Chris Stratton Jun 19 '16 at 5:11
  • 1
    \$\begingroup\$ Your bit timing looks off. Notice the "framing errors" and the dots are not centered in the bits. How are you doing timing in your soft UART? \$\endgroup\$ – DoxyLover Jun 19 '16 at 6:31
  • 1
    \$\begingroup\$ @redcar, Have you tried with 2 stop bits? see if it get fixed after some bytes. \$\endgroup\$ – user.dz Jun 19 '16 at 7:13
  • 2
    \$\begingroup\$ @ChrisStratton - yes, which is why I suggested using it to "frame blocks of data". It will give the receiving UART something it can resynchronize on. While this situation is easy to recognize (due to the regular framing errors) it is almost impossible to fix without creating some sort of event which allows the rx UART to resync, no matter if the UART is implemented in hardware or software (how do you tell your UART 'ignore the next 3 bits' ... ?). A byte-long delay in transmission or a break character would both work perfectly. \$\endgroup\$ – brhans Jun 20 '16 at 13:16
1
\$\begingroup\$

It is of course possible that you have a bug in your bit-banged UART implementation. How do you do your timing, do you loop spending an amount of time, or do you you loop until a ceratin moment in time has arrived (the only realistic way - beyond isosynchronous coding - to do this is to use a free-running timer). You could look at your output very carefully with a test character of 0x00 and see how much the timing (start of startbit to start of stopbit) deviates from the ideal. I would be comfortable with 1% or less, you might get by with a bit more.

That said, I agree with brhans. There are situations in which a accommunication between totally correct UART sender and receiver start at the 'wrong' moment and continues to be out of sync forever. This is a property of the UART protocol and has nothing to do with the quality (or lack thereof) of either side. The only way out is a pause in the transmission (a break is not needed) of more than a char's length.

As an illustration of the out-of-sync situation, consider a continous transmission of the pattern 0011111101 (8N1 format).

When the first 0 is interpreted as start bit, the data bits are 01111110, followed by a stop bit (1) and the next start bit (0). This is a totally valid stream of 0x7E bytes.

But when the last 0 is interpreted as a start bit, it is followed by 1 and 0011111101, which is interpreted as 10011111 and a stop bit 1, followed by a next 0 start bit. This is an equaly valid stream of 0x9F bytes.

I think (but did not try) that with other patterns there can be more than 2 valid ways to interpret a stream. I think (but again, did not try to prove) that using parity and/or more than 1 stop bit bit will reduce the chance of multiple interpretations but not eliminate it.

\$\endgroup\$
  • \$\begingroup\$ Increasing the delay after the stop bit seems to work. But is there any other way? \$\endgroup\$ – red car Jun 19 '16 at 11:22
  • \$\begingroup\$ As my argumentation should tell you, there is no other reliable way to get out of the multiple-interpretation situation. But if you can tolerate that the situation lasts for a number of characters, inserting a delay afer that number of characters is sufficient. \$\endgroup\$ – Wouter van Ooijen Jun 19 '16 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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