Consider this scenario that we have to build a monitoring system for a solar power plant. To ensure optimal performance, we need to monitor critical data such as power generation and environmental conditions. The data is being generated by various sensors and control devices deployed throughout the facility. However, we need to find a way to communicate with those sensors using the Python-based control software. Fortunately, pySerial can help us overcome this challenge by establishing UART serial communication channels to communicate with our control devices.
In this Answer, we’ll explore the key features and functionalities of pySerial, starting with the basics of finding available system ports. We’ll then delve into the process of initiating a serial port connection, configuring essential parameters like baud rate and data bits, and finally, communicating seamlessly over the channel. Additionally, we’ll uncover other useful controls and attributes that pySerial offers, providing you with a comprehensive guide to mastering serial communication with Python.
Note: If you want to learn more about UART serial communication protocol, see this Answer on our platform.
The pySerial is a Python library that allows us to establish serial communication channels on Windows, Linux, and OSX. It supports various baud rates, and its APIs make serial channel communication intuitive.
The first and foremost requirement to establish a serial communication channel is a physical port on the system. Initially, serial communication required DB9 connectors, but that is not a restriction now. Serial communication channels can also be established using Ethernet or USB connections. No matter the connection type, there is always a port number associated with it. To find all the available connections that can establish serial communication channels, we can use the tools.list_ports
module provided by pySerial.
import serialimport serial.tools.list_ports as portsp_list = ports.comports()for i in p_list:print(i.name)
Line 4: Fetch the list of objects containing individual port information.
Line 6–7: Loop over the list of objects and print the name attribute from each object.
We need to supply the communication port number, baud rate, and data packet parameters to initialize a serial communication channel. The pySerial has default values for the baud rate and the data packet composition parameters, and we can instantiate a serial port by only supplying the port name as a string..
import serials = serial.Serial('Port name')
With this basic setup, all other values are set to default. These values can easily be modified using simple API commands.
Baud rate: The default value of the baud rate set by pySerial is 9600 and can be modified by changing the baudrate
object’s attribute. The pySerial supports a long list of baud rates up to BAUDRATES
attribute of the Serial
object.
import serialimport serial.tools.list_ports as portsp_list = ports.comports()for i in p_list:print(i.name)
Data bits: The default value of the data bits set by pySerial is EIGHTBIS
(8 bits) and can be modified by changing the bytesize
attribute of the serial.Serial
object. Supported data bits numbers in pySerial are FIVEBITS
, SIXBITS
, SEVENBITS
, and EIGHTBITS
.
s.bytesize = SIXBITS
s.parity = PARITY_NONE
Stop bits: The default number of parity bits set by pySerial is STOPBITS_ONE
and can be modified by changing the stopbits
attribute of the serial.Serial
object. The pySerial supports a long list of baud rates up to stopbits
attribute supported by pySerial are STOPBITS_ONE
, STOPBITS_ONE_POINT_FIVE
, and STOPBITS_TWO
.
s.stopbits = STOPBITS_ONE
Note: We don’t need to change the number of start bits as there is always a single start bit. No other options are available.
A serial communication channel has two communication attributes: read (to get data) and write (to send data).
The read()
function in pySerial takes the number of bytes (or data packets) to be read from the port in integer format. When a data packet is received and processed by a system, all the bits other than the data bits are discarded, and all we get are the bytes of data as the output of the read()
function. The number of bits in every byte will be determined by the bytesize
attribute of the pySerial object.
num_bytes = 10data = s.read(num_bytes)
The write()
function in pySerial takes the data to send as its input. It also returns the number of bytes sent through the channel.
data = 47s.write(data)
Data is continuously being pumped in whether we read it or not, and is temporarily stored in a FIFO buffer until we access it using the read()
function. Similarly, if the channel is receiving data faster than it can transmit it, it’ll be temporarily stored in a FIFO buffer as well. The pySerial provides us the following commands to manage these buffers according to our needs:
in_waiting: The number of bytes available in the input buffer.
out_waiting: Contains the number of bytes available in the output buffer.
reset_input_buffer(): This function flushes all the data in the input buffer. This option can prove useful to remove any lag in communication at the expense of some data.
reset_output_buffer(): This function flushes all the data in the output buffer. This option can prove useful to remove any lag in communication at the expense of some data.
set_buffer_size(): This function takes the buffer size as input and can be used to change the size of the input buffer. The default buffer size pySerial sets is 4096 KB but can be set to any value below
Serial communication is crucial in various technological applications. The pySerial is a powerful tool for seamless communication across multiple platforms. It allows us to identify system ports, initiate serial port connections, fine-tune parameters, and enable smooth data transfer. The pySerial simplifies the complexities of serial communication, making it a valuable tool for connecting Python applications to external devices.
Free Resources