Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Sensor Series
      • 3D Printing
      • AI
      • ARDUINO Compatible Coding
      • Audio Electronics
      • Battery Management
      • Beginners Electronics Series
      • Brainwave
      • Digital electronics (DE)
      • Electric Vehicles
      • EMI/EMC/RFI
      • EVs
      • Hardware Filters
      • IoT tutorials
      • LoRa/LoRaWAN
      • Power Tutorials
      • Protocol
      • Python
      • RPI Python Programming
      • Sensors
      • USB
      • Thermal management
      • Verilog
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
  • Guest Post Guidelines
  • Advertise
  • Subscribe

RPi Python Programming 19: Serial UART communication on RPi’s TTL port

By Nikhil Agnihotri July 27, 2020

In the previous tutorial, we discussed the universal asynchronous receiver-transmitter (UART) protocol and voltage levels, covering USB-serial boards and other serial adaptors. We also learned how to find a serial port name on Linux, Windows, macOS, and Raspberry Pi (RPi).

In this tutorial, we’ll learn how to use the Python Serial library to setup bidirectional communication with a computer.

Configuring UART on RPi
As discussed in the serial communication on Raspberry Pi tutorial, the default serial Linux console on Raspberry Pi OS must be disabled to use RPi’s serial TTL port for UART communication.

Follow these steps to disable RPi’s serial Linux console:

1. In Raspberry Pi, open the Terminal window (Bash shell) and execute this command:
sudo raspi-config

2. Navigate to the “Interfacing Options.”

3. Next, select the “Serial” option.

4. The configuration window will ask if you’d like the login shell to be accessible over serial. Select “No.”

5. The configuration window will then ask you to enable the serial port hardware. Select “Yes.”

6. Now, the serial TTL port (GPIO14 and GPIO15) are enabled for serial communication on Raspberry Pi.

7. Reboot Raspberry Pi for these changes to take effect.

After rebooting RPi, its serial TTL port can be used for serial communication over the UART protocol. The port can be addressed by name /dev/serial0. 

Alternatively, /dev/ttyS0 or /dev/ttyAMA0 can be used as port names, depending on whether PL011 or mini-UART is the primary UART (on the respective Raspberry Pi model). It’s possible to know which UART type is the primary one by inspecting the /boot/config.txt file. 

If in the /boot/config.txt file, the enable_uart flag is set to 0 by default, then the mini-UART is the primary UART on that RPi model. However, if the enable_uart flag is set to 1 by default, then PL011 is the primary UART on that RPi model.  

Selecting a USB-serial board  
There are several USB-serial boards available. FTDIs are the oldest and most common one. The one for use with Raspberry Pi must have 3.3V UART voltages. If a 5V USB-serial board is used, the TTL port channels of RPi can get permanently damaged. 

Some USB-serial boards offer jumpers that can be set between 5 and 3.3V UART voltages. Be sure to select the 3.3V option before connecting to Raspberry Pi. 

USB-serial boards also have an option to receive supply voltage directly from the Raspberry Pi. For this to occur, RPi’s 3.3V pin should be connected to the VCC terminal of the board. 

It’s important to ensure that: 

  • RPi’s Rx (GPIO15) connects to the Rx of the USB-serial board 
  • RPi’s Tx (GPIO14) connects to Tx of the USB-serial board. 
  • The USB-serial board’s ground pin connects to RPI’s ground (because this is the reference ground for the UART voltages).
  • The USB-serial board’s USB port connects to the USB port of a computer (desktop) via a USB-to-USB cable. 

If the serial TTL port has to connect directly with the serial TTL port of another device with the same 3.3V UART voltage levels: 

  • RPi’s Rx (GPIO15) connects to the Tx of the other device 
  • RPi’s Tx (GPIO14) connects to the Rx of the other device.    

Hardware permissions for serial 
To use RPi’s serial TTL port, the Raspberry Pi user must be a member of the dialout group. The default user is pi but there can be other users created on a Raspberry Pi system. 

If the current user is not a member of the dialout group, an attempt to access the TTL serial port will result in this warning: 

serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyS0: [Errno 13] Permission denied: ‘/dev/ttyS0’

If you’re not the default user (pi), you can add yourself to the dialout group by entering the following command on the Terminal window (Bash Shell):

sudo adduser your_username dialout

After executing the command successfully, reboot Raspberry Pi for the changes to take effect.  

Python serial library
For a Python script to use Raspberry Pi’s serial port, it requires a library to interface with it. PySerial is the library that’s used as the Python Serial Port Extension for Linux, BSD, OSX, Win32, and even Jython and IronPython. 

It’s available under the free software license on GitHub. The module encapsulates access to the serial port, including access over various interfaces (such as TTL ports, RS232, RS485, and RFC 2217) and various URL handlers. 

This library is a class-based interface that supports all major platforms. It’s a purely Python library and is compatible with Python’s io library.   

Installing PySerial 
By default, PySerial is installed on RPi. If it’s been removed, it can be installed by executing these commands on the Terminal:

python3 -m pip install pyserial
or
easy_install -U pyserial

However, if the pip is not installed, first install it by entering the commands below. Then, install PySerial. 

sudo apt install python3-pip

PySerial API 
The library includes a serial class that’s used to access a serial (UART) port. 

The class supports these read-only attributes:

The class supports these configurable attributes:

The class supports these constants:

The serial class supports these methods:

serial.Serial() — This method creates a serial object in the Python script that must point to a serial port. At the same time, it’s a constructor and supports configuration of the following parameters:

1. port – Device name or none.
2. baudrate – The baud rate in bits per second (bps). It can be any of the standard values like 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200. Standard values above 115200 are also supported on many platforms and devices but not on Raspberry Pi.
3. bytesize – The number of data bits. The possible values can be FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS.
4. parity – This enables parity checking. The possible values can be PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK, PARITY_SPACE.
5. stopbits – The number of stop bits. The possible values can be STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO.
6. timeout – This sets the read timeout value.
7. xonxoff – This enables software flow control.
8. rtscts – This enables hardware (RTS/CTS Modem lines) flow control.
9. dsrdtr – This enables hardware (DSR/DTR Modem lines) flow control.
10. write_timeout – This sets a write timeout value.
11. inner_byte_timeout – This sets the inter character timeout. It can be set to None to disable. It is disabled by default.

When a serial object is created with a port name given, the port is immediately opened. If the port is set to None, it needs to be opened using a successive call to the open() method.

serial.open() — This method opens a port. If the RTS and DTR lines of a modem are used, the state of rts and dtr can be applied using this method.

serial.close() — This method immediately closes a port. 

serial.__del__() — This method closes the port and destroys the serial object. 

serial.read() — This method reads size bytes from the serial port. If a timeout is applied, it may return fewer characters than requested. Without the timeout, it blocks the execution of a program until the requested number of bytes is read. In version 2.5 and above, the method returns the bytes when available; otherwise, it will return the complete string.  

serial.read_until(expected=LF, size=None) — This method reads serial data until an expected sequence (such as, line-break ‘\n’) is found, the size is exceeded, or there is timeout. 

serial.write() — This method writes byte data to the serial port (and the data should be the bytes type). This means the Unicode strings must be encoded by using the encode() method of str library. In version 2.5 and above, it will write the bytes or bytearray when available. Otherwise, it writes the str type. 

serial.readline(size) — This method has been provided via the io.IOBase.readline(). It reads and returns one line from the serial port. If a parameter size is specified, that size bytes are read from a line. 

serial.readlines(hint=-1) — This method has been provided via the io.IOBase.readlines(). This method reads and returns a list of lines from the serial port. The parameter hint can be specified to control the number of lines that are read.

serial.writelines(lines) — This method has been provided via the io.IOBase.writelines(). It writes a list of lines to the serial port. However, each line must have a line separator at the end (like newline character ‘\n’). 

serial.flush()— This method will flush file-like objects. It also makes the port wait until all of the data is written. 

serial.in_waiting() — This method returns the number of bytes in the received buffer. 

serial.out_waiting() — This method returns the number of bytes in the output buffer. 

serial.reset_input_buffer() — This method will flush the input buffer, discarding all of its content. It’s replaced the flushinput() method in the versions before 3.0.  

serial.reset_output_buffer() — This method clears the output buffer, aborting the output and discarding all of its content. For some USB serial adapters, this may only flush the buffer of the OS — and not all of the data that may be present in the USB port. It’s replaced the flushoutput() method in the versions before 3.0.  

serial.send_break(duration=0.25) — This method sends a BREAK condition. If the duration is specified (in seconds), the port returns to an idle state after that time period. It’s only possible to apply a break condition when the hardware flow control modem lines are used. 

serial.get_settings() — This method returns a dictionary with the port settings. The settings can be stored in a variable and later restored using the apply_settings() method. It’s replaced the getSettingsDict() method in the versions before 3.0.  

serial.apply_settings(d) — This method applies a dictionary that was created by the get_settings(). When a key is missing and the changes are applied, this means that the setting remains unchanged. It’s replaced the applySettingsDict() method in the versions before 3.0.  

The methods that are used in a Python script depend on the version of PySerial installed on the system. If the version is before 2.5, older methods may be used. However, if PySerial version 2.5 or above is installed, the new methods must be used. 

The PySerial library can be imported in a Python script using this code: import serial 

After importing the library in a script, various methods and attributes can be used to configure and execute serial communication over the UART protocol.

Recipe: Sending serial data from the RPi to the PC

In this recipe, we will send data from Raspberry Pi to a desktop computer.

Components required
1. Raspberry Pi 3/4 Model B x1
2. FTDI USB-to-serial converter x1
3. USB-to-USB cable x1
4. Female-to-female jumper wires

Circuit diagram

Circuit connections  

  • Connect the GPIO14(UART_TXD0, board pin number 8) to the Tx of USB-serial board
  • Connect the GPIO15 (UART_RXD0, Board pin number 10) to the Rx of USB-Serial board using jumper wires
  • Connect any one of RPi’s ground pins (such as board pin number 6) to the USB-serial board’s ground.
  • Connect the USB-serial board to the USB port of a desktop computer using a USB-to-USB cable.

Python script 1

 

How the project works
The Raspberry Pi and a desktop computer are connected via the USB-serial board. On RPi, a python script is used to send the serial data to the desktop computer. The script updates a counter value and sends it to the serial port. RPi is configured to use the serial TTL port for UART communication.

The sent data is passed as an 8-bit data chunk over the UART protocol at a baud rate of 9600 bps with no parity, one stop bit, and a timeout of one second. Each time a counter value is sent over the serial port, the message “Printed” is printed on the console (of Python IDLE) and the counter variable is increased by one.
On the desktop side, the Termite serial application is used on a Win32 system to receive serial data. The Termite will automatically detect the USB-serial device when it’s connected to the desktop computer (laptop) as COM22.

The UART settings are set to 9600 8N1 on the Termite, which are the same settings used in the Python script on Raspberry Pi.

Programming guide
The script begins by importing the serial and time library. A serial object is created using the serial.Serial() method with the port specified to /dev/ttyS0.

A counter variable “counter” is declared and initialized to 0. In an infinite while loop, the value of the counter is sent in a string by using the serial.write() method. The message “Printed” is printed on Python IDLE’s Console using the print() method. 

A delay of one second is given using the sleep() method and the value of the counter is increased by one. The loop will keep iterating until the script is forced to shut down from the console. 

import time
import serial
ser = serial.Serial(“/dev/ttyS0”, baudrate = 9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1)
counter=0
while 1:
ser.write(b’Write counter: %d \n’%(counter))
print(“Printed”)
time.sleep(1)
counter += 1

Demonstration video  

Recipe: Bidirectional serial communication
In this recipe, we will setup a bidirectional communication between a desktop computer and Raspberry Pi. When a message is sent from the computer to RPi’s serial port, it will send back the same message to the computer.

Components required
These are the same as in the previous recipe.

Circuit diagram
These are the same as in the previous recipe.

Circuit connections
These are the same as in the previous recipe.

Python Script 2


Python Script 3


How the project works
The Raspberry Pi and a desktop computer are connected via the USB-serial board. On the desktop side, the Termite serial application is used on a Win32 system to send and receive the serial data. The Termite automatically detects the USB-serial device when it’s connected to the desktop computer (laptop) as COM22. 

The UART settings are set to 9600 8N1 on the Termite, which are the same settings used in the Python script on RPi. From the Termite, we’ll send different messages (such as “Hello,” or “How r u?”) to RPi’s serial port. 

On Raspberry Pi, a python script is used to: 

Read the serial data at its serial hardware port

  •  Print that data to the console
  • Send the same data back to the desktop computer

RPi is configured to use the serial TTL port for UART communication. The sent data is passed as an 8-bit data chunk over the UART protocol at a baud rate of 9600 bps with no parity, one stop bit, and a timeout of one second. 

There are two scripts written for the same functions (i.e. to read data from the serial port, print it to console, and send the same message back through the serial port to the desktop computer). However, both scripts use different methods of PySerial library to execute these same functions. 

Programming guide   
Script 1 begins by importing the time, sleep, and the serial library. A serial object is created using the serial.Serial() method with the port specified to /dev/ttyS0.

In an infinite while loop, the serial data on the TTL port is read by using the readline() method. The read data is then printed to the console using the print() method. The same thing is then written through the serial port to the desktop computer by using the write() method.

import time
from time import sleep
import serial
ser = serial.Serial(“/dev/ttyS0”, baudrate = 9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1)
while 1:
    rx_data =ser.readline()
    print(rx_data)
    ser.write(rx_data)

Script 2 is similar to script 1, however, it uses the read() method to read the serial port data and waits for any data left using the inWaiting() method. Afterwards, it reads the left data using the read() method again.

The second script only differs in the way it reads the data from RPi’s serial port.

while 1:
    rx_data = ser.read()
    sleep(0.03)
    data_left = ser.inWaiting()
    rx_data += ser.read(data_left)
    print(rx_data)
    ser.write(rx_data) 

Demonstration video
>

Now, you can read and write data over Raspberry Pi’s serial hardware port.

In the next tutorial, we will learn how to interface SIM900A GSM-GPRS modem with it.  


Filed Under: Raspberry pi

 

Next Article

← Previous Article
Next Article →

Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

Submit a Guest Post

submit a guest post

EE TECH TOOLBOX

“ee
Tech Toolbox: Power Efficiency
Discover proven strategies for power conversion, wide bandgap devices, and motor control — balancing performance, cost, and sustainability across industrial, automotive, and IoT systems.

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions.

  • Can anyone please help me with this single board computer?
  • Anyone successfully communicated to the BlueNRG-M0 module on the B-L4S5I-IOT01A board
  • How to Build an Audio Tone Control?
  • Current version of LTspice not working on Windows 11?
  • Addressable Latch in My Logic Project

RSS Electro-Tech-Online.com Discussions

  • Measuring controller current output with a meter
  • KiCad custom symbol definition correct approach
  • restarting this Christmas project
  • Anyone In The US Ordered From AliExpress Recently?
  • My Advanced Realistic Humanoid Robots Project

Featured Tutorials

Real Time Hardware Filter Design

  • Practical implementation of bandpass and band reject filters
    Practical implementation of bandpass and band reject filters
  • Practical application of hardware filters with real-life examples
    Practical application of hardware filters with real-life examples
  • A filter design example
    A filter design example
  • Types of filter responses
    Types of filter responses
  • What are the two types of hardware filters?
    What are the two types of hardware filters?
  • What are hardware filters and their types?
    What are hardware filters and their types?
More Tutorials >

Recent Articles

  • Posifa sensors improve low-flow accuracy in compact systems
  • Acopian releases low-profile power supplies rated to 900 W
  • Octavo Systems OSDZU-3 REF Development Platform
  • Same Sky adds enclosure design to its audio engineering capabilities
  • Waterproof SMA-to-MHF I LK assemblies introduced by Amphenol RF

EE ENGINEERING TRAINING DAYS

engineering
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Sensor Series
      • 3D Printing
      • AI
      • ARDUINO Compatible Coding
      • Audio Electronics
      • Battery Management
      • Beginners Electronics Series
      • Brainwave
      • Digital electronics (DE)
      • Electric Vehicles
      • EMI/EMC/RFI
      • EVs
      • Hardware Filters
      • IoT tutorials
      • LoRa/LoRaWAN
      • Power Tutorials
      • Protocol
      • Python
      • RPI Python Programming
      • Sensors
      • USB
      • Thermal management
      • Verilog
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
  • Guest Post Guidelines
  • Advertise
  • Subscribe