Python/Serial port/pySerial

From Wikiversity
Jump to navigation Jump to search
Completion status: this resource has reached a high level of completion.

Objective

[edit | edit source]

This tutorial will guide you to work with the serial port on your PC by using pySerial library. This tutorial is specifically for anyone working with devices, i.e microcontrollers, PLC,... to communicate with PC via USB port, and intend to use a third party library to handle those connection. The Python programming skills required for this tutorial is very basic.

Hobbyist, Python starter and inexperienced developers who wish to communicate their PC with microcontroller boards, like Arduino Uno R3, STM32 dev-kit, Tiva C dev-kit,... via USB port may find this course useful.

This tutorial provides you the basic knowledge of simple operations on serial port, include:

  • View serial port information
  • Open and close the serial ports
  • Read operation: Receive data sent to the serial port
  • Write operation: Send data to the serial port

Introduction

[edit | edit source]

pySerial is a third party Python library to support working with the Serial port. PySerial is compatible with Windows, macOS, Linux, BSD and IronPython.

pySerial is a famous library, whose official Github named pyserial has more than 3.1k stars till July 2024.

To install pyserial:

pip install pyserial

View serial port information

[edit | edit source]

In your PC, plug in your micro-controller board or dev-kit which supports the UART-to-USB converter, e.g an Arduino Uno R3, to your USB port. On your Windows PC, if all drivers are well setup, it will appear as COM3. In Linux PC, like Ubuntun, it will appear as /dev/ttyUSB0.

[edit | edit source]
import serial

arduino_serial = serial.Serial('/dev/ttyUSB0', 9600) # /dev/ttyUSB0 on Linux PC; change it to your serial port
print(arduino_serial)

The result will be like:

Serial<id=0x7f4a1a876b70, open=True>(port='/dev/ttyUSB0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False)

In the program above, the serial port at /dev/ttyUSB0 is opened with the baudrate of 9600 bit/s. Also note that this program only works if the serial port at /dev/ttyUSB0 is plugged in at the time the program starts. Please change the serial port to your port name.

List of serial ports

[edit | edit source]

With multiple serial ports plugged into your PC, to get that list:

import serial.tools.list_ports

print(serial.tools.list_ports.comports())

The result will be like:

[<serial.tools.list_ports_common.ListPortInfo object at 0x00000239241BFDC8>, <serial.tools.list_ports_common.ListPortInfo object at 0x0000023924215F88>]

To get their specific information:

import serial.tools.list_ports

ports = serial.tools.list_ports.comports()

for port, desc, hwid in sorted(ports):
    print("{}: {} [{}]".format(port, desc, hwid))

The result will be like:

COM1: Communications Port (COM1) [ACPI\PNP0501\0]
COM4: Arduino Uno (COM4) [USB VID:PID=2341:0043 SER=854353331313514082D1 LOCATION=1-11]

To get the serial port name only:

import serial.tools.list_ports

port_array = []

def display_serial_ports():
    ports = serial.tools.list_ports.comports()
    for port in ports:
        port_array.append(port.device)
    return port_array   

print(display_serial_ports())

The result will be like:

['COM1', 'COM4']

Open and close the serial ports

[edit | edit source]

Open the serial port

import serial

serialObject = serial.Serial()
serialObject.port = "/dev/ttyUSB0"

serialObject.open() # Open port

# Check whether serialObject is opened
print(serialObject.is_open) # true: if opened before, false: if not opened before

Close the serial port immediately

arduino_serial = serial.Serial('/dev/ttyUSB0', 9600)

arduino_serial.close()

Receive data sent to the serial port

[edit | edit source]

PC, as the receiver, receives the data sent from a device as the transmitter, e.g an Arduino Uno R3, to the PC's serial port:

import serial

arduino_serial = serial.Serial('/dev/ttyUSB0', 9600)

while True:
    serial_receive = arduino_serial.readline()
    print(serial_receive)

Suppose that the data sent from the device is string "Hello, World !" for an interval of time inside an infinite loop, the received data will be:

b'Hello, World !\r\n'
b'Hello, World !\r\n'
b'Hello, World !\r\n'

The "b" appears as pySerial receives those value of bytes data type. To "parse" the received string, i.e to remove the "b":

serial_receive = arduino_serial.readline().decode('ascii')

The result will then be:

Hello, World!

Hello, World!

Hello, World!

Send data to the serial port

[edit | edit source]

PC, as the transmitter, sends data to a device as a receiver, e.g an Arduino Uno R3, via the serial port:

import serial
import time
arduino_serial = serial.Serial('/dev/ttyUSB0', 9600)

while True:
  arduino_serial.write(b"Hello, World !\n")
  time.sleep(1) # Send the string for every 1 second

From the receiver side which has setup its baudrate to be 9600, it will receive the string "Hello, World !" sent from the PC.

Assignment

[edit | edit source]

Two-way communication between master and slave

[edit | edit source]

The following master program (which runs on your PC) will wait until the slave sends a character "R" to it. After receiving the "R" character, it will start sending a string with a count up value to the slave

# master.py
import serial
import time

arduino_serial = serial.Serial('/dev/ttyUSB0',9600)
count = 0

while True:
    serial_receive = arduino_serial.read(1)
    # print(serial_receive)
    if serial_receive.decode() == "R":
        arduino_serial.write(b"Hello, World: " + str(count).encode() + b"\r")
        count += 1

Your assignment is to write the slave program in your slave device to communicate with the master. Your slave device can be microcontroller like Arduino - ATmega family, STM family, Tiva C,... or single board computer like Raspberry Pi, Beagle Bone,...

Python serial port communication without pySerial library

[edit | edit source]

A follow up question for developers and students who want to deep into serial communication is to write your own program using only the Python built-in API for serial port communication. This will all the operations we have gone through above, especially the serial port communication between the PC and the external devices.

Those who don't want to go deep into low-level programming with Python can skip this assignment.

Conclusion

[edit | edit source]

Congratulation ! You have reached the end of the tutorial. The tutorial is very basic for hobbyist and inexperience developers who will gain enough basic knowledge with pyserial to work on their hobbyist or simple projects. Hobbyist will need to investigate more on the pyserial API based on their project features. Anyone who works on the serial communication between PC and microcontrollers or single board computer are required to complete the Two-way communication between master and slave assignment as this is an important problem met in almost every communication system.

External links

[edit | edit source]