Sensors, interfaces and bus systems (SENIN, BUSSY)

TIA-232 (wiki)

last updated: 03/12/19


Song of this chapter: Gordon Lightfood > Summertime Dream > Protocol

We will try in this chapter to understand one protocol in depth. This will give us a basic knowledge that we can transfer to other protocols.

Sometimes a little history helps to better understand why things are what they are.

S.F.B. Morse made a first practical fully serial binary system with his Morse Code (first only uppercase letters). Morse's first system had a needle contacting a rotating drum of paper that made a continuous mark. With an electromagnet it was possible to lift the needle away from the paper creating a space. Telegraph operators noticed that the sound the needle made when scratching the paper was enough to get the message ans so the drum was replaced by a speaker. The terms MARK and SPACE are still used in the RS-232 standard.

The Recommended Standard 232 (RS-232) was originally introduced in 1960 as telecommunication standard. The standard was needed to connect electromechanical teletypewriters (or dumb computer terminals), called data terminal equipment (DTE) to a data communication equipment (DCE, also data circuit-terminating equipment) like a modem. The modulator-demodulator (modem) was necessary to transmit digital signals wich need a huge bandwidth (see Fourier in ELEFU) over the telephone line witch had only 3.4 kHz of bandwidth. The simplest method is a frequency-shift keying FSK modulation, where we use 2 sine tones (e.g. 1 kHz for low and 2 kHz for high) to represent the two binary states.


At this time (1961) over sixty different ways of representing characters were used, and machines from different manufacturers could not communicate with one another. An IBM engineer (Bob Bemer) contacted the American National Standards Institute (ANSI) to develop a single code for computer communication. the American Standard Code for Information Interchange ASCII was released to serve as a common language among computers. It consists of 32 control characters like linefeed (LF, 0x0A) or carriage return (CR, 0x0D) to control the teletypewriter or terminal) and 96 characters—letters, numbers, or punctuation marks. With the limits of seven-bit hardware from that time ASCII represents each of the 128 characters with a numeric value.

When computer terminals began to be used, they often had to be interchangeable with teletypewriters, and so supported RS-232. Later personal computers got an RS-232-compatible port for serial communications and used the standard for mice and keyboards. After 2000 USB took over. USB to serial adapters and cables are used today to connect serial devices to a computer. RS-232 is because of its simplicity still used widely on microcontroller, but also in networking equipment, industrial machines, and scientific instruments where a point-to-point, low-speed and wired data connection is adequate.


Signals and connectors

Data and control signals

Commonly used RS-232 signals and pin assignments for DB-25 and DB-9 connectors:

DB-9 DB-25 Signal Name Purpose line DTE↔DCD) Active low
1 8 DCD Data Carrier Detect DCE is receiving a carrier on the line message yes
2 3 RxD Received Data Carries data from DTE to DCE data
3 2 TxD Transmitted Data Carries data from DTE to DCE data
4 20 DTR Data Terminal Ready DTE is ready to receive, initiate, or continue a call. control yes
5 7 GND Ground Signalground ground
6 6 DSR Data Set Ready DCE is ready to receive and send data message yes
7 4 RTS Request To Send DTE requests the DCE prepare to transmit data control yes
8 5 CTS Clear To Send DCE is ready to accept data from the DTE message yes
9 22 RI Ring Indicator message yes

All the signals are named from the standpoint of the DTE. We get two data lines, two control lines (DTE to DCE) and 4 message lines (DCE to DTE).

Connectors and cables

RS-232 connectors

The first computer and modem used the D-subminiature 25-pin connector recommended by the first revisions of the standard. Later the DB-25M connector (no more used today) was replaced with the smaller DE-9M connector (sometimes mistakenly called DB-9).

For computer the male connector was used (DB-25 female was the parallel port) and for the modem the female connector. So the straight connection cable from DTE to DCE uses a female connector (DTE (PC) side) and a male connector on the DCE side.

RS-232 cable straight

Null modem cable

Today as modems are seldom used with TIA-232 all practically all our devices are computer or microcontroller (e.g. in sensors). So TIA-232 connects two DTE! and the sender must be connected to the receiver and vis-versa meaning the cables must be crossed!

If two DTE are connected together the lines must be crossed! Such cables are named null modem cable and have two female connectors.

RS-232 null modem cable

Two null-modem cables:

null modem cable

The simplest null modem cable (and most used today) has only three lines:

RS-232 null modem cable 3 lines

Hardware handshake

To better understand the control and message lines, let's look at a standard hardware handshake used between DTE and DCE (part of the protocol of TIA-232). This handshake was necessary because the modem usually was slow and could not manage the fast data stream, so the handshake helped to control the data stream and avoid a buffer overflow. As seen, all the signals are named from the standpoint of the DTE.

Here a possible time diagram for a handshake (TTL side). The control lines are active low!

RS-232 hardware handshake

Programming a chip with Arduino

Today if control or message lines are used, it is normally a proprietary use and not the use meant by the standard. A good example is the Arduino platform. TIA-232 (through an USB-Serial converter chip realised with an ATMega16u2) is used to program e.g. the controller (ATmega328p) on the Arduino Uno (R3) board.

When the microcontroller gets reset, the bootloader checks to see if there is a new program waiting to be installed (by checking the serial data line). If a new program is ready, the bootloader overwrites the existing program with the program and hands control over to it. If no program is waiting, the bootloader does nothing and allows the serial connection to run as normal.

Uploading a sketch is possible without having to physically press the reset button. The Arduino software automatically resets the board before starting the upload. This is done with the help of the DTR line. It is connect through a capacitor to RESET.

"Just do it" TIA1:

With this knowledge and a corresponding bootloader it is easy to "Arduinoize" other microcontroller like e.g. an ATmega8, ATmega32 ot ATmega644p (look here).

Arduino also uses DTR and RTS to program ESP8266 and ESP32 chips. The needed circuit is already integrated on most Boards. To program a bare chip you need an ESP programmer).

Software handshake

If no hardware handshake is possible a software handshake can be used to control the data flow. The two commonly used methods for TIA-232 are XON/XOFF and EXT/ACK. Software handshake is seldom used today, but the possibility should be known.


With two ASCII control codes XON and XOFF (X for transmitter or transmission) the data flow can be controlled by switching the transmission on or off, respectively. If the input buffer of the receiver starts to become full the data is stopped with the XOFF character. When enough space appears in the buffer XONis sent to resume the data flow.

Mostly the ASCII codes DC1 (0x11) for XON and DC3 (0x13) for XOFF are used.

RS-232 software handshake xon xoff


A second method uses the ASCII codes End of TeXt ETX (0x03) and ACKnowledgment ACK (0x06). With this half duplex method the data is separated into blocks (often 128 byte, depending on the buffer capacity) and after each block "end of text" will be sent to show the end of this block of text.

If the data is accepted by the receiver and there is sufficient space in the input buffer an acknowledgement control code is sent. After this the next data block is sent.

The receiver also shows with the DTR line that he is ready.

RS-232 software handshake ext act

Disadvantages of a software handshake

We need more extra characters. This makes the communication less effective. To send binary data is not possible without recoding because control codes are used (not all 256 characters are available).

Voltage levels

With a TTL voltage of 5 V or even only 3.3 V from ESP microcontroller it is, because of the surrounding noise and voltage drop due to losses, difficult to cover long distances with a serial signal. So TIA-232 specifies other voltage levels:

RS-232 voltage levels

The voltages lie between -3 V and -15 V and between 3 V and 15 V, so avoiding ground. This makes it possible to detect if a connector is not plugged in or a cable is broken. Both data lines and control or message lines are inverted to the microcontroller signal (making data lines active low (negative logic)).

In the following picture we see a signal on the microcontroller side (blue) and the same signal on TIA-232 (red). 2 character of 8 bit (no parity, one stop bit (8N1)) are sent.

RS232 signal

To create the TIA-232 signal, extra ICs with the marking 232 (e.g. MAX232) were developed. They have a circuit called charge pump or DC-DC converter, working with capacitors, to get higher voltages from 5 or 3.3 and to get the negative voltages. The signals are amplified with inverting amplifier. Here a circuit with the bigger MAX238 that allows also to use control or message lines:

MAX 238

A breakout board and an Arduino shield with MAX232:

max 232

Serial to USB

Today computers have seldom an external TIA-232 interface (even if it's available on most motherboards). So USB to TIA-232 adapters are used (left picture). We find them as breakout boards or cables often with only TxD and RxD, but they also exist with control lines.

If we work with microcontroller or single-board computers (e.g. Raspberry Pi) only serial and not full TIA-232 is needed. So cables with TTL signals (5 V) or with 3.3 V signals can be bought (right picture).

There exist different chips, the most known are the chips from FTDI (best compatibility, e.g. FT232R), Profilic (e.g. PL2303) or WCH.cn (e.g CH340). In Linux the drivers are already integrated. In Windows or macOS they must be installed.

usb 2 tia232 usb 2 TTL

Bit rates and baud rates

Baud is the unit for the symbol rate (modulation rate) in symbols or better pulses (changes of the signal) per second. The symbol rate is called baud rate and is only one of the components that determine the speed of communication over a data channel. As it is possible to send more than one bit with one signal change, the bit rate (gross bit rate) in bits per second is normally not equivalent to the baud rate. Only in binary systems with only two symbols the baud rate and the bit rate are equivalent.

It is better to use only the bit rate to avoid confusion and wrong designations.

Bit rates used for TIA-232 are: 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 56000, 57600, 76800, 115200, 128000, 230400, 256000, 460800 bit/s.

Today the following bit rates are mostly used (especially the bold ones):

speed in bit/s data rate with 8N1
1200 120 byte/s
4800 480 byte/s
9600 960 byte/s
19200 1.875 kibibyte/s
38400 3.74 kibibyte/s
115200 11.25 kibibyte/s

The bit rate of hardware serial is derived by binary dividers from the clock of the microcontroller. Arduino AVR chips often use a crystal of 16 MHz. For certain bit rates the error of the rate gets above 1%. This can be seen in the data sheet, or on this page. So to get a good connection it is best to avoid 57600 and 115200 bit/s on Arduino and use 38400 bit/s instead (this does not count for the serial monitor which is emulated over USB).

"Just do it" TIA2:

Cable length

The possible cable length depends on the used voltage, the electromagnetic shielding of the cable and the capacitance of the cable (the lesser the better). A CAT7 network cable gives a bigger range than a CAT5 network cable. Here a table with RS232 cable length according to Texas Instruments (source wikipedia), to give an indication:

bit rate (bit/s) max. length
2400 900 m
4800 300 m
9600 152 m
19200 15 m
57600 5 m
115200 <2 m

By halving the maximum communication speed, the allowed cable length increases a factor ten!

As the cables today are much better the ranges increase. The cables in the standard had a capacitance of about 170pF/m. CAT5 cables have about 57pF/m. This increases the length of the cable min. by a factor 3.

Serial data format

We have seen in the previous chapter that in a serial transmission the data is transferred bit by bit from the sender Tx to the receiver Rx over one data line. With the help of shift register the parallel data is converted to a serial stream. In asynchronous serial communication the sender and receiver have no common clock, so we need synchronisation information contained in the data stream. This is done in TIA-232 with a start bit at the beginning and stop information at the end of the stream.

With TIA-232, we get a on state known as mark and an off state named space. When the line is idle, it is kept in the mark state.

Data bits are sent with a predefined bit frequency (bit rate), that both the sender and receiver must know. After the first bit is received, the receiver calculates . It will check the line voltage levels at those moments.

Start bit

As there is no clock information, the receiver needs to resynchronise with the help of the start bit (signal going from mark to space, falling edge). After the received falling edge of the signal the receiver samples the line with a higher clock than the bit rate and tries to detect the center of the start bit to know at which moments the other data bits will be received.

start bit

Data bits (5,6,7,8)

The first communication over serial worked with 5 or 6 bit in teletype era. To get 128 characters and control codes for ASCII, 7 bits and later 8 bits (256 character) were used. So it is possible to choose the number of data bits. Today normally 8 bit are used. Naturally sender and receiver must use the same amount of bits. The least significant bit is sent first. This is called little-endian (bit endianness).

Parity bit (E,O,N)

For simple error detecting, an extra bit was added to the data byte automatically by hardware. This parity bit can be even (E), odd or none. With even parity, for the whole data byte, the bits whose value is 1 are counted. If that count is odd, the parity bit is set to 1, making the total count of 1s in total (including the parity bit) an even number. Otherwise the parity bit is set to 0 to maintain the even number. In the case of odd parity, the coding is reversed.

Today the parity bit is very seldom used.

Stop bits (1, 1.5, 2)

The stop bit has mark value. With slow modems, 1 stop bit was sometimes not enough and so it was possible to send 1.5 or 2 stop bits, no more used today. As the receiver knows the bit rate, a missing stop bit is showing a synchronization failure (framing error) and the receiver can try to resynchronize on new incoming bits.

The data format and the bit rate must be the same for the sender and the receiver! Today mostly 8 data bit, no parity and 1 stop bit 8N1 is used.

Examples of serial data units

start bit

"Just do it" TIA3:

Serial on Arduino

For information about serial on Arduino look at the Arduino reference here or at Paul J. Stoffregens homepage here. Paul rewrote and improved parts of the Arduino libraries to be used with the Teensy boards.

On microcontroller we can use a software emulated serial communication (a pin is switched on and off by a library (e.g. softserial on Arduino)), or use an integrated UART or USART for hardware serial. The UART (Universal Asynchronous Receiver-Transmitter) is a hardware part in the microcontroller that handles the asynchronous serial communication. The data format and transmission speeds are configurable through registers. Up to six UART or USART are commonly integrated in newer microcontroller chips. The USART (Universal Synchronous and Asynchronous Receiver-Transmitter) also supports synchronous operation.

If possible we always use hardware serial because it doesn't disturb our timing of the program and the data stream timing is much more accurate. Hardware serial mostly works with interrupts, so interrupting the main program only very shortly. They use a buffer to store the incoming data.

To use hardware serial in Arduino the following line suffices:


Serial is the serial port object. If more ports are available (Teensy, ESP8266, ESP32) they are called Serial1, Serial2 etc.. The parameter is the bit rate. The default data format is 8N1 (8 data bits, no parity, one stop bit). This can be changed with an optional second parameter.

Often Serial is used for the Arduino terminal monitor. So if a real hardware serial port is needed it is best to choose a chip with a second serial port.

The commands to send data are Serial.print() and Serial.write().

Serial.write(value) sends the bit pattern of a one-byte value as is (binary data). Serial.write(string) sends the bit patterns of the characters of the string one by one. Serial.write(buffer, length) can be used to send the bytes of an array. Length defines how many bytes of the array will be sent. Serial.write() returns the number of bytes written.

Hint: If the transmit buffer is full, Serial.write() will not return (block) until there is enough space in the buffer. To avoid blocking is possible to check if there is enough free space in the transmit buffer with the method availableForWrite(). To clear the buffer from old data we can use Serial.flush().

Serial.print(value,format) or Serial.println(value,format) uses Serial.write() but converts the data first in a human-readable ASCII text. Characters and strings are not changed but e.g. numbers are printed using an ASCII character for each digit. With the second parameter format the base for the conversion can be specified. Allowed are BIN, OCT,HEX and DEC. For floating point numbers, format specifies the number of decimal places to use. Serial.print() also returns the number of bytes written. As already seen flash-memory based strings can be send by wrapping them with `F()``.

With Serial.read() we get serial data. The method returns the first byte of incoming serial data available as integer (-1 if no data is available). Normally it is used in combination with Serial.available(). Other methods are Serial.readBytes(),Serial.readBytesUntil(), Serial.readString() and Serial.readStringUntil().

Here a simple program to send and read a two bytes:

    // TIA_232_simple loopback with Teensy 2.0

    byte incoming_byte;

    void setup() {
      Serial.begin(115200);              // initialize serial for terminal
      delay(500);                        // mega32u4 needs a little time
      Serial1.begin(115200);             // initialize hardware serial
      Serial.println("Test begins");

    void loop() {
      Serial1.write("Gu");               // write two bytes
      while (Serial1.available() > 0) {  // if any serial available, read it
        incoming_byte = Serial1.read();  // and write it to the terminal
        Serial.write(incoming_byte);     // alt: Serial.write(Serial1.read());
"Just do it" TIA4:
"Just do it" TIA5:
"Just do it" TIA6
"Just do it" TIA7

Interesting links: