Skip to content
Ytai Ben-Tsvi edited this page Jan 7, 2015 · 5 revisions

UART

Background

This section assumes you are familiar with the concepts of Digital I/O

Universal Asynchronous Reception and Transmission (UART) is a very common, simple and useful serial communication interface. It serves as a basis for many ubiquitous protocols such as RS-232 (used on COM ports of old computers), and MIDI. Its basis is a one-way communication channel, on which one end transmits and the other end receives on a single wire. The basic data units transferred are 8-bit bytes. Each byte is sent on the wire bit-by-bit, preceded by a start bit which is simply the bit '0' and followed by an optional parity bit (used for error correction, but commonly not used at all) and one or two stop bits (commonly only one), which are simply the bit '1'.

Thus, an 8-bit byte is represented by 10 to 12 bits on the wire, and the bytes get sent one after the other. When the line is idle, it is HIGH. The rate at which bits are sent is called baud rate. Common baud rates are 9600, 19200, 38400, 115200, etc. This is all there's to it in UART really. So when you connect to a UART-speaking device, you'll need to know the baud rate, the parity type (usually no parity) and the number of stop bits (usually one) it expects. You'll also need to know the voltage levels used to designate LOW and HIGH. Most often (but not always), you'll encounter either 3.3V or 5V UART devices. 3.3V is the easiest with IOIO as this is the "native" format for all the IOIO pins. For receiving or transmitting 5V signals, read here.

In order to establish two-way communications, two UART channels are used, which are not synchronized in any way. Just two independent one-way streams. Each end then has a TX (transmit) and an RX (receive) channel.

IOIO has 4 UART modules, each having a transmit channel and a receive channel. You can use either channel or both. The TX channel can be used on any peripheral output pin. These are the pins designated with "P" at the bottom of the board. The RX channel can be used on any peripheral input pin. These are also the pins marked as "P" and the pin marked as "Pi". Note that on the first revision of boards the letter "P" has unfortunately been omitted from some of the pins that support peripheral input and output. These are pins 34-40 and 45-48. You can see a complete list of pin functions in the table at the bottom of this page.

A common confusion when connecting two devices via UART is figuring out whether to connect TX <-> TX and RX <-> RX or TX <-> RX and RX <-> TX. Most commonly the latter (crossed) is correct, but sometimes the pins would be labeled in the opposite way. To remove all doubt, the pin assigned as TX by the IOIO is used for the IOIO as an output to transmit on and should be connected to the receive (input) pin of the other device. Connecting both output lines together can damage the IOIO and/or the other device. If you are unsure about the labeling conventions of the other device, check carefully before connecting. As a safety measure, a 220-1K Ohm resistor connected in series to the TX line of the IOIO would be harmless in case of a correct connection and would prevent damage in case of an incorrect connection.

Usage

Using the IOIO UART modules is done via the Uart interface. An instance of this interface corresponds to a single UART module on the board, as well as to the pins it uses for RX and/or TX. Uart instances are obtained by calling one of the overloads of IOIO.openUart(). The simplest form is:

Uart uart = ioio.openUart(rxPin, txPin, baud, parity, stopBits);

This opens a UART module transmitting through pin txPin, receiving through pin rxPin, with baud rate baud and the specified parity and stop bits settings. It is possible to pass IOIO.INVALID_PIN as either txPin or rxPin for creating a RX-only or TX-only UART. It is required that at the time of call, these pin are not being used for anything else, and that there is at least one free UART module. In order to open a the TX pin as open-drain or the RX pin in pull-up or pull-down mode, the other version of IOIO.openUart() should be used. See here for more details on digital pin modes.

Once an instance of Uart is obtained, sending and receiving data is done through the standard Java InputStream and OutputStream classes, obtained by:

InputStream in = uart.getInputStream();

and

OutputStream out = uart.getOutputStream();

A nice experiment for playing around with this API is to physically wire the RX pin to the TX pin (loopback). Since UART is completely symmetric, this will cause any data transmitted to be received back.

When you are done using the UART, call:

uart.close();

in order to return the pins to a "floating" state and possibly be able to re-open them in the same or in a different mode, as well as free the UART module. The Uart instance becomes useless after this call - it is illegal to do anything with it.