UART (Universal Asynchronous Receiver-Transmitter) is one of the oldest and most reliable communication protocols in electronics. Despite being decades old, it remains the go-to protocol for connecting microcontrollers, GPS modules, GSM modems, sensor arrays, and legacy devices to the Raspberry Pi. Unlike I2C or SPI, UART needs only two wires for bidirectional communication: TX (transmit) and RX (receive).
This guide covers everything you need to know about Raspberry Pi UART — from hardware wiring to reading live sensor data in Python.
UART Basics: What You Need to Know
UART communication works without a shared clock signal — both devices agree on a baud rate (bits per second) in advance. Common baud rates are 9600, 19200, 38400, 57600, and 115200. The Pi and the sensor must use the same baud rate or you’ll get garbage data.
Key UART terms:
- TX — Transmit pin. Pi’s TX connects to sensor’s RX
- RX — Receive pin. Pi’s RX connects to sensor’s TX
- Baud rate — Communication speed in bits/second
- 3.3V logic — Raspberry Pi GPIO is 3.3V, NOT 5V tolerant. Use a level shifter for 5V devices
The Raspberry Pi’s primary UART is on GPIO 14 (TX) and GPIO 15 (RX), which correspond to physical pins 8 and 10.
Step 1: Enable UART on Raspberry Pi
On Pi 5 and Pi 4 running Raspberry Pi OS Bookworm, the UART is managed differently depending on the model. The Pi 5 has 6 hardware UARTs.
sudo raspi-config
Navigate to Interface Options → Serial Port:
- Would you like a login shell accessible over serial? → No
- Would you like the serial port hardware to be enabled? → Yes
Reboot:
sudo reboot
After reboot, verify the UART device exists:
ls /dev/serial*
# On Pi 5: /dev/serial0 → /dev/ttyAMA0
# On Pi 4: /dev/serial0 → /dev/ttyS0 or /dev/ttyAMA0
Also add your user to the dialout group to access serial ports without sudo:
sudo usermod -a -G dialout $USER
newgrp dialout
Step 2: Wiring Sensors to UART
The Raspberry Pi’s UART pins are at 3.3V logic. Most modern sensors designed for Pi use 3.3V and can be connected directly. For 5V sensors (Arduino shields, some GPS modules), use a bi-directional logic level shifter.
Direct Connection (3.3V sensors)
Pi GPIO 14 (TX, Pin 8) → Sensor RX
Pi GPIO 15 (RX, Pin 10) → Sensor TX
Pi Pin 1 (3.3V) → Sensor VCC
Pi Pin 6 (GND) → Sensor GND
Important: TX of Pi connects to RX of sensor, and RX of Pi connects to TX of sensor. This cross-connection is correct and intentional.
DS18B20 Temperature Sensor (1-Wire, not UART)
The DS18B20 actually uses the 1-Wire protocol — it connects to any GPIO pin, not the UART pins. Enable 1-Wire via raspi-config:
sudo raspi-config → Interface Options → 1-Wire → Enable
Connect DS18B20 to GPIO 4 (Pin 7) with a 4.7kΩ pull-up resistor to 3.3V. Then read it:
ls /sys/bus/w1/devices/
# Shows: 28-XXXXXXXXXXXX (your sensor's address)
cat /sys/bus/w1/devices/28-XXXXXXXXXXXX/temperature
# Returns temperature in millidegrees Celsius (e.g. 25000 = 25°C)
Step 3: Reading UART Data in Python
Install the pyserial library:
pip install pyserial
Basic Serial Read
import serial
import time
# Open serial port
ser = serial.Serial(
port='/dev/serial0',
baudrate=9600,
timeout=1
)
print(f"Port open: {ser.name}")
try:
while True:
if ser.in_waiting > 0:
line = ser.readline().decode('utf-8', errors='replace').strip()
print(f"Received: {line}")
time.sleep(0.1)
except KeyboardInterrupt:
ser.close()
print("Connection closed")
GPS Module (NEO-6M/NEO-7M) via UART
GPS modules are the most common UART sensor used with Pi. They output NMEA sentences at 9600 baud:
import serial
import pynmea2 # pip install pynmea2
ser = serial.Serial('/dev/serial0', 9600, timeout=1)
while True:
try:
line = ser.readline().decode('ascii', errors='replace')
if line.startswith('$GPRMC') or line.startswith('$GNRMC'):
msg = pynmea2.parse(line)
if msg.status == 'A': # A = Active (GPS fix acquired)
print(f"Lat: {msg.latitude:.6f}, Lon: {msg.longitude:.6f}")
print(f"Speed: {msg.spd_over_grnd} knots")
except Exception as e:
pass
Step 4: Using Multiple UART Ports on Pi 5
The Raspberry Pi 5 has 6 hardware UART interfaces (UART0–UART5), all accessible via Device Tree overlays. This is a huge advantage if you need to connect multiple serial sensors simultaneously.
Enable additional UARTs in /boot/firmware/config.txt:
sudo nano /boot/firmware/config.txt
# Add these lines:
dtoverlay=uart2 # UART2 on GPIO 0 (TX) and GPIO 1 (RX)
dtoverlay=uart3 # UART3 on GPIO 4 (TX) and GPIO 5 (RX)
dtoverlay=uart4 # UART4 on GPIO 8 (TX) and GPIO 9 (RX)
dtoverlay=uart5 # UART5 on GPIO 12 (TX) and GPIO 13 (RX)
Reboot and the new UARTs appear as /dev/ttyAMA2, /dev/ttyAMA3, etc. Open them exactly like the primary UART, just with the correct device path.
Working with I2C Pressure Sensors (vs UART)
Not all sensors use UART. The BMP280/BME280 barometric pressure sensors use I2C — a different protocol that’s also common on Pi projects. Understanding when to use UART vs I2C is important:
- UART: point-to-point, longer cable runs, GPS/GSM/Bluetooth modules
- I2C: multiple devices on 2 wires, sensors, displays, RTCs (BME280, OLED, PCF8523)
- SPI: high-speed, short distance, displays, SD cards, ADCs
- 1-Wire: simple temperature sensors, long cable runs (DS18B20)
UART Alternative: Ultrasonic Distance Sensors
The JSN-SR04T waterproof ultrasonic sensor has a UART mode — connecting directly to Pi’s TX/RX pins for distance measurement, unlike the HC-SR04 which needs GPIO trigger/echo pins:
import serial
import time
ser = serial.Serial('/dev/serial0', baudrate=9600, timeout=1)
while True:
# Send measurement command
ser.write(b'x55')
time.sleep(0.1)
data = ser.read(4)
if len(data) == 4 and data[0] == 0xFF:
distance_mm = (data[1] << 8) + data[2]
print(f"Distance: {distance_mm} mm ({distance_mm/1000:.2f} m)")
time.sleep(0.5)
Troubleshooting UART Issues
- No data received — Check TX/RX are crossed (Pi TX → sensor RX). Verify both sides use the same baud rate.
- Garbage data — Baud rate mismatch or electrical noise. Use a shorter cable. Verify you’re reading the right serial port.
- Permission denied — Run
sudo usermod -a -G dialout $USERand log out/in. - Console interfering with UART — Ensure you disabled the login shell on the serial port in raspi-config.
- Data corruption with 5V sensors — Never connect a 5V TX directly to Pi’s 3.3V RX. Use a voltage divider (1kΩ + 2kΩ) or a level shifter module.
Frequently Asked Questions
What is the difference between /dev/ttyAMA0 and /dev/ttyS0?
On Raspberry Pi 4, ttyAMA0 is the full-featured PL011 UART and ttyS0 is the mini-UART. The mini-UART has variable baud rate tied to CPU clock and is less reliable — always prefer ttyAMA0. On Pi 5, all UARTs use the RP1’s full-featured UART hardware, so this distinction no longer applies. /dev/serial0 is a symlink to whichever UART is the primary one.
Can I use RS-232 devices with Raspberry Pi UART?
Not directly. RS-232 uses ±12V signals while Pi uses 3.3V TTL. You need an RS-232 to TTL converter module (MAX3232 chip). These are inexpensive and convert the voltage levels safely, letting you connect legacy serial devices like PLCs, industrial sensors, and old lab equipment.
How fast can Raspberry Pi UART communicate?
Raspberry Pi supports baud rates up to 4 Mbps on Pi 5 hardware UARTs. Practically, 115200 bps is the sweet spot for most sensor projects. GPS modules use 9600 bps, Bluetooth modules typically use 115200 bps, and high-speed industrial sensors may use 230400 or higher.
Can I use UART and I2C simultaneously on the same Pi?
Yes. UART (GPIO 14/15), I2C (GPIO 2/3), and SPI (GPIO 10/11) all use separate hardware and can operate independently at the same time. This is one of the strengths of the Pi — you can have a GPS module on UART, multiple sensors on I2C, and a display on SPI all working simultaneously in the same Python script.
My sensor datasheet says 5V — can I still connect it to Raspberry Pi?
The VCC can be connected to the Pi’s 5V pin (Pin 2 or 4) to power the sensor. However, the sensor’s TX output will be at 5V logic which can damage the Pi’s 3.3V GPIO. You must use a voltage divider or logic level shifter between the sensor’s TX and the Pi’s RX pin. The Pi’s TX → sensor RX direction is usually fine since 3.3V high is recognized as logic-high by most 5V devices.
Build your sensor projects today. Shop Raspberry Pi boards, temperature sensors, ultrasonic sensors, and humidity sensors at zbotic.in/raspberry-pi with fast delivery across India.
Add comment