# What is RTS and CTS flow control?

I recently ordered two Bluetooth dongles for my Arduinos so I can have them communicate over long range. The dongles that I ordered have pin labeled CTS-I and a pin labeled RTS-0. I did a little bit of googling and found that they have something to do with "flow control," what is that?

I have the Arduinos communicating properly without these pins in use. What are these two pins intended to be used for? Should I want to use them? How can I use them?

Flow control is a general term for a means by which an entity that wants to push information to another can avoid sending it faster than the recipient can accept. One of the earliest forms of flow control that still exists in common usage is commonly called xon/xoff; it was used in communication between teletypes, in situations where one teletype was using its paper-tape reader to send data to another teletype. Although a teletype printer could usually keep up with a paper tape reader (both operated at ten characters/second), that would be contingent upon things like an adequate supply of paper. An operator who noticed that it was necessary to replace the paper in a teletype which was receiving a transmission could type Control-S to send an XOFF character, which would ask the paper-tape reader at the other end to stop. After the paper was replaced, the operator could type Control-Q to restart the paper-tape reader. Those characters are still used to this day, although the far end of the connection will usually be a computer rather than a tape reader.

RTS/CTS protocol is a method of handshaking which uses one wire in each direction to allow each device to indicate to the other whether or not it is ready to receive data at any given moment. One device sends on RTS and listens on CTS; the other does the reverse. A device should drive its handshake-output wire low when it is ready to receive data, and high when it is not. A device that wishes to send data should not start sending any bytes while the handshake-input wire is low; if it sees the handshake wire go high, it should finish transmitting the current byte and then wait for the handshake wire to go low before transmitting any more.

Note that while devices should ideally never send more than a byte after their handshake input goes high (if the line goes high just as they start transmitting a character, they must allow that character to be transmitted completely), many PC serial ports do not comply with this even when handshaking is enabled. The serial ports allow software to detect the state of the incoming handshake wire, and expect software to decide when data should be enqueued for transmission. Unfortunately, the only way to achieve good performance with a serial port is to enqueue data for transmission slightly in advance of when it will actually be sent, and many PC serial ports will always transmit any queued-up data as fast as they can without regard for the handshake wires. Consequently, it's not uncommon for PC serial ports to send a dozen or so characters even after they've been asked to wait.

• Thanks for the detailed answer! If I understand your answer it seems to me that using both pins would be redundant because they are always opposite of each other, right? For my project I am only sending a single bit of data over my connection (it is either on or off), so I don't think I really need to implement flow control. But now I know what it is if I do more data-intensive projects in the future. – Sponge Bob Aug 15 '12 at 20:35
• @KeeganMcCarthy: If the two devices are X and Y, one pin (an output from X and input to Y) will indicate whether X is ready for data from Y; the other (an output from Yy and input to X) will indicate whether Y is ready for data from X. Generally one would use both pins, unless one could be certain that e.g. X would always be ready for anything Y might send, even though Y might not always be ready for data from X. – supercat Aug 15 '12 at 20:41
• That's interesting about the FIFO dump. Might mention which UARTs are affected. Is it a 16450/16550 thing? – JustJeff Aug 16 '12 at 1:00
• @JustJeff: The 16550 was that way, as were many of its successors and imitators. The 16450 had I think one character of buffering in addition to the transmit shifter, so it wouldn't transmit more than two characters after it was told to stop. – supercat Aug 16 '12 at 5:15

RTS = Request To Send. The sending device is telling the other end to get ready to receive, and to set its CTS line when ready.

CTS = Clear To Send. The receiving end is ready ("all clear") and telling the far end to start sending the characters.

Long ago, half-duplex connections were common. These were one-way-at-a-time connections, and these signals were used to "turn the line around" so you didn't try to send when something was being sent to you.

Hardware handshaking, used improperly, was a classic "computer gets stuck" problem, and was so much trouble that the majority of implementers simply gave up trying to use this handshake method. That's why you were successful.

If characters continue to be sent after the far end says to stop, this may be due to the "FIFO" (First-In First-Out) in the device. This can store (buffer) several characters to be sent, so the computer doesn't have to stop and check after each character. But, as stated, it's sometimes hard to get it to stop! Hence the creation of receive buffers...

• I don't think they were taking turns driving a single channel, and it isn't even really about half-duplex. It was more a matter of the underpowered machines of the day not having enough buffer space to absorb a bunch of data. For example, a printer with a serial interface and an 8-bit micro with 1K or less RAM just wouldn't be able to keep up, even at the low baud rates of the day, so the idea was to tell the sending end to hold off. – JustJeff Aug 16 '12 at 0:57
• There are lots of good stories about serial I/O, and I lived quite a few of them. But the truth of the matter is that it was all designed around modems, and the rest followed from that. I refrained from providing a full history lesson :) – gbarry Aug 16 '12 at 15:03