This project demonstrates UART (Universal Asynchronous Receiver-Transmitter) communication on the ESP32 using the ESP-IDF framework. The application receives serial data through UART2 and immediately echoes the received data back to the sender. The project helps in understanding low-level serial communication, ESP32 UART peripherals, ESP-IDF UART drivers, GPIO pin routing, interrupt-driven communication, and ring buffer handling.
The communication is established between the ESP32 and a PC using an external USB-to-Serial adapter. A serial terminal running on the PC sends characters to the ESP32, and the ESP32 echoes the same characters back in real time.
UART (Universal Asynchronous Receiver-Transmitter) is one of the simplest and most widely used serial communication protocols in embedded systems. UART communication uses only two signal lines:
- TX (Transmit) → sends data
- RX (Receive) → receives data
UART is called asynchronous because it does not require a shared clock signal between devices. Instead, both devices agree on a communication speed called the baud rate before communication starts.
This project uses:
- Baud Rate: 115200
- Frame Format: 8N1
In 8N1 communication:
[START][D0][D1][D2][D3][D4][D5][D6][D7][STOP]
- Start bit indicates the beginning of transmission
- D0–D7 represent the 8-bit data
- N means no parity bit
- 1 stop bit indicates the end of transmission
The ESP32 UART peripheral is configured with these parameters using the ESP-IDF UART driver.
The ESP32 contains three hardware UART peripherals:
| UART | Usage |
|---|---|
| UART0 | Used for flashing and serial monitor |
| UART1 | General-purpose UART |
| UART2 | Used in this project |
UART0 is already connected internally to the onboard USB-to-Serial converter and is used by idf.py flash and idf.py monitor. To avoid conflicts with the debug console, this project uses UART2 for communication.
The ESP-IDF UART driver provides an abstraction layer over the hardware UART peripheral. Instead of directly accessing hardware registers, the application uses UART driver APIs provided by ESP-IDF.
When serial data arrives at the RX pin, a hardware interrupt is generated. The ESP-IDF UART driver interrupt handler stores the incoming bytes into an RX ring buffer in RAM. The application reads data from this buffer using uart_read_bytes().
Similarly, outgoing data is placed into a TX ring buffer and transmitted by the UART driver in the background using uart_write_bytes().
This interrupt-driven approach ensures that incoming serial data is not lost even when the application is temporarily busy.
UART initialization in this project follows three major steps:
A uart_config_t structure is created with:
- Baud rate = 115200
- Data bits = 8
- No parity
- 1 stop bit
- Hardware flow control disabled
The ESP32 GPIO matrix allows UART peripherals to be routed to different physical GPIO pins.
This project uses:
| Function | GPIO |
|---|---|
| TX | GPIO17 |
| RX | GPIO16 |
- Allocates RX/TX ring buffers
- Registers UART interrupt handlers
- Enables background UART communication
After this step, UART communication becomes active.
The UART echo application continuously runs inside a FreeRTOS task.
The application loop performs the following operations:
- Wait for incoming UART data using
uart_read_bytes() - Store received data into a local buffer
- Echo the same data back using
uart_write_bytes() - Print the received string using
ESP_LOGI()
If no data is received within the specified timeout, the loop continues waiting for new data.
This creates a real-time UART loopback system.
The ESP32 communicates with the PC using a USB-to-Serial adapter.
Connections:
ESP32 GPIO17 (TX) ─────► USB Adapter RX
ESP32 GPIO16 (RX) ◄──── USB Adapter TX
ESP32 GND ─────► USB Adapter GND
Important notes:
- TX must connect to RX
- RX must connect to TX
- Ground connection is mandatory
- ESP32 GPIO pins are 3.3V tolerant only
| Function | Purpose |
|---|---|
| uart_param_config() | Configure UART settings |
| uart_set_pin() | Assign TX/RX GPIO pins |
| uart_driver_install() | Install UART driver |
| uart_read_bytes() | Read UART data |
| uart_write_bytes() | Transmit UART data |
- Connect USB-to-Serial adapter
- Open PuTTY or another serial terminal
- Select correct COM port
- Set baud rate to 115200
- Type characters in terminal
- Observe echoed output
This project helped in understanding:
- UART serial communication
- ESP32 UART peripherals
- ESP-IDF UART driver architecture
- Interrupt-driven communication
- Ring buffer handling
- GPIO routing using GPIO matrix
- Real-time embedded debugging
- Git and GitHub integration for embedded projects