I have a project that uses I2C to collect data from four Nanos into one Mega. The buss speed has been increased to it's max, 888,888(TWBR=1) but is still too slow for my application, 4D sonar. The four Nanos and one Mega have been replaced with three Teensy 3.2 boards. Two of the Teensies will collect the same data as four of the Nanos using dual synced ADCs. The other Teensy will have the same task as the Mega, collection and transmission to shore. Instead of using I2C, I wanted to try hardware serial and find it's maximum speed, 4.5Mbps. Here are the details.
Connect two Teensy 3.2 boards with the following chart.
Receiver Gnd <--> Sender Gnd
Receiver TX1 --> 1K resistor --> Sender RX1 // Not really needed for this test but more later
Receiver RX1 <-- 1K resistor <-- Sender TX1
Each Teensy will be powered by their own USB cable
Open Arduino IDE using desktop shortcut, 1.65-rc5
Connect sender board USB to PC
Select the comport displayed in tools
Load sender sketch shown below
Upload
Open serial monitor
Note that baud value is about twice that expected
This will be discussed below
Open another Arduino IDE using desktop shortcut, 1.65-rc5
Connect receiver board USB to PC
Select the comport displayed in tools, not the previous
Load receiver sketch shown below
Upload
Open serial monitor
Note that baud value is about that expected
This will be discussed below
Sender sketch ****
// Teensy 3.2 hardware serial port speed test sender
#define SERIAL_PORT Serial1 // Use ports 1, 2, or 3
#define SERIAL_RATE 4500000 // Max speed, 1/16 of CPU clocck
#define SERIAL_DELAY 1250 // Takes this long for Serial.begin() to respond
#define ARRAY_SIZE 100 // Use a convenient number
#define LED_PIN 13 // Built-in LED
// Global variables
uint8_t bytebuffer[ARRAY_SIZE]; // A byte data array
uint32_t startTime, stopTime; // For CPU clock values
void setup()
{
Serial.begin( 115200 ); // Monitor port
startTime = millis(); // Present CPU clock
while( !Serial && ( millis() - startTime ) < SERIAL_DELAY ) { yield(); } // Ready or timeout
SERIAL_PORT.begin( SERIAL_RATE ); // Hardware test port
startTime = micros(); // Present CPU clock
while( !SERIAL_PORT && ( micros() - startTime ) < SERIAL_DELAY ) { yield(); } // Ready or timeout
// Load an array with phony data for transmission speed test
for( uint8_t i = 0; i < ARRAY_SIZE; i++ )
bytebuffer[i] = i;
pinMode( LED_PIN, OUTPUT );
digitalWrite( LED_PIN, HIGH ); // Show that sketch made it this far
Serial.println( "End setup()" );
}
void loop()
{
uint8_t written; // Bytes written to hardware serial port
uint32_t elapsed; // Write time
startTime = micros(); // When write started
written = SERIAL_PORT.write( bytebuffer, ARRAY_SIZE ); // Write the buffer
stopTime = micros(); // When write finished ????
elapsed = stopTime - startTime; // Write time ????
// Show the results
Serial.print( written );
Serial.print( " bytes written in " );
Serial.print( elapsed );
Serial.print( " usec. Baud value = " );
Serial.print( ARRAY_SIZE * 10000 / elapsed );
Serial.println( " Kbps" );
delay( 1000 ); // Wait long enough to read monitor screen
}
Receiver sketch ****
// Teensy 3.2 hardware serial port speed test receiver
#define SERIAL_PORT Serial1 // Use ports 1, 2, or 3
#define SERIAL_RATE 4500000 // Max speed, 1/16 of CPU clocck
#define SERIAL_DELAY 1250 // Takes this long for Serial.begin() to respond
#define ARRAY_SIZE 100 // Use a convenient number
#define LED_PIN 13 // Built-in LED
// Global variables
uint8_t bytebuffer[ARRAY_SIZE]; // A byte data array
uint32_t startTime, stopTime; // For CPU clock values
void setup()
{
Serial.begin( 115200 ); // Monitor port
startTime = millis(); // Present CPU clock
while( !Serial && ( millis() - startTime ) < SERIAL_DELAY ) { yield(); } // Ready or timeout
SERIAL_PORT.begin( SERIAL_RATE ); // Hardware test port
startTime = micros(); // Present CPU clock
while( !SERIAL_PORT && ( micros() - startTime ) < SERIAL_DELAY ) { yield(); } // Ready or timeout
pinMode( 13, OUTPUT );
digitalWrite( 13, HIGH );
Serial.println( "End setup()" );
}
void loop()
{
uint8_t bbread; // Bytes read from hardware serial port
uint32_t elapsed; // Read time
if( SERIAL_PORT.available() > 0 )
{
startTime = micros(); // Read time start
bbread = SERIAL_PORT.readBytes( bytebuffer, ARRAY_SIZE );
stopTime = micros(); // When read finished ????
elapsed = stopTime - startTime; // Read time ????
// Show the results
Serial.print( bbread );
Serial.print( " bytes read in " );
Serial.print( elapsed );
Serial.print( " usec. Baud value = " );
Serial.print( ARRAY_SIZE * 10000 / elapsed );
Serial.println( " Kbps" );
}
}
Here is the screenshot of both serial monitor windows running. The receiver is on the left and sender on the right. Notice on the right that the sender appears to be running at about twice the value expected while the receiver is about right. This supposed discrepancy occurs at all baud values. Apparently, the sender is running as a background task even though the yield() function is not evoked but was seen during the compile. The stoptime statement is reached before the TX buffer is empty. The receiver does not have this same problem so the computed value is about right. I also tested Serial2 and Serial3 and got the same sender results. I believe that Serial1 has a 128 byte dedicated buffer so my application will use that value for data packet size and not the 100 used in this test.
I hope this info is helpful for those wanting to use Teensy 3.2 hardware serial at it's maximum speed.

