RS485: ESP32 not relinquishing control of the bus
Posted: Wed Jun 19, 2024 9:32 pm
I have been struggling with a particular RS485 device because sporadically the ESP32 receives less bytes from it than expected. For a while I thought it was a problem with this device because I have used exactly the same setup and code to communicate with other devices with 100% success rate (slower baud rate is the only difference; 9600 baud/s vs 115200 baud/s). But I have now discovered that it is a problem on my side.
Specifically, the `RTS` signal from the ESP32 is sometimes going low a too long while (~300 micro-seconds) after the master's/ESP32's transmission has ended. This causes the RS485 driver chip in my board (Texas Instruments SN65176BDR) to hold control of the bus even when it is the slave's turn to respond. The slave device responds either way and its response gets attenuated enough for the ESP32 to loose the first few bytes received. See the attached images of the Bus Contention in the oscilloscope and my schematic.
My UART setup code is the one below.
I have to note that the `flow_control` member of the `uart_config_t ` typed variable is set to `UART_HW_FLOWCTRL_DISABLE` and that using `UART_HW_FLOWCTRL_RTS` causes errors in the communication.
I must say that I do not understand why this is happening. My code is heavily based on the code for the UART RS485 Echo Example by Espressif https://github.com/espressif/esp-idf/tr ... echo_rs485
Has anyone had problems like this? What am I doing wrong? Why is this behavior occurring only some times
My guess is that this is not an issue with slower (reduced baud rates) devices because of the increased time between messages but I might be wrong.
Specifically, the `RTS` signal from the ESP32 is sometimes going low a too long while (~300 micro-seconds) after the master's/ESP32's transmission has ended. This causes the RS485 driver chip in my board (Texas Instruments SN65176BDR) to hold control of the bus even when it is the slave's turn to respond. The slave device responds either way and its response gets attenuated enough for the ESP32 to loose the first few bytes received. See the attached images of the Bus Contention in the oscilloscope and my schematic.
My UART setup code is the one below.
I have to note that the `flow_control` member of the `uart_config_t ` typed variable is set to `UART_HW_FLOWCTRL_DISABLE` and that using `UART_HW_FLOWCTRL_RTS` causes errors in the communication.
I must say that I do not understand why this is happening. My code is heavily based on the code for the UART RS485 Echo Example by Espressif https://github.com/espressif/esp-idf/tr ... echo_rs485
Has anyone had problems like this? What am I doing wrong? Why is this behavior occurring only some times
My guess is that this is not an issue with slower (reduced baud rates) devices because of the increased time between messages but I might be wrong.
- void uart_rs485_init(uint32_t baud_rate){
- int intr_alloc_flags = 0;
- uart_driver_install(RS485_UART_PORT, RS485_UART_BUFFER_SIZE * 2, 0, 0, NULL, intr_alloc_flags);
- uart_config_t uart_config = {
- .baud_rate = baud_rate,
- .data_bits = UART_DATA_8_BITS,
- .parity = UART_PARITY_DISABLE,
- .stop_bits = UART_STOP_BITS_1,
- .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
- .source_clk = UART_SCLK_APB,
- };
- uart_param_config(RS485_UART_PORT, &uart_config);
- uart_set_pin(RS485_UART_PORT, RS485_UART_TXD_PIN, RS485_UART_RXD_PIN, RS485_UART_RTS_PIN, UART_PIN_NO_CHANGE);
- uart_set_mode(RS485_UART_PORT, UART_HW_FLOWCTRL_RTS);
- return;
- }