This article discusses how to read data from serial ports using serial.read() and serial.readline() functions on the pyserial library. Before we do that, however, let us cover some prerequisites.
Prerequisites
We must take care of two things before interacting with serial ports on your device.
First of all, we need to install the Python library to use. The package is called pyserial, which can be installed from the PyPI repository using pip by running the command:
pip install pyserial
Secondly, we need to identify the serial ports available on the device. We can do this using serial.tools (which is part of the pyserial library but needs to be imported separately). The serial device name can then be found using the .device method. Here is the code.
1 2 3 4 5 6 7 8 9 |
# import function import serial.tools.list_ports # Get the list of all serial ports available ports = list(serial.tools.list_ports.comports()) for p in ports: # Loop through the instances and get the ports and device name. print(p) print(p.device) |
Output:
COM3 - Intel(R) Active Management Technology - SOL (COM3) COM3
You can also run serial.tools.list_ports as a module to get the list of serial ports. That can be done by running the following line on the command line.
1 |
python -m serial.tools.list_ports |
You can also locate serial devices outside Python. If you are working with Linux or Mac, serial ports are named /dev/tty*, whereas on Windows, the ports are located on the Ports item on Devices Manager (Go to Start and search for “Device Manager” and find the Ports on the list).
Reading Data from a Serial Port
Once you have identified the active ports, we can choose the one we want to read from. Let’s assume we want to read from COM4 serial port using read() and readline() functions.
Reading serial device using serial.read()
Let’s see an example with comments to break down each line.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import serial # Path to the serial device. serial_port = "COM3" ser = serial.Serial( # Serial port to read the data from port=serial_port, # Rate at which the information is shared to the communication channel # 9600 means sharing 9600 bits per second, approximately 960 bytes per second. baudrate=9600, # Total number of bits to be read bytesize=serial.EIGHTBITS, # Number of serial commands to accept before timing out timeout=1, ) # Print the port name print("Connected to the port: ", ser.name) # Pause the program for 1 second to avoid overworking the serial port while True: x = ser.read() # returns 1 byte at a time print(x) # close the serial instance. ser.close() |
The timeout argument in serial.Serial() is set to 1 in the code above. That means that ser.read() will be timed out after 1 second and returns bytes that have been fetched until then.
If we set timeout=None, then the ser.read() will wait forever/until the requested bytes of data is retrieved. You can request a specific number of bytes by changing the line x=ser.read() into something like this to fetch 8 bytes:
1 |
x = ser.read(size=8) |
You can also use serial object as a context manager as follows.
1 2 3 4 5 6 7 |
import serial with serial.Serial("/dev/ttyS0", 9600, timeout=8) as ser: x = ser.read() # read one byte print(x) s = ser.read(size=10) print(s) # read up to ten bytes or stop at timeout. |
Using serial.readline() to read information from a serial port
If you are sure that each data piece is terminated with the End of Line character (EOL), you can use serial.readline() to read all bytes until the data piece is terminated by EOL. The new line character “\n” is the default EOL in the pyserial library.
If data coming in does not have proper EOL character, serial.readline() may run without terminating if a timeout value is not provided.
“Be careful when using readline(). Do specify a timeout when opening the serial port otherwise, it could block forever if no newline character is received. Also, note that readlines() only work with a timeout. readlines() depends on having a timeout and interprets that as EOF (end of file).” – Source: documentation.
1 2 3 4 5 6 7 8 9 10 11 |
import serial # Initialize serial object ser = serial.Serial(port="/dev/ttyS1", baudrate=9600, timeout=10) with True: # Fetch bytes until the EOL character is encountered info = ser.readline() # Decode incoming bytes - from bytes to string. data = info.decode("utf-8") # Print deconded income data. print(data) |
The ser.readline() returns all bytes before the EOL character or until timeout. You can increase timeout if you have a slower baud rate or if many bytes in a single data piece are coming before the EOL character.
Conclusion
This article covered how to read data from serial ports on the device. The first step, as shown in the guide’s first section, is to identify the serial port you want to read and then read the data from it either using serial.read() or serial.readline() functions.
By default, the serial.read() function reads one byte at a time until the process is timed out. On the other hand, serial.readline() reads multiple bytes until EOL is encountered or the reading process is timed out.