PySerial
PySerialDocs

Raspberry Pi

Set up PySerial on Raspberry Pi. Enable UART, configure GPIO serial pins, and communicate with devices over USB and GPIO.

Use PySerial on Raspberry Pi to talk to sensors, microcontrollers, and industrial devices over GPIO UART or USB serial.

Enable UART on Raspberry Pi

Edit boot config

sudo nano /boot/config.txt

Add these lines:

enable_uart=1
dtoverlay=disable-bt

disable-bt frees the full hardware UART (/dev/ttyAMA0) from Bluetooth, giving you a stable clock-backed UART on GPIO 14/15.

Disable serial console

The Pi uses the serial port as a login console by default. Disable it so your application can use the port:

sudo systemctl disable serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@serial0.service

Reboot

sudo reboot

Verify the port exists

ls -l /dev/serial0

You should see /dev/serial0 -> ttyAMA0. If it points to ttyS0 (mini UART), the disable-bt overlay didn't take effect.

GPIO UART Pinout

PinGPIOFunctionNotes
8GPIO 14TXD (transmit)Pi sends data
10GPIO 15RXD (receive)Pi receives data
6-GroundMust connect to device GND

Raspberry Pi GPIO pins are 3.3V. Do not connect 5V serial devices directly. Use a level shifter between the Pi and any 5V UART device (Arduino Mega, RS-232 adapters, etc.).

Basic Serial Communication

import serial
import time

ser = serial.Serial(
    port='/dev/serial0',
    baudrate=115200,
    timeout=1,
)

# Send a command
ser.write(b'AT\r\n')
time.sleep(0.1)

# Read response
response = ser.read(ser.in_waiting or 1)
print(f"Response: {response.decode()}")

ser.close()

Log Raspberry Pi test data automatically

TofuPilot records test results from your PySerial scripts, tracks pass/fail rates, and generates compliance reports. Free to start.

USB Serial Devices

USB serial adapters show up as /dev/ttyUSB0 (FTDI, CH340) or /dev/ttyACM0 (Arduino, CDC-ACM). List connected devices:

import serial.tools.list_ports

for port in serial.tools.list_ports.comports():
    print(f"{port.device}: {port.description}")
    if port.vid:
        print(f"  VID:PID = {port.vid:04X}:{port.pid:04X}")

To open a USB serial device:

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
data = ser.readline()
print(data.decode())
ser.close()

UART Device Map

Raspberry Pi 3/4/5 have multiple UARTs. After applying the disable-bt overlay:

DeviceTypePinsNotes
/dev/serial0SymlinkGPIO 14/15Points to the primary UART
/dev/ttyAMA0PL011 (hardware)GPIO 14/15Stable clock, good for high baud rates
/dev/ttyS0Mini UARTGPIO 14/15Clock tied to CPU frequency (unstable)

On Pi 4/5, additional UARTs can be enabled via overlays:

dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5

These map to /dev/ttyAMA1 through /dev/ttyAMA4 on different GPIO pins. Check the Raspberry Pi UART documentation for pin assignments.

Permissions

If you get "Permission denied" when opening a serial port, add your user to the dialout group:

sudo usermod -aG dialout $USER

Log out and back in for the change to take effect.

Persistent Port Names with udev

USB serial devices can change between /dev/ttyUSB0 and /dev/ttyUSB1 on reboot. Create a udev rule for a stable name:

# Find device attributes
udevadm info -a /dev/ttyUSB0 | grep -E 'idVendor|idProduct|serial'
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyGPS"
sudo udevadm control --reload-rules
sudo udevadm trigger

Now use /dev/ttyGPS in your code. It will always point to the right device.

Troubleshooting

ProblemFix
Permission denied on /dev/serial0Add user to dialout group
/dev/serial0 missingCheck /boot/config.txt has enable_uart=1, reboot
Garbled data on GPIO UARTUse disable-bt overlay for PL011 UART (not mini UART)
Garbled data on USB serialBaud rate mismatch between Python and device
ttyUSB0 changes on rebootUse a udev rule for a persistent symlink
No data from deviceCheck wiring (TX to RX, RX to TX), verify GND is connected