esp32-uart

How to use the Serial Port (UART) on ESP32

  • 4 min

UART, or Serial Port as it is commonly known in the Arduino world, is a communication protocol that allows asynchronous transmission and reception of data between devices.

Unlike synchronous communications, such as SPI or I2C, UART does not require an additional clock signal. This makes it a flexible and widely used option in a great variety of applications.

UART ports allow us to communicate with other devices, such as other microcontrollers, computers, sensors, GPS modules, some types of displays, among others.

UART on the ESP32

The ESP32 has more than one UART, depending on the model we are using. Specifically:

  • The ESP32 and ESP32-S3 have 3 UARTs
  • The ESP32-S3 and ESP32-C3 have 2 UARTs

These ports are called UART0, UART1 and UART2. Each of them can use four pins, RX, TX, CTS and RTS (but the Arduino environment only uses RX and TX).

Another difference of the ESP32 compared to a conventional Arduino is that, thanks to its multiplexer, we can reassign the UARTs to any pin without performance loss.

The UARTs come preconfigured to use certain pins. But we can (and sometimes must), change the pins.

These are the default assignments for the ESP32

UART PortTXRXRTSCTS
UART0132219
UART1109116
UART2171678

As we can see, UART1’s TX and RX pins coincide with those used to connect the SPI Flash memory. So if we want to use the UART, we will necessarily have to reassign the pins.

These are the default assignments for the ESP32-S3

UART PortTXRXRTSCTS
UART049501516
UART117181920
UART2----

In this case, UART2 is not associated by default with any pin. So if we want to use it, we will again have to reassign it to a pin of our choice.

How to Use UART on the ESP32 in the Arduino Environment

Using the UART on the ESP32 in the Arduino environment is not too complicated (if we are clear about what we are doing).

Basically, we have the same functions available as we would on any Arduino, such as print(), println(), read(), available() and others to send and receive data.

Serial.println("Hello, UART!");
Copied!

If you have doubts, check the links to the tutorials I posted before.

Using Multiple UARTs on the ESP32

The only “mess” you will have is with the pins of UART1 and UART2. To make it simpler, just like on the Arduino Mega, the ESP32 Core for Arduino defines three UARTs as Serial, Serial1 and Serial2.

The “normal” Serial is an alias for UART0 and will work without problems. It is used for programming and communication via the board’s USB (so changing its pins is neither necessary nor a good idea).

Things change with Serial1 and Serial2. Depending on your ESP32 model and your board, it is normal that the Serial1 and Serial2 syntax will not work for you.

The best thing you can do if you want to use more than one UART is to manually define the pins. In fact, I wouldn’t even think of using UART1 or UART2 without specifying which pins it is associated with.

The good news is that it is very easy to associate them. For this we need the HardwareSerial library, which are the “guts” of what we call ‘Serial’ in Arduino.

The necessary steps are

  1. Include the library
  2. Define a new HardwareSerial
  3. Initialize it with begin(...)

Here is an example:

include <HardwareSerial.h>

HardwareSerial MySerial(1); // define a Serial for UART1
const int MySerialRX = 16;
const int MySerialTX = 17;

void setup() 
{
	// initialize the Serial to the pins
    MySerial.begin(11500, SERIAL_8N1, MySerialRX, MySerialTX);
}

void loop() 
{
	// here we could use our MySerial normally
    while (MySerial.available() > 0) {
        uint8_t byteFromSerial = MySerial.read();
        //and whatever else
    }
   
    MySerial.write(...);
}
Copied!