Sending many bytes via UART - ATmega328

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

Hi guys,

I'm trying to send many data bytes at once via UART to the PC using Peter Fleurys UART Library.
The TX buffer size is about 32 Byte, but I need to transfer much more,

so I tried to check, if the TX buffer is empty and then send the next byte.

As proposed in some threads here, I used

while ( !( UCSR0A & (1<<UDRE0)) );

but that doesn't seem to work. This line freezes everything.

Can anybody please explain what's happening and how get it work?

for (uint8_t i = 1; i< 200; i++ )
{
    while ( !( UCSR0A & (1<<UDRE0)) );// Wait until buffer is empty
    uart_putc(i);
}

Many thanks!
BEXX

 
This topic has a solution.
Last Edited: Thu. Aug 30, 2018 - 03:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The library handles its own ring buffer.  No need to check the hardware buffer.

 

for (uint8_t i = 1; i< 200; i++ )
{
    uart_putc(i);
}

Have you not looked at the documentation?:

http://homepage.hispeed.ch/peterfleury/doxygen/avr-gcc-libraries/group__pfleury__uart.html

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

...you are right!

It works quite fine using it separately ...now I'm looking for something else being wrong with my code ;-)

 

Thanks!

BEXX

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

I've been just doing one more test.

Using it at the beginning of the code it works fine as mentioned before but using it somewhere in the middle of the code, nothing is working anymore.

But using it with only 10 byte, it is working elsewhere in the code fine also.

 

for (uint8_t i = 0; i< 10; i++ )
{
	uart_putc(i);
}	

Any idea what might have been changed to get this behaviour or what I have to look for to get it working?

 

 

 
Last Edited: Wed. Aug 29, 2018 - 06:17 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where exactly is "somewhere in the middle of the code"? Inside of an ISR by any chance?

Stefan Ernst

Last Edited: Wed. Aug 29, 2018 - 06:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No ISR. 

I placed it for testing in different 'normal' functions and the behaviour is always the same.

If it has more than 32 Byte for sending, it crashes...

... I checked it again: 32 bytes does not work also, it is only 31 byte sending in line working.

I then tried sending always 31 byte in a loop with a delay of 1000ms. This either doesn't work.

 

I'm totally confused.

 

(I'm using AtmelStudio 7)

 

 
Last Edited: Wed. Aug 29, 2018 - 06:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Please post a small complete program that demos the problem!

 

Jim

 

 

 

 

 

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

BEXX wrote:
The TX buffer size is about 32 Byte

What do you mean by about 32 bytes?    PF doc says: Size of the circular transmit buffer, must be power of 2,  same for the RX buffer too.

so if it is not exactly 32, or 16 or 64.....    it will not work as expected, what value do you have for UART_TX_BUFFER_SIZE

 

Jim

 

 

 

 

 

Last Edited: Wed. Aug 29, 2018 - 06:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim,

the UART_TX_BUFFER_SIZE is defined 32.

I didn't change the library.

The complete code is quite large, so I will try to separate a working part tomorrow.

 

Thanks!

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

You could increase the size of the TX buffer to 64 (or 128 if allowed in PF's library code). 

 

And increase the baud rate to 115200.  Your PC will have a bigger input buffer and can handle the incoming serial bytes much faster than the AVR can output them at 115200 baud.

 

Or, set up the timer to interrupt at an interval that equal to (or a tiny little longer) than the interval needed to send 32 bytes through the UART (about 2.7 milliSeconds at 115Kbaud).

At every timer interrupt, load the UART TX buffer with another 32 bytes.  Keep track of the number of bytes sent until you've sent them all, and then turn off the timer interrupt.

 

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

Now the problem is solved! :-)

 

I 've been using an ISR from a different library the wrong way and this was crashing the UART commands....

 

Many thanks to all!

BEXX

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

BEXX wrote:
Now the problem is solved!

Excellent! 

 

Now please see Tip #5

 

EDIT

 

Oh, you have marked a solution (post #2) - but then you said that was not the solution!

 

(Tip #5 does show how you can change which post is marked)

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...
Last Edited: Thu. Aug 30, 2018 - 03:02 PM