| ||
|
Shopping Cart
|
| Home | MP3 Player | 8051 Tools | All Projects | PJRC Store | Site Map |
|
You are here:
Teensy
| Search PJRC |
|
Using USB Serial CommunicationTeensyduino provides a Serial object which is compatible with the Serial object on standard Arduino boards. Usually Serial is used to print information to the Arduino IDE Serial Monitor.void setup() { Serial.begin(9600); // USB is always 12 Mbit/sec } void loop() { Serial.println("Hello World..."); delay(1000); // do not print too fast! }Unlike a standard Arduino, the Teensy Serial object always communicates at 12 Mbit/sec USB speed. Many computes, especially older Macs, can not update the serial monitor window if there is no delay to limit the speed! In this example, "Hello World..." is printed once per second.
The Teensy does not actually become a serial device until your sketch is running, so you must select the serial port (Tools -> Serial Port menu) after your sketch begins. Standard Serial FunctionsAll of the standard Serial functions are supported.Serial.begin()Initialize the Serial object. The baud rate is ignored and communication always occurs at full USB speed.Serial.print() and Serial.println()Print a number or string. Serial.print() prints only the number or string, and Serial.println() prints it with a newline character.// Serial.print() can print many different types int number = 1234; Serial.println("string"); // string Serial.println('a'); // single character Serial.println(number); // number (base 10 if 16 or 32 bit) Serial.println(number, DEC); // number, base 10 (default) Serial.println(number, HEX); // number, base 16/hexidecimal Serial.println(number, OCT); // number, base 8/octal Serial.println(number, BIN); // number, base 2/binary Serial.println(number, BYTE); // number, as a single byte Serial.println(3.14); // number in floating point, 2 digitsOn a standard Arduino, this function waits while the data is transmitted. With Teensyduino, Serial.print() and Serial.println() typically return quickly when the message fits within the USB buffers. See Transmit Buffering below. Serial.write()Transmit a byte.Serial.available()Returns true if at least 1 byte is available, or false if nothing has been received.On a standard Arduino, Serial.available() tends to report individual bytes, whereas large blocks can become instantly available with Teensyduino. See Receive Buffering below for details. Serial.read()Read 1 byte (0 to 255), if available, or -1 if nothing available. Normally Serial.read() is used after Serial.available(). For example:if (Serial.available()) { incomingByte = Serial.read(); // will not be -1 // actually do something with incomingByte } Serial.flush()Discard any received data that has not been read.Teensy USB Serial ExtensionsTeensyduino provides extensions to the standard Arduino Serial object, so you can access USB-specific features.Serial.send_now()Transmit any buffered data as soon as possible. See Transmit Buffering below.Serial.dtr()Read the DTR signal state. By default, DTR is low when no software has the serial device open, and it goes high when a program opens the port. Some programs override this behavior, but for normal software you can use DTR to know when a program is using the serial port.void loop() { pinMode(6, OUTPUT); // LED to show if a program is using serial port digitalWrite(6, HIGH); // (active low signal, HIGH = LED off) while (!Serial.dtr()) ; // wait for user to start the serial monitor digitalWrite(6, LOW); delay(250); Serial.println("Hi there, new serial monitor session"); while (Serial.dtr()) { // wait for the user to quit the serial monitor Serial.print('.'); delay(500); } }On a standard Arduino, the DTR and RTS signals are present on pins of the FTDI chip, but they are not connected to anything. You can solder wires between I/O pins and the FTDI chip if you need these signals. Serial.rts()Read the RTS signal state. USB includes flow control automatically, so you do not need to read this bit to know if the PC is ready to receive your data. No matter how fast you transmit, USB always manages buffers so all data is deliveried reliably. However, you can cause excessive CPU usage by the receiving program is a GUI-based java application like the Arduino serial monitior!For programs that use RTS to signal some useful information, you can read it with this function. Serial.baud()Read the baud rate setting from the PC or Mac. Communication is always performed at full USB speed. The baud rate is useful if you intend to make a USB to serial bridge, where you need to know what speed the PC intends the serial communication to use.Serial.stopbits()Read the stop bits setting from the PC or Mac. USB never uses stop bits.Serial.paritytype()Read the parity type setting from the PC or Mac. USB uses CRC checking on all bulk mode data packets and automatically retransmits corrupted data, so parity bits are never used.Serial.numbits()Read the number of bits setting from the PC or Mac. USB always communicates 8 bit bytes.USB Buffering and Timing DetailsUsually the Serial object is used to transmit and receive data without worrying about the finer timing details. It "just works" in most cases. But sometimes communication timing details are important, particularly transmitting to the PC.Transmit BufferingOn a standard Arduino, when you transmit with Serial.print(), the bytes are transmitted slowly by the on-chip UART to a FTDI USB-serial converter chip. The UART buffers 2 bytes, so Serial.print() will return when all but the last 2 bytes have been sent to the FTDI converter chip, which in turn stores the bytes into its own USB buffer.On a Teensy, Serial.print() writes directly into the USB buffer. If your entire message fits within the buffer, Serial.print() returns to your sketch very quickly. Both Teensyduino and the FTDI chip hold a partially filled buffer in case you want to transmit more data. After a brief timeout, usually 8 or 16 ms on FTDI and 3 ms in Teensyduino, the partially filled buffer is scheduled to transmit on the USB. The FTDI chip can be made to immediately schedule a partially filled buffer by toggling any of the handshake lines (which are not connected on a standard Arduino board). It can also be configured (by the PC device driver) to schedule when an "event character" is received. Normally it is difficult to control when the FTDI chip schedules its partially filled transmit buffer. Teensyduino immediately schedules any partially filled buffer to transmit when the Serial.send_now() function is called. All USB bandwidth is managed by the host controller chip in your PC or Mac. When a full or partially filled buffer is ready to transmit, it actual transmission occurs when the host controller allows. Usually this host controller chip requests any scheduled transfers 1000 times per second, so typically actual transmission occurs within 0 to 1 ms after the buffer is scheduled to transmit. If other devices are using a lot of USB bandwidth, priority is given to "interrupt" (keyboard, mouse, etc) and "isychronous" (video, audio, etc) type transfers. When the host controller receives the data, the operating system then schedules the receiving program to run. On Linux, serial ports opened with the "low latency" option are awakened quickly, others usually wait until a normal "tick" to run. Windows and MacOS likely add process scheduling delays. Complex runtime environments (eg, Java) can also add substantial delay. Receive BufferingWhen the PC transmits, usually the host controller will send at least the first USB packet within the next 1ms. Both Teensyduino and the FTDI chip receive a full USB packet (and verify its CRC check). The FTDI chip then sends the data to a standard Arduino via slow serial. A sketch repetitively calling Serial.available() and Serial.read() will tend to see each byte, then many calls to Serial.availble() will return false until the next byte arrives via the serial communication.void loop() { // On a serial-based Arduino, bytes tend to arrive one at a time // so this while loop usually only processes 1 byte before allowing // the rest of the loop function to do its work while (Serial.available()) { incomingByte = Serial.read(); // do something with incomingByte } // do other unrelated stuff time_sensitive_task1(); another_urgent_thing(); still_yet_even_more_stuff(); }On a Teensy, the entire buffer is received, so successive calls to Serial.available() will return true until all bytes are read. Sketches that do other work while receiving data might depend on this slow reception behavior, where successive calls to Serial.available() are very unlikely to return true. On a Teensy receiving large amounts of data, it may be necessary to add a variable to count the number of bytes processed and limit the delay before other important work must be done. void loop() { // On a Teensy, large groups of bytes tend to arrive all at once. // This bytecount prevents taking too much time processing them. unsigned char bytecount = 0; while (Serial.available() && bytecount < 10) { incomingByte = Serial.read(); // do something with incomingByte bytecount++; } // do other unrelated stuff time_sensitive_task1(); another_urgent_thing(); still_yet_even_more_stuff(); } |