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.txtAdd these lines:
enable_uart=1
dtoverlay=disable-btdisable-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.serviceReboot
sudo rebootVerify the port exists
ls -l /dev/serial0You should see /dev/serial0 -> ttyAMA0. If it points to ttyS0 (mini UART), the disable-bt overlay didn't take effect.
GPIO UART Pinout
| Pin | GPIO | Function | Notes |
|---|---|---|---|
| 8 | GPIO 14 | TXD (transmit) | Pi sends data |
| 10 | GPIO 15 | RXD (receive) | Pi receives data |
| 6 | - | Ground | Must 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:
| Device | Type | Pins | Notes |
|---|---|---|---|
/dev/serial0 | Symlink | GPIO 14/15 | Points to the primary UART |
/dev/ttyAMA0 | PL011 (hardware) | GPIO 14/15 | Stable clock, good for high baud rates |
/dev/ttyS0 | Mini UART | GPIO 14/15 | Clock tied to CPU frequency (unstable) |
On Pi 4/5, additional UARTs can be enabled via overlays:
dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5These 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 $USERLog 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 triggerNow use /dev/ttyGPS in your code. It will always point to the right device.
Troubleshooting
| Problem | Fix |
|---|---|
Permission denied on /dev/serial0 | Add user to dialout group |
/dev/serial0 missing | Check /boot/config.txt has enable_uart=1, reboot |
| Garbled data on GPIO UART | Use disable-bt overlay for PL011 UART (not mini UART) |
| Garbled data on USB serial | Baud rate mismatch between Python and device |
ttyUSB0 changes on reboot | Use a udev rule for a persistent symlink |
| No data from device | Check wiring (TX to RX, RX to TX), verify GND is connected |