Xon/Xoff In Arduino?

I am working with a device that uses UART Xon/Xoff as default, and I'm not able to change it at the minute.

Reading around, it seems that Xon/Xoff might involve sending data until the device receiving it sends back an Xoff signal, meaning wait until Xon happens to continue sending data.

That's fine, but this device seems to require Xon/Xoff in the sending of the data, (tested in realterm, data does not arrive after the first 10 bytes sent if software flow control Xon/Xoff is not activated on Transmit). What does Xon/Xoff require in the transmission of data?

Is Xon/Xoff something the Arduino has in its Serial library?

Is that a full duplex communication?

Usually a receiver sends Xoff to stop incoming data and Xon when it's ready to receive again. Of course that Xon/Xoff is transmitted on the outgoing channel and should not go into the input buffer of the receiver.

Unfortunately the 8 bit Arduinos seem not to support any handshake, not by hardware (RTS/CTS) nor by software (Xon/Xoff).

CTRL-Q/CTRL-S - software flow control

XonXoff is software control, no additional hardware required. Generally is is used with full duplex communications. It was very common on mini computers years ago like the PDP series etc. Yes even on the PDP8. CtlS and CtlQ are the same thing but with different characters.

XON == DC1 == 0x11 == ctrl-Q
XOFF == DC3 == 0x13 == ctrl-S

Correct. Your problem with the Arduino (you don't mention which one) is that serial transmit is buffered and you can not immediately abort.

You will (to my knowledge) have to send one byte, flush the serial, check if the device has send a Xoff using Serial.read() and if not, send the next byte and flush and so on. If the device did send a Xoff, you will have to read the serial port till you find a Xon after which you can continue sending.

You may find this simple approach helpful:

https://www.stm32duino.com/viewtopic.php?p=10443

I'm not sure I have asked this clearly, let me try again.

Reading around, it seems that Xon/Xoff might involve sending data until the device receiving it sends back an Xoff signal, meaning wait until Xon happens to continue sending data. I get that now, and some of the answers have re-stated it.

However, there seems to be more than that. In RealTerm, if I turn on Xon/Xoff for Receive, then when The transmitting PC receives an Xoff signal (I can see that after the buffer is full - real term displays the received byte 17) and pauses then starts again when the Xon signal is received.

Transmitting with Xon/Xoff activated for Receive only will cause the receiving device to only accept 10 bytes. Transmitting with Xon/Xoff activated for Transmit allows me to send bytes until the buffer is full, and the device can receive 60 bytes. The Xon/Xoff when activated for Transmit seems to be doing something different than just stalling when it receives Xoff and continuing when it receives Xon. Any ideas what the something different is?

Bad implementation of the handshake protocol. RS-232 has been misinterpreted by several companies in various ways.

X-on and X-off were ONLY, EVER, used for full duplex communications. Why do we not have an answer to the question? What is the other device?
An Arduino CANNOT operate in full duplex communication, so there is no reason to support X-on and X-off.

Sorry, I don't understand you. I have no meaningful interpretation of the behavior of that strange device.

Each UART supports full duplex communication, but nowadays not normally any handshake. Implementation of software handshake in the Serial driver should not be too hard for an experienced coder.

The other device is an FT260 USB HID to UART/I2C, and unfortunately I am stuck with its default settings. 19200 8 N 1 - Xon/Xoff.

What is the difference in Using Software Flow Control (Xon/Xoff) through Receiving and Transmitting in RealTerm?

I have tested Transmitting to the device in RealTerm, and if I do not have Transmit ticked in the Software Flow Control box, then the device does not receive more than 10 bytes. This is apart from the fact that the Receive flow control kicks in when too many bytes are sent to the FT260 at once, which causes an Xoff to be sent to PC which waits until an Xon is received.

I am looking to see if anyone knows what ticking this Transmit box in the Software Flow Control settings, and how I can use it in an Arduino program.

There are or were external modules/shields that would allow you full control of the USART (universal asynchronous receiver-transmitter) and operate it in full duplex. I do not remember the name or number but the ones I had were about 1" square and worked OK. You could look for them from your favorite supplier.

Why do you think that an external module is required? What's missing from Arduino UARTS for your intended solution?

But, note it uses 2 channels! You can do the same if your Arduino has TWO separate channels(UARTS). Read a byte, send a byte. IF the read byte is XOFF, don't send a byte. IF the read byte is XON, continue reading and sending a byte.

NOTE! if you are build a USB connected device, the USB, by definition is NOT a full duplex communication protocol.

They can run in full duplex and you can control how much is in a Que if you define one.

A UART always runs in full duplex mode unless you block it.
The receive and transmit queues are implemented in Serial. For software handshake you only have to filter incoming Xon/Xoff and control (start/stop) the transmitter accordingly instead of queuing these control codes. Also Xoff/Xon should be sent when the input queue fills up and empties again.

The link I provided above shows this example code:

#include <Arduino.h>

enum State {
	XOff = 0,
	XOn
};

State state;

void setup(){
	state = State::XOff;
	pinMode(PA0, INPUT_ANALOG);
};

void loop() {
	// this part is the command processor
	if(Serial.available()) {
		int c = Serial.read();
		switch(c) {
			case 17: // Ctrl Q
				state = State::XOn;
				break;
			case 19: // Ctrl S
				state = State::XOff;
				break;
		}

	}
	if (state == State::XOn) {
		Serial.println(analogRead(PA0));
	}
}

With other words:

  • The receiving device with limited input buffer sends "XOff" to the sender to stop further transmission.
  • If the input buffer is (sufficiently) free, the receiving device sends "XOn" to resume the transmission process.

It does not make sense if the sender would do it as there is no information about the buffer of the other side...

And in the example you can see that the transmitting side reads inputs from the receiver:

  • It stops transmission if XOff was received.
  • It restarts transmission after receiving a XOn.

If your device reacts not like this it is quite likely that you have a different issue ...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.