"Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I have a counter example to awneil's list entry (in the subject line).

 

This was with a Mega328P but that is pretty much not relevant. This is NOT an electronics issue, particularly, but it was due to electronics which I inadvertently abused to the point where they  malfunctioned. This is not really about compilers, but it is sort of about "general programming" in the sense that an improperly written program was the source of the hardware abuse. So, here is where it rests, for the moment.

 

I have a program that goes to sleep at the "end" of a loop. A sensor "data available" signal generates an interrupt which restarts the loop every 10ms. Most of the time, the body of the loop takes well under 1ms to execute. 

 

The device has a serial/USB (FT232R) port that runs at 9600 baud for the async serial part. (1.04ms per character). An earlier step of this program had the full serial running, the way it should. After a number of significant changes (including almost all of the top level "body" of the main loop), it suddenly did NOT work. I could see characters coming in, on my logic analyzer (at the correct logic level). All the UART settings appeared correct. New characters are serviced in an interrupt and all of the enables were on. Nary a twitch from ISR. I looked hither and yon, finding nothing. All the register settings seemed correct. There were enough changes that I really could not sort out which, if any, might be causing such a problem.

 

So, thought I, I'll send out a few characters to check the baud  rate that the UART is running at. Total garbage (here, you can reference the subject line). And, sending one character seem to result in 2-3 characters as seen by the terminal. I found, by trial and error, that I could successfully send a character before entering the main loop, and everything was perfect. But, if I added other characters inside the main loop, it all fell apart. 

 

It took a week of digging and trying (not full time, mind you) when I finally realized something. I had not done anything to guarantee that the previous character frame was complete before sending the next character. As soon as I added these "guard" tests, all was perfect, on the transmit side. Apparently, what was happening was that new characters were being written into the UDR before the old one was complete, thus trashing it. But, still zilch receive.

 

So, at this point, I was quite confident that there was nothing wrong with the UART or the interface between the UART and the FT232R. 

 

So, as with the transmit test, I went back and added an explicit receive test just before it drops into the main loop. I put in a while(1){} statement to prevent it from continuing into the loop. Wowie, there were the received characters!

 

Then, I began searching the main loop for anything that might effect async serial character reception. I found it. Guess what happens when it goes to sleep (before the character receive is complete)? Also, since it was sleeping most of the time, the odds of totally missing a character were quite high. The character is lost and the interrupt never occurs.

 

Now, the design of the program called for sleep to be skipped if USB is connected because it is powered by USB and there is no need for minimizing the power consumption. I had forgotten to add that test around the sleep block. As soon as that was added, everything behaved, nicely.

 

Thus, not all garbage characters are due to incorrect baud rate.

 

On the other hand, for newbies,  one can certainly assert that incorrect baud rate is probably the single most prevalent culprit. You need a bit of experience to tangle your web as much as I did.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Wed. Jul 11, 2018 - 11:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great advice!

Hence why Lee preaches to test the TXC flag and RXC flag

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Jul 11, 2018 - 11:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was not getting any RXC flags, probably because the character receives that were started never finished and because many were totally missed during sleep. That was the puzzle that started it all.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well based on your OP it looks like your deliberate and methodical troubleshooting resolved the issue at hand.

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It was certainly methodical. But, it took a bloody long time. Way too many false leads not included in the OP. Too many rabbit holes followed.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Thu. Jul 12, 2018 - 01:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Congratulations on your successful resolution of issues and thank you for your write-up of lessons learned to pass on.

ka7ehk wrote:
Now, the design of the program called for sleep to be skipped if USB is connected because it is powered by USB and there is no need for minimizing the power consumption.
USB suspend does have current limits.

USB suspend is active when a notebook PC sleeps.

Some USB UART have an impressively low current consumption during USB suspend; this leaves a significant amount of current for the MCU to do some work when USB suspend is active.

When USB suspend is deactivated then the MCU can return to complete functionality.

USB suspend can be a signal from the USB UART to the MCU for some USB UART.

ka7ehk wrote:
You need a bit of experience to tangle your web as much as I did.
enlightened ... thank you


USB in a NutShell - Chapter 2 - Hardware

Suspend Current

https://www.beyondlogic.org/usbnutshell/usb2.shtml#SuspendCurrent

http://www.ftdichip.com/Products/ICs/FT232R.htm 

Cypress Semiconductor

CY7C65213: USB-UART LP Bridge Controller

http://www.cypress.com/documentation/datasheets/cy7c65213-usb-uart-lp-bridge-controller

Cypress Semiconductor

Replacing FT232R with CY7C65213 USB-UART LP Bridge Controller - KBA85921 | Cypress Developer Community

https://community.cypress.com/docs/DOC-10995

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
not all garbage characters are due to incorrect baud rate.

Well, of course, all generalisations are dangerous!

 

cheeky

 

But, yes - this is exactly why my Tip #2 does say "almost".

 

Of course there are others - not checking that the UART is ready is probably Number Two in posts on forums.

 

Another would be data being inverted.

 

A common cause of one (or a few) junk characters is glitches caused at power-up.

 

Perhaps this thread should be made a "sticky" ... ?

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great job Jim, sometimes persistence is the key to winning! 

 

I have a similar story about a timer but will save for another day as I don't want to take away from your story above...

 

Take time out for a cold one!

 

 

Jim

edit: spelling

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Thu. Jul 12, 2018 - 04:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A quick note for gchapman. This really had nothing to do with USB. The system is a M328P and a FT232R USB-serial bridge. The micro was (incorrectly) sleeping while the USB stayed active. That was a huge part of the problem. The other part was that the non-sleeping time was less than the length of a character. As soon as I stopped it from sleeping when connected to USB, the problem disappeared.

 

The other half of it, with transmitted characters being garbled, was entirely of my own naive making. That happened when new characters were written to the UART data register before the previous character had been completely sent. It worked just fine when I had only one character to send, but as soon as others were added for more debugging detail, the whole thing fell apart. The proper empty-buffer test (which SHOULD have been used in the first place) solved this one.

 

The part to scream about is that it took several months (far less than full time) to sort all this out. It all could have been avoided by including a simple if() statement that was intended in the first place.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net