/* USB to Serial - Teensy becomes a USB to Serial converter
http://dorkbotpdx.org/blog/paul/teensy_as_benito_at_57600_baud
You must select Serial from the "Tools > USB Type" menu
This example code is in the public domain.
*/
// set this to the hardware serial port you wish to use
#define HWSERIAL Serial1
#define HWSERIAL1 Serial2
#define HWSERIAL2 Serial3
unsigned long baud[3] = {19200, 19200, 19200};
unsigned char prev_dtr[3] = {0, 0, 0};
const int reset_pin[3] = {4, 3, 4};
const int led_pin = 13; // 13 = Teensy 3.X & LC
// 11 = Teensy 2.0
// 6 = Teensy++ 2.0
void setup()
{
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
digitalWrite(reset_pin[0], HIGH);
pinMode(reset_pin[0], OUTPUT);
Serial.begin(baud[0]); // USB, communication to PC or Mac
HWSERIAL.begin(baud[0]); // communication to hardware serial
#if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL)
digitalWrite(reset_pin[1], HIGH);
pinMode(reset_pin[1], OUTPUT);
SerialUSB1.begin(baud[1]);
HWSERIAL1.begin(baud[1]);
#endif
#if defined(USB_TRIPLE_SERIAL)
digitalWrite(reset_pin[2], HIGH);
pinMode(reset_pin[2], OUTPUT);
SerialUSB2.begin(baud[2]);
HWSERIAL2.begin(baud[2]);
#endif
}
long led_on_time = 0;
#define BUFFER_SIZE 512
byte buffer[BUFFER_SIZE];
void loop()
{
// first do the simple stuff.
processUSBToSerial(0, &Serial, &HWSERIAL, Serial.dtr(), Serial.baud());
#if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL)
processUSBToSerial(1, &SerialUSB1, &HWSERIAL1, SerialUSB1.dtr(), SerialUSB1.baud());
#endif
#if defined(USB_TRIPLE_SERIAL)
processUSBToSerial(2, &SerialUSB2, &HWSERIAL2, SerialUSB2.dtr(), SerialUSB2.baud());
#endif
// if the LED has been left on without more activity, turn it off
if (millis() - led_on_time > 3) {
digitalWrite(led_pin, LOW);
}
}
//=========================================================================
// Process for one USB to Serial connection.
// Wish USB Serial classes derived from common class other than Stream.
//=========================================================================
void processUSBToSerial(uint8_t serial_index, Stream* usbStream, HardwareSerial *hwserial,
unsigned char dtr, unsigned long usb_baud)
{
int rd, wr, n;
// check if any data has arrived on the USB virtual serial port
rd = usbStream->available();
if (rd > 0) {
// check if the hardware serial port is ready to transmit
wr = hwserial->availableForWrite();
if (wr > 0) {
// compute how much data to move, the smallest
// of rd, wr and the buffer size
if (rd > wr) rd = wr;
if (rd > 80) rd = 80;
// read data from the USB port
n = usbStream->readBytes((char *)buffer, rd);
// write it to the hardware serial port
hwserial->write(buffer, n);
// turn on the LED to indicate activity
digitalWrite(led_pin, HIGH);
led_on_time = millis();
}
}
// check if any data has arrived on the hardware serial port
rd = hwserial->available();
if (rd > 0) {
// check if the USB virtual serial port is ready to transmit
wr = usbStream->availableForWrite();
if (wr > 0) {
// compute how much data to move, the smallest
// of rd, wr and the buffer size
if (rd > wr) rd = wr;
if (rd > 80) rd = 80;
// read data from the hardware serial port
n = hwserial->readBytes((char *)buffer, rd);
// write it to the USB port
usbStream->write(buffer, n);
// turn on the LED to indicate activity
digitalWrite(led_pin, HIGH);
led_on_time = millis();
}
}
// check if the USB virtual serial port has raised DTR
if (dtr && !prev_dtr[serial_index]) {
digitalWrite(reset_pin[serial_index], LOW);
delayMicroseconds(250);
digitalWrite(reset_pin[serial_index], HIGH);
}
prev_dtr[serial_index] = dtr;
// if the LED has been left on without more activity, turn it off
if (millis() - led_on_time > 3) {
digitalWrite(led_pin, LOW);
}
// check if the USB virtual serial wants a new baud rate
if (usb_baud != baud[serial_index]) {
baud[serial_index] = usb_baud;
if (usb_baud == 57600) {
// This ugly hack is necessary for talking
// to the arduino bootloader, which actually
// communicates at 58824 baud (+2.1% error).
// Teensyduino will configure the UART for
// the closest baud rate, which is 57143
// baud (-0.8% error). Serial communication
// can tolerate about 2.5% error, so the
// combined error is too large. Simply
// setting the baud rate to the same as
// arduino's actual baud rate works.
hwserial->begin(58824);
} else {
hwserial->begin(usb_baud);
}
}
}