I have a similar issue. I want to use the ESP32 with RS485. I have used the Arduino and this works well assigning pins, but it seems not to allow full use of the UART.

I see the new uarts in the ESP32 can support the direction control (RTS) of the direction pin and there is actually a hardware RS485 mode. See the repository that the board package is based on: https://github.com/espressif/arduino-esp32

Then https://github.com/espressif/arduino-esp32/tree/master/tools/sdk/include/driver/driver uart.h

This shows we can actually have full hardware flow control, so no more guessing delays for controlling the DIR lines or getting interrupts when the send buffer is empty in order to know when to switch back to receive.

I found using board manager this did not all get installed, so I followed some tutorials on how to install it manually. The board either doesn't appear at all, or I can't reference "uart.h".

Any ideas or examples? Thanks, Mark


2 Answers 2


your example was of great help solving the problem of driving RTS properly, thanks a lot!

I found a small bug in the code example, the data buffer is allocated in the loop() function instead of setup() and as a result, eventually the memory leak will fill-up all available memory.

Ciao! Alessandro


Espressif and Arduino use the same UART numbering, and there are no hidden properties of hardwareSerial that are bound to it UART instance So it's possible to perform a reach-around and replace the arduino harwareSerial UART driver instance with an espressif RS485 uart instance and then use Arduinos hardwareSerial methods to communicate with the UART.

#include <Arduino.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <driver/uart.h>

#define ECHO_TEST_TXD   (25)
#define ECHO_TEST_RXD   (26)
#define ECHO_TEST_RTS   (27)
#define BUF_SIZE        (127)
#define BAUD_RATE       (9600)

#define         SERIAL_485 Serial 
#error  Serial is already committed elsewhere in this code

#define         SERIAL_485 Serial1 

#define         SERIAL_485 Serial2 

static const char *TAG = "RS485_ECHO_APP";
void setup() {
    Serial.begin(115200); //uses UART_NUM_0
    //configure UART_NUM_2 for RS485
    const uart_port_t uart_num = ECHO_UART_PORT;
    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,
        .rx_flow_ctrl_thresh = 122,
    Serial.println("Start RS485 application test and configure UART.");
    // start arduino serial port
    SERIAL_485.setTimeout(1+(10000/BAUD_RATE) ); // 10000 is 10 symbols per byte * 1000 ms per second
    // drop rhe Arduino installed UART driver!
    // we will replace this with a 485 capable driver.

    // Configure UART parameters
    uart_param_config(uart_num, &uart_config);

    Serial.println("UART set pins, mode and install driver.");
    // Set UART1 pins(TX: IO23, RX: I022, RTS: IO18, CTS: IO19)
    // Install UART driver (we don't need an event queue here)
    // In this example we don't even use a buffer for sending data.
    uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0);
    // Set RS485 half duplex mode
    uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX);
    ESP_LOGI(TAG, "UART start recieve loop.\r\n");
    SERIAL_485.printf("Start RS485 UART test.\r\n");

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.