Skip to content

Enable UART Flow Control #6185

Closed
Closed
@GioTB

Description

@GioTB

Related area

UART

Hardware specification

ESP32

Is your feature request related to a problem?

No, i just need to use uart flow control.

Describe the solution you'd like

Enable support for flow control (RTS and CTS, perhaps it would be also usefull to enable DTR and DSR)

Describe alternatives you've considered

Add a parameter on the "begin" function that allows to select if the serial should use CTS/RTS and a pin assigment (might be just adding de pins, and if they are different than -1 the flow control would be enabled).
Also a "setRts" and "setCts" function could be implemented to enable one or both flow control pins

Additional context

No response

I have checked existing list of Feature requests and the Contribution Guide

  • I confirm I have checked existing list of Feature requests and Contribution Guide.

Activity

VojtechBartoska

VojtechBartoska commented on Jan 24, 2022

@VojtechBartoska
Contributor

@SuGlider Can you please take a look?

SuGlider

SuGlider commented on Jan 24, 2022

@SuGlider
Collaborator

@GioTB

Thanks for the suggestion.

In the meanwhile, Arduino UART is based on IDF, thus all the IDF calls can be used in conjunction with Arduino HardwareSerial
You can activate it by using specific IDF calls within your Arduino Sketch.

You can use this IDF call with UART_PIN_NO_CHANGE for the pins that you don't want to change.
uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)

You can also set Hardware Flow Control mode to use CTS, RTS together or each one isolated.
uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh)

For instance:

#include "driver/uart.h"
void setup() {
  Serial.begin(115200);   // uses default RX/TX pins for UART 0

  // it sets pin 2 for RTS and pin 4 for CTS in UART 0 (Arduino Serial)
  uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 2, 4);
  
  // UART_HW_FLOWCTRL_CTS_RTS or only UART_HW_FLOWCTRL_CTS | UART_HW_FLOWCTRL_RTS
  // UART_HW_FLOWCTRL_DISABLE to disable Hardware Control on UART
  // 64 is the Threshold for RX Flow control when RTS is used. It goes from 0 to 127 (bytes).
  uart_set_hw_flow_ctrl(UART_NUM_0, UART_HW_FLOWCTRL_CTS_RTS, 64);
}

Please let me know if this would solve your current need.

GioTB

GioTB commented on Jan 24, 2022

@GioTB
Author

Hello, thanks for your response. I didn´t know the esp-idf functions where available on the Arduino framework, i tested it, and it works!, but, it still has the problem of the queue of the HardwareSerial filling up if i don´t empty it, of course this wouldn´t be a "hardware flow control" implementation, and i could just set the buffer to a bigger size, but i need totally confident that the flow control will prevent the other device from sending data. Since the hardware serial doesn´t give direct access to that queue i can´t check it on my code to empty it or to disable CTS line if the queue it´s full. Never the less since i see i have access to the esp-idf functions i´ll implement the project using those. As an idea, for the implementation of this flow control on the arduino framework: on the uart_isr it could check if the queue it´s "almost full" (like the Rx thresshold), for de-asserting the CTS line, so any byte will be lost.

Thanks for your help!, if there is anything that i could help let me know.

SuGlider

SuGlider commented on Jan 24, 2022

@SuGlider
Collaborator

Arduino HardwareSerial, in Arduino Core V2.0.0+, is implemented on top of IDF.
Thus any IDF call will affect directly HardwareSerial as well.

I didn't test it, but uart_set_hw_flow_ctrl(UART_NUM_0, UART_HW_FLOWCTRL_CTS_RTS, 64); shall rise RTS line when ESP32 has more than 64 bytes, in this example, in FIFO that have not been sent to IDF UART Driver Queue - which is the same used by Serial.read(), for instance. In case IDF Queue if full, incoming data shouldn't be moved from FIFO to the RX Queue and RTS should go high.

Anyway, we have now a UART ISR Callback that may help your application in dealing with incoming UART data.
Serial.onReceive(userCallBackFunc); - PR #6134

Not sure about which Arduino Core version you are using. We are currently in version 2.0.2.
Please test it and let me know by droping a message in this issue.
Thanks!

GioTB

GioTB commented on Jan 25, 2022

@GioTB
Author

I´m using platformio, and it seems that it´s using the 1.0.6 version, so i´m trying to upgrade it to the lastest version. As far as i can see from the code, i think it should work exactly the way you say it, once i try it i will let you know, Thanks!!!!

SuGlider

SuGlider commented on Jan 25, 2022

@SuGlider
Collaborator

1.0.6 will use IDF 3.3. Its HardwareSerial isn't based on IDF calls and the issue you commented with Queue and FIFO will actually happen.

The Arduino Core 2.0.2 uses IDF 4.4 and as said its HardwareSerial implementation is built on top of IDF, which will allow you to just use Serial.begin() followed by IDF RTS setup call making it work seamless all together.

SuGlider

SuGlider commented on Feb 12, 2022

@SuGlider
Collaborator

See PR #6272

GioTB

GioTB commented on Feb 13, 2022

@GioTB
Author

Anaother comment about the hardware flow control, when i implemented it at first it didin´t work well, and a colleague found out that it was becuase on the uart_begin function it has de uart_set_mode to "UART_MODE_RS485_HALF_DUPLEX" and after changing it to UART_MODE_UART, it works great.
so the final code we have to implement to make it work was:

Serial.begin(115200);
uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE,RTS_PIN , CTS_PIN);
uart_set_hw_flow_ctrl(UART_NUM_0, UART_HW_FLOWCTRL_CTS_RTS, 64);
uart_set_mode(UART_NUM_0, UART_MODE_UART);

SuGlider

SuGlider commented on Feb 14, 2022

@SuGlider
Collaborator

Yes, it was also fixed and removed in a prior PR #6133

Thanks for reporting it!

1 remaining item

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Enable UART Flow Control · Issue #6185 · espressif/arduino-esp32