Pages: [1]   Go Down
Author Topic: Teensyduino on Teensy 2.0 - UART Serial  (Read 957 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Since I cannot find an official Teensyduino board, I figured I might post here. Does anyone have experience with UART serial (the hardware serial - not the USB) on the teensy? I'm wondering if write() blocks instruction or uses a buffer. I'm also wondering what the max reliable baud rate is? They list some on their site, but I was wondering if anyone has experience with higher speeds?

Thanks!
« Last Edit: January 03, 2012, 12:41:14 pm by gcotten » Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 177
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Does anyone have experience with UART serial (the hardware serial - not the USB) on the teensy?

Yes.  It works well (just like the UART on the 328).  It's one of the features I really like on the Teensy.


Quote
I'm wondering if write() blocks instruction or uses a buffer.

Let's check the source code (my copy is several months old so things may have changed)...

Code:
void HardwareSerial::write(uint8_t c)
{
uint8_t i;

if (!(UCSR1B & (1<<TXEN1))) return;
if (tx_enable_pin < 255 && !transmitting) {
digitalWrite(tx_enable_pin, HIGH);
}
i = tx_buffer_head + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
while (tx_buffer_tail == i) ; // wait until space in buffer
tx_buffer[i] = c;
transmitting = 1;
tx_buffer_head = i;
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1) | (1<<UDRIE1);
}

Looks very "buffery" to me.


Quote
I'm also wondering what the max reliable baud rate is?

"Reliable"?  There's no way to answer that question.  It depends on: medium quality, medium length, receiver hardware, receiver and transmitter software.  And, you have not defined what "reliable" means in your application.


Quote
They list some on their site, but I was wondering if anyone has experience with higher speeds?

I have not had any problems at 115200.


If possible, you will have better results using baud rates that are "16 MHz compatible".  Go here...

http://www.wormfood.net/avrbaudcalc.php

Find the "16 Mhz" table.  Choose baud rates in green.  Or, use the equations in the datasheet to determine baud rates with zero error (250K is one such choice).
Logged

0
Offline Offline
God Member
*****
Karma: 24
Posts: 587
Always making something...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I recently did a project with another non-USB AVR chip sending debug data, and a Teensy receiving it and resending it to a PC.  The Teensy was also connected to the reset line and could do ISP reprogramming of that other AVR chip, as well as a few checks of various analog voltages.

I wanted the serial to run as fast as possible, but I didn't want to do a lot of work.  I did go to the trouble of reading to a 64 byte buffer, rather than 1-byte-at-a-time, but otherwise I just went with things as they are.  Here's the code.

Code:
void loop() {
        char buf[64];

        if (cpu_is_running) {
                int n = Uart.available();
                if (n > 0) {
                        if (n > sizeof(buf)) n = sizeof(buf);
                        Uart.readBytes(buf, n);
                        Serial.write((uint8_t *)buf, n);
                }
        }

With the code above, it turned the fastest reliable baud rate was 666667 bits/sec.

Code:
#define BAUDRATE 666667
//#define BAUDRATE 1000000  // Teensyduino can't keep up...
//#define BAUDRATE 2000000
//#define BAUDRATE 115200
HardwareSerial Uart = HardwareSerial();

It did work pretty well for short bursts of data at 1 Mbit/sec.  But if the other AVR chip sent sustained maximum rate data, ultimately it couldn't keep up.

If your program were structured in the common 1-byte-at-a-time approach, you'd incur more overhead, especially since each write to the PC would have the overhead of manipulating the USB buffers.  It very likely would not keep up at 666667 bps with so much more overhead.

Internally, readBytes() calls the read function for 1 byte at a time.  I may someday optimize readBytes and the underlying Stream class for block reads.  When/if that happens, the code above would very likely become able to reliably handle 1 Mbit/sec.

Of course, if your program is doing something different with the data, the actual reliable maximum data rate will depend heavily on what you're doing, and especially if you manage data in blocks or 1-byte-at-a-time.  But hopefully this 1 use case gives you at least some idea of the underlying capability to move at least 667 kbits/sec speed from the hardware serial port to the USB virtual serial port.


ps: another caveat is this does NOT apply to regular Arduino boards.  The HardwareSerial code in Teensyduino is heavily optimized.  Arduino's HardwareSerial code is much slower.
Logged

Pages: [1]   Go Up
Jump to: