6

Does there exist (any user developed etc.) version of the Hardware UART serial library that has support for RTS/CTS based flow control? More interested in the Tx side (Arduino sends data, while the peripheral can back-pressure). The library should enable the Arduino to stop transmitting within 1 character of seeing a 'not ready' indication from the peripheral.

Thank you.

1

3 Answers 3

2

I am not aware of any such library. You could try to implement one yourself, and maybe share it with the community. :-)

If you take this route, you will have to copy the file HardwareSerial.cpp from the Arduino core, make your changes there, and have your version replace the one from the core. Here are some ideas that may help to get you started:

  • Wire the 'ready' signal from the device to an interrupt-capable pin of the Arduino.
  • Inside the interrupt handler:
    • when 'ready' is deasserted, disable the UDRE interrupt by issuing cbi(*_ucsrb, UDRIE0)
    • when ready is asserted, enable it again, but only if the output buffer is not empty: if (_tx_buffer_head != _tx_buffer_tail) sbi(*_ucsrb, UDRIE0);
  • Patch HardwareSerial::write() to enable the interrupt only if 'ready' is asserted.
  • Note that the UDRE IRQ can be explicitly called by HardwareSerial::flush() and by HardwareSerial::write() if interrupts are globally disabled. You will have to condition this on the 'ready' signal.
  • Note also that HardwareSerial::write() can write directly to the UART if the buffer is empty. This also has to be conditioned on the 'ready' signal.
0

I believe that CTS would be fairly easy to implement:

void loop() {
  uint8_t clear_to_send = digitalRead(CTS);
  volatile char data;
  if (clear_to_send) {
    Serial.write(data);
  }
}

I'm not sure about RTS.

3
  • 2
    This wont work to stop the transmission within a one (or even a few) characters, because although you stopped the Serial.write, there may already be data in the serial buffer (default 64bytes I think in Arduino lib) that could continue to go out (and potentially lost). Anyways, I shifted to Teensy, which has hardware based RTS/CTS flow control, so it is capable of stopping as soon as (i believe 1 character) CTS is deasserted
    – O.K.
    Commented Aug 2, 2016 at 3:39
  • Hardware USART is better for sure. Though, you could flush the buffer Serial.flush() after every write and store the last sent byte to be sent later.
    – woo2
    Commented Aug 2, 2016 at 3:46
  • I'd be surprised if there is no Arduino implementation. Usually, the (hardware) send buffer on an UNO is, I believe, 1 byte. The Arduino serial wrapper has it's own software buffer implemented. You could change it there. But you may have to retrigger the sending manually (since I think they use the "tx complete interrupt" to wait for the next possible send, which won't happen if you stop the sending)
    – aaa
    Commented Nov 30, 2016 at 7:04
0

I have I discovered that RTS/CTS may be implemented in genuine Arduinos, but is not supported by Arduinos that use the CH340 USB to serial chip. I found this when my JAVA program could talk with a genuine Uno ok, but didn't send any data to several Arduino compatibles that use the CH340 chip (but did receive from them). I had RTS/CTS set on the JAVA program. When I changed it to FLOWCONTROL_NONE it started working just fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.