Arduino UART Tutorial: Serial Communication, Sending & Receiving Data with Examples
Every Arduino project eventually needs to talk to something — a PC for debugging, a GPS module for location data, a GSM module for SMS, an ESP8266 for Wi-Fi, or another microcontroller in a larger system. UART is how that conversation happens. Two wires (TX and RX), a matched baud rate, and the Arduino Serial library — that is the entire setup.
In this tutorial you will learn how UART communication works at the parameter level (baud rate, data bits, stop bits, parity), which pins carry TX and RX on Uno, Nano, and Mega, and how to use every key function in the Arduino Serial library. You will then build three complete examples: sending data from Arduino to your PC, receiving data from the PC and echoing it back, and controlling an LED on pin 13 from commands typed in the Serial Monitor. A troubleshooting section covers the three most common UART problems — baud rate mismatch, crossed TX/RX wiring, and Hardware UART versus SoftwareSerial.
Before starting, check that you are comfortable with:
- Arduino digitalWrite() & digitalRead() — Complete Guide
- Arduino External Interrupts — attachInterrupt() & ISR
For other Arduino communication protocols covered on this site:
- Arduino I2C Tutorial: Wire Library, Master/Slave & Scanner
- Arduino SPI Tutorial
- Arduino PWM and analogWrite() — Complete Guide
- Arduino ADC and analogRead() — Complete Guide
- Arduino delayMicroseconds() — Precision Timing Guide
Browse the full Arduino Core tutorials collection for more.

- Arduino UART Communication — How It Works
- Connect Arduino to PC via UART
- Send Data from Arduino to PC — Serial.println()
- Receive Data from PC on Arduino — Serial.read()
- Control Arduino LED from PC via UART
- UART Troubleshooting — Common Problems & Fixes
- Real-World UART Applications for Arduino
- Arduino UART: Frequently Asked Questions
Arduino UART Communication — How It Works
What Is UART (Universal Asynchronous Receiver-Transmitter)?
UART (Universal Asynchronous Receiver/Transmitter) is one of the most common ways for Arduino boards to communicate with other devices. It allows data to be sent and received one bit at a time over just two wires: TX (transmit) and RX (receive). Unlike parallel communication, where multiple bits are sent simultaneously, UART is simple, lightweight, and perfect for connecting Arduino to a computer, sensors, or other microcontrollers.
A UART frame diagram shows how data is transmitted bit by bit over a serial line between devices. Each frame consists of several key parts that ensure the data is sent and received correctly:
- Idle Line – When no data is being transmitted, the line remains at a logic HIGH (
1). This is the default state. - Start Bit – A single logic LOW (
0) signals the beginning of a data frame. The receiver detects this to know that incoming bits are about to arrive. - Data Bits – Typically 8 bits, sent least significant bit (LSB) first. These bits carry the actual information. Each bit lasts for the duration defined by the baud rate.
- Parity Bit (Optional) – Used for error checking. Depending on the configuration, it can be even or odd parity. If not used, this bit is skipped.
- Stop Bit(s) – One or more logic HIGH (
1) bits mark the end of the frame, allowing the receiver to prepare for the next data frame.
By looking at the UART frame diagram, you can visualize the sequence of bits on the TX/RX line. This makes it easier to understand how serial communication works, troubleshoot errors, and design communication protocols between Arduino and other devices.
UART Communication Parameters
The key UART parameters are:
- Baud Rate
- Defines the speed of data transfer in bits per second (bps).
- Both the Arduino and the device it communicates with must use the same baud rate.
- Common baud rates include
9600,115200, etc. - Example in Arduino:
Serial.begin(9600);
- Data Bits
- Determines how many bits represent each character or data unit.
- Standard is 8 bits per character.
- Stop Bits
- Used to indicate the end of a data packet.
- Can be 1 or 2 bits. Arduino usually uses 1 stop bit by default.
- Parity
- A method to check for errors in transmitted data.
- Can be None, Even, or Odd. Arduino typically uses No parity.
- Flow Control (Optional)
- Manages the pace of data transfer between devices to prevent data loss.
- Hardware flow control (RTS/CTS) is rarely used on standard Arduino boards.
These parameters must be correctly configured on both communicating devices to ensure error-free UART communication. In Arduino, most of these settings are handled automatically with the Serial.begin() function, while advanced settings can be configured using lower-level commands.
Arduino UART TX and RX Pins by Board
UART communication on Arduino relies on two main pins: TX (Transmit) and RX (Receive). The TX pin is used to send data from the Arduino to another device, while the RX pin receives data from external devices.
On most Arduino boards:
- Arduino Uno / Nano:
- TX = Pin 1
- RX = Pin 0
- Arduino Mega:
- Serial0: TX0 = Pin 1, RX0 = Pin 0
- Serial1: TX1 = Pin 18, RX1 = Pin 19
- Serial2: TX2 = Pin 16, RX2 = Pin 17
- Serial3: TX3 = Pin 14, RX3 = Pin 15
Arduino Serial Library — Key Functions
The Arduino Serial Library provides a set of built-in functions to use the UART module for serial communication. It allows Arduino boards to send and receive data over the TX (transmit) and RX (receive) pins easily. Using this library, you can communicate with a PC, another Arduino, or any device that supports UART.
Key Functions of the Serial Library:
Serial.begin(baudRate)- Initializes the UART communication with the specified baud rate.
- Example:
Serial.begin(9600);
Serial.print()/Serial.println()- Sends data from Arduino to the connected device.
Serial.println()adds a new line after the data.
Serial.read()- Reads incoming data from the RX pin.
- Returns the first byte of incoming serial data.
Serial.available()- Checks if data is available to read.
- Returns the number of bytes in the receive buffer.
Serial.flush()- Clears the serial buffer to ensure no leftover data interferes with new communication.
The Arduino Serial Library abstracts the low-level details of UART, making it easy for beginners to implement serial communication without worrying about hardware registers or timing.
Connect Arduino to PC via UART
Most Arduinos (Uno, Nano, Mega) come with a USB-to-Serial converter. You can use the USB cable to directly connect the Arduino to the computer. Alternatively, you can also use some external hardware (USB to TTL Converter) to communicate to the computer.
To communicate with your computer using UART:
- USB Connection: Simply connect the Arduino via USB to your PC. This allows communication through the Serial Monitor in the Arduino IDE.
- Direct UART (Optional): If you want to use the hardware UART pins directly:
- Connect Arduino TX → USB-to-Serial RX
- Connect Arduino RX → USB-to-Serial TX
- Connect GND → GND
This setup is useful when using external modules or USB adapters without affecting the Arduino’s main USB connection.
The image above shows how to connect the Arduino to an external USB to TTL Module (Like FT232). The TX pin from Arduino connects to the RX pin of the module and RX pin from Arduino connects to the TX pin of the module.
Send Data from Arduino to PC — Serial.println()
We will first learn how to transmit data from Arduino to the PC using UART. This is useful for logging sensor readings, debugging programs, or sending status messages from your Arduino to the computer.
Code — Transmit “Hello, PC!” Every Second
Sending data from Arduino to your PC is simple with the Serial object. First, you need to initialize the UART communication in the setup() function using the Serial.begin() command with a chosen baud rate. For example:
void setup() {
Serial.begin(9600); // Initialize UART at 9600 baud
}
void loop() {
Serial.println("Hello, PC!"); // Send data to the PC
delay(1000); // Wait 1 second before sending the next message
}Explanation:
Serial.begin(9600)sets the communication speed to 9600 bits per second.Serial.println()sends data followed by a newline character, making it easier to read in the Serial Monitor.- The
delay()function ensures messages are not sent too fast.
Open the Arduino Serial Monitor
Once the Arduino is running the above code:
- Open the Arduino IDE.
- Go to Tools → Serial Monitor (or press
Ctrl+Shift+M).
- Set the baud rate in the Serial Monitor to match your
Serial.begin()(e.g., 9600). - You will see “Hello, PC!” appearing every second.
Output — Message Appears Every 1 Second
The GIF below shows the output of the above code on the Serial monitor.
This simple example demonstrates one-way UART communication from Arduino to your PC. It’s useful for debugging, logging sensor data, or sending status messages to your computer.
Receive Data from PC on Arduino — Serial.read()
Arduino can not only send data to a PC but also receive data from the computer over UART. This is useful for controlling Arduino projects from a PC, sending commands, or updating variables in real-time.
How UART Reception Works on Arduino
When data is sent from the PC to Arduino, it arrives on the RX (Receive) pin. Arduino reads this incoming data using the Serial.read() or Serial.readString() functions. The data is stored in a buffer until your program processes it.
Key points:
- Each character sent from the PC is received one byte at a time.
- The Arduino must check if data is available before reading it using
Serial.available(). - Matching baud rates on both Arduino and PC is essential; otherwise, the received data may be garbled.
Code — Echo Received Characters Back to PC
Here’s a simple example that reads data from the PC and echoes it back:
void setup() {
Serial.begin(9600); // Start UART at 9600 baud
Serial.println("Send me a message:");
}
void loop() {
if (Serial.available() > 0) { // Check if data is available
char receivedChar = Serial.read(); // Read one byte
Serial.print("You sent: ");
Serial.println(receivedChar); // Echo back the received character
}
}Explanation:
Serial.available()returns the number of bytes waiting in the buffer.Serial.read()reads the first byte from the buffer.Serial.println()sends a response back to the PC, confirming what was received.
Output — Serial Monitor Echo Demo
The image below shows the data sent by PC is received by Arduino and transmitted back to PC.
Control Arduino LED from PC via UART
You can expand the serial to control LEDs, motors, or other components. For example:
void setup() {
Serial.begin(9600); // Start UART at 9600 baud
Serial.println("Send 1 to turn on the LED\n And 0 to turn it OFF");
pinMode(13, OUTPUT);
}
void loop() {
if (Serial.available() > 0) { // Check if data is available
char receivedChar = Serial.read(); // Read one byte
if (receivedChar == '1') {
digitalWrite(13, HIGH); // Turn LED ON
Serial.println("LED turned ON");
} else if (receivedChar == '0') {
digitalWrite(13, LOW); // Turn LED OFF
Serial.println("LED turned OFF");
}
}
}We will control the LED connected to pin 13 using the data received from the UART. I have already covered how to control the LED on Arduino, so check out the tutorial if you haven’t.
Here we will turn the LED ON if the data is a ‘1’ and turn it OFF if the data is ‘0’. We will also print the state of the LED on the console.
This way, you can send simple commands from your PC via the Serial Monitor or a custom application to control your Arduino project.
Output — LED Response to Serial Commands
The GIF below shows the LED is controlled by the data received from PC via UART.

As you can see in the gif, when a ‘1’ is sent by the PC, the LED is turned ON. Similarly, when a ‘0’ is sent, the LED is turned OFF. When any other data is sent (other than ‘0’ and ‘1’), the LED is not affected at all.
UART Troubleshooting — Common Problems & Fixes
UART communication is usually straightforward, but beginners often encounter common problems. Understanding these issues and their solutions can save a lot of debugging time.
Baud Rate Mismatch — Garbled Output
A baud rate mismatch occurs when the Arduino and the device it’s communicating with (PC, module, or another microcontroller) are set to different speeds. For example, if Arduino is transmitting at 9600 baud but the PC is set to 115200, the data received will appear garbled or unreadable.
Fix:
- Ensure both devices use the same baud rate in code and serial monitor.
- Double-check
Serial.begin(baudRate)in your Arduino sketch matches the PC or module settings.
TX/RX Crossed Incorrectly — No Data
Incorrect wiring of TX (Transmit) and RX (Receive) pins is a very common UART issue. Remember:
- Arduino TX → Module/PC RX
- Arduino RX → Module/PC TX
Fix:
- Always cross the TX and RX connections.
- Connect GND to GND between devices to ensure a common reference voltage.
- Avoid connecting devices that use the same UART pins simultaneously (especially on Arduino Uno with USB).
Hardware UART vs SoftwareSerial — When to Use Each
- Hardware UART: Built into the Arduino’s microcontroller, offers reliable, high-speed communication, usually using the
Serialobject. Most boards have at least one hardware UART. - SoftwareSerial: A library that simulates UART on any digital pins. It is slower and may not be suitable for high-speed communication or simultaneous multiple UART devices.
Use hardware UART whenever possible for reliability, and reserve SoftwareSerial for additional peripherals when hardware UART pins are occupied.
USB Conflict on Arduino Uno — TX/RX Shared with USB
Pins 0 (RX) and 1 (TX) on the Arduino Uno are also used by the USB connection. If another UART device is connected to these pins, sketch uploads or Serial Monitor communication may fail.
Fix
- Disconnect devices from pins 0 and 1 while uploading code
- Use
SoftwareSerialon different GPIO pins - Use boards with multiple UARTs like the Mega 2560
Real-World UART Applications for Arduino
UART is not just for simple message logging. It is widely used in real-world projects for communication with modules, debugging, and remote control.
GPS Modules — NMEA Sentences over UART
Many Arduino-compatible modules rely on UART for communication:
- GPS Modules: Send location coordinates to Arduino via UART.
- GSM Modules: Receive and send SMS/AT commands using UART.
- ESP8266 Wi-Fi Modules: Connect Arduino to the internet, receive commands, or send data via UART.
Tip: Always check the module’s datasheet for the correct TX/RX pins and baud rate.
GSM Modules — AT Commands over UART
UART is a powerful tool for debugging:
- Send variable values or sensor readings to the Serial Monitor.
- Track program flow by printing messages at key points in your code.
- Identify errors in real-time without stopping the program.
Example:
Serial.print("Temperature: ");
Serial.println(sensorValue);This prints sensor values live, making it easier to troubleshoot and optimize your project.
ESP8266 Wi-Fi Modules — Wi-Fi via UART
ESP8266 modules commonly use UART to communicate with Arduino boards.
Using UART, Arduino can:
- Send AT commands to the ESP8266
- Connect to Wi-Fi networks
- Send sensor data to cloud servers
- Receive commands from web or mobile applications
Example applications:
- IoT sensor monitoring
- Remote LED control
- Weather stations
- Home automation systems
Most ESP8266 modules operate at 3.3V logic levels, so avoid connecting 5V UART signals directly.
Debugging Live Sensor Values with Serial Monitor
UART is one of the easiest ways to debug Arduino projects in real time.
Using the Serial Monitor, you can:
- Print sensor readings continuously
- Check variable values during execution
- Verify program logic
- Detect unexpected behavior quickly
Example:
Serial.print("Temperature: ");
Serial.println(sensorValue);
This sends live sensor values to the Serial Monitor, making troubleshooting much easier during development.
Arduino UART: Frequently Asked Questions
Yes, but it depends on your board. Arduino Uno has only one hardware UART, so additional devices require SoftwareSerial or other multiplexing techniques. Boards like the Mega have multiple hardware UARTs, which can communicate with several devices simultaneously without timing issues.
UART requires compatible voltage levels between devices. Standard Arduino boards operate at 5V logic, while some modules (like ESP8266) use 3.3V logic. Connecting them directly may damage the lower-voltage module. Use a level shifter to safely interface devices with different logic voltages.
UART is generally meant for short distances (a few meters) due to voltage degradation and noise. For longer distances, you can use RS-232 or RS-485 converters, which allow UART communication over tens to hundreds of meters while maintaining signal integrity.
To reliably handle multiple bytes, implement start and stop delimiters or a fixed-length protocol. You can also use buffers and check Serial.available() before reading. Libraries like SerialEvent in Arduino IDE can help manage incoming data efficiently.
On boards like the Arduino Uno, the hardware UART is shared with the USB interface. This means if you connect a device to the TX/RX pins while uploading a sketch, it may interfere with uploading. For uninterrupted UART communication, use boards with multiple UARTs (Mega) or SoftwareSerial on separate pins.
Conclusion
UART is the foundational communication protocol in the Arduino ecosystem — it is how your sketch talks to your PC during development, how your board connects to GPS, GSM, Wi-Fi, and Bluetooth modules in deployed projects, and how two microcontrollers exchange data in larger systems. The Serial library abstracts all the hardware complexity: Serial.begin() configures the baud rate, Serial.available() tells you when data has arrived, and Serial.read() retrieves it one byte at a time.
In this tutorial you covered the full one-wire-per-direction model — TX out, RX in, GND shared — and the four parameters that both sides must agree on before a single byte transfers correctly. You sent data to the PC with Serial.println(), received it back with Serial.read(), parsed command characters to control an LED, and confirmed the behaviour live in the Serial Monitor.
The troubleshooting section covers the three problems that catch nearly every beginner: baud rate mismatch producing garbled output, TX/RX crossed the wrong way producing silence, and using SoftwareSerial on a Uno when hardware UART pins are already occupied by USB.
UART feeds naturally into more advanced protocols. I2C connects multiple sensors on two wires with addressed communication. SPI gives you higher-speed full-duplex transfers for displays and SD cards. External interrupts let your board react to a UART RX event without polling Serial.available() in every loop iteration. Download the full project above and explore the Arduino Core tutorials collection for the next step.
Download Arduino UART Serial Communication Project Files
Complete Arduino sketches for UART serial communication: transmit "Hello, PC!" every second via Serial.println(), receive and echo characters with Serial.read(), and control the onboard LED on pin 13 by sending '1' (ON) and '0' (OFF) from the Serial Monitor. All code runs at 9600 baud and is compatible with Uno, Nano, and Mega. Free to download — support the work if it helped you.
Browse More Arduino Core Tutorials
Arduino ADC and analogRead() Explained: Complete Guide with Examples
Arduino I2C Tutorial: Wire Library, Master/Slave, Scanner & Troubleshooting
Arduino delayMicroseconds() Tutorial: Precise Timing, Pulses & Alternatives
Arduino PWM and analogWrite() Explained: Complete Guide with Examples
Arduino External Interrupts Tutorial: attachInterrupt(), ISR & Debounce
Arun is an embedded systems engineer with 10+ years of experience in STM32, ESP32, and AVR microcontrollers. He created ControllersTech to share practical tutorials on embedded software, HAL drivers, RTOS, and hardware design — grounded in real industrial automation experience.
Recommended Tools
Essential dev tools
Categories
Browse by platform





