November 23, 2024

Arduino-Python Serial Communication Interface Using pySerial in Windows

In this Python and Arduino tutorial, we explain how to properly develop a serial communication interface between a computer running a Python script and an Arduino microcontroller. In particular, we explain how to send and receive back number and string messages between a computer running a Python script and an Arduino program. This tutorial is developed for a Windows operating system. In our next tutorial, we will explain how to establish the communication interface in a Linux Ubuntu operating system.

The material and concepts that we explain in this tutorial are extremely important for robotics, mechatronics, and control engineering students and professionals. For example, you can use the ideas explained in this tutorial to develop your own serial communication interface between a PC computer or a Raspberry Pi running ROS2 and Arduino boards. In this way, you can use Arduino as a low-level microcontroller that will control motors and read sensor information and that will be integrated in the ROS2 environment. The YouTube video accompanying this post is given below.

Install pySerial library

This tutorial is based on the pySerial library. The documentation page of this library is given here. We can install this library by opening a terminal (or Anaconda base terminal) and by typing

pip install pyserial

Example 1 – How to Send and Receive Back Integer Messages

The idea of this example is to teach you how to send and receive back integer messages between Python and Arduino. We cannot directly send integer messages. Instead, on the Python side, we need to convert integers to strings and then to bytes, and then we can send the messages through the Serial communication port.

The first part of the code of Example 1 is given below:


# Demonstration of Computer-Arduino communication interface
# by using the pySerial library
# this code explains how to send integer messages to Arduino 
# and receive back modified integer messages 
# Second example

# Author: Aleksandar Haber

# import pySerial
import serial 
# time library for introducing delays
import time

# this is necessary for listing all the port
from serial.tools.list_ports import comports


# printing the port information
for portItem in comports():
    print(portItem)

# adjust the proper port, 
# in my case it is COM6    
arduinoSerial = serial.Serial(port='COM6', 
                              baudrate=115200, 
                              timeout=.5)

# check if the port is opened
arduinoSerial.is_open

# close the port
arduinoSerial.close()

First, this code will import the necessary libraries, and it will use “comports()” to list all the available serial communication ports. In our case, the Arduino microcontroller is attached to the communication port 6. Then, by using serial.Serial() function we define the serial communication object. We specify the port number, baudrate, and timeout. It should be kept in mind that the baudrate should be equal to the baudrate of the Arduino Serial communication object. At the end, we close the serial communication port. This is necessary in order to upload the Arduino code.

After uploading the Arduino code (it will be explained later on), we can execute the second part of the code given below.

# Type Arduino code, and upload the Arduino code

# open the port 
arduinoSerial.open()

# integer to send
numberToSend=423
# convert integer to string
stringConverted=str(numberToSend)
# write the message 
arduinoSerial.write(bytes(stringConverted, 'utf-8'))

# wait for Arduino to process the message
time.sleep(0.01)
# read the message that is available on the Serial port
readLine = arduinoSerial.readline() 

# convert the Byte message to string
stringLine=readLine.decode("utf-8")

# convert string to integer
receivedInteger=int(stringLine)

print(receivedInteger)

# close the port
arduinoSerial.close()

By using arduinoSerial.open() we reopen the communication port. Then, we define an integer number, denoted by numberToSend , that we want to send. After that, we convert the integer number to a string, and then we use the function “arduinoSerial.write()” to actually send the message. Note that the string is converted to Bytes in order to properly send it. After that, we wait for a short time interval for Arduino to process the message. The Arduino code will receive the message, convert the message to an integer value, and then increase the integer. After that, it will send back the increased integer. By using readLine = arduinoSerial.readline(), we read the message coming from Arduino. Then, we convert the message to an integer, and we print the received integer. Finally, we close the communication port.

The Arduino code is given below.

// Arduino-(Python) Computer Serial Communication Interface
// Author: Aleksandar Haber 
// Second Example
// this is the integer number
int number1;
// this is the received string
String receivedString;
// this is the integer that will be sent back 
String sendBackInteger;

void setup() {
  // put your setup code here, to run once:
  // the baud rate should match the baud rate in the Python file
  Serial.begin(115200);

}

void loop() {
  // this while loop will run until something appears at the Serial communication channel
  while(Serial.available()==0);
  
  // read the string from the communication channel
  receivedString=Serial.readString();

  // convert string to integer
  number1=receivedString.toInt();

  // perform an operation on the received integer 
  number1=number1+100;
   
  // convert the integer to a string that will be sent back
  sendBackInteger=String(number1);

  // print the message to the Serial port - this will be sent back to the computer
  Serial.print(sendBackInteger);
  
}

After defining the Serial communication object in the Setup function, in the loop function, we use an infinite while loop to wait until a message is available on the Serial communication port. After that, we read the message by using “Serial.readString()” and we use the function “receivedString.toInt()” to convert the message to an integer value. After that we increase the received integer, and then we use “String(number1)” to convert it to a string value. Finally, we use “Serial.print(sendBackInteger)” to send back the increased integer.

Example 2 – How to Send and Receive Back String Messages

In the sequel, we give the second example demonstrating the serial communication interface between a Python script running on a PC host computer and Arduino. The working principle of the second example is similar to the first example, and we just present the code.

Python code:

# Demonstration of Computer-Arduino communication interface
# by using the pySerial library
# this code explains how to send string messages to Arduino 
# and receive back string messages 

# Author: Aleksandar Haber

# import pySerial
import serial 
# time library for introducing delays
import time

# this is necessary for listing all the port
from serial.tools.list_ports import comports


# printing the port information
for portItem in comports():
    print(portItem)

# adjust the proper port, 
# in my case it is COM6    
arduinoSerial = serial.Serial(port='COM6', 
                              baudrate=115200, 
                              timeout=.5)

# check if the port is opened
arduinoSerial.is_open

# close the port
arduinoSerial.close()

# Type Arduino code, and upload the Arduino code

# open the port 
arduinoSerial.open()


# write the message 
arduinoSerial.write(bytes('Hello World', 'utf-8'))

# wait for Arduino to process the message
time.sleep(0.01)
# read the message that is available on the Serial port
readLine = arduinoSerial.readline() 

# convert the Byte message to string
stringLine=readLine.decode("utf-8")

print(stringLine)
# close the port
arduinoSerial.close()



Arduino code

// Arduino-(Python) Computer Serial Communication Interface
// Author: Aleksandar Haber
// First Example

// this is the string we want to fill-in and send back
String stringPrint;

void setup() {
  // put your setup code here, to run once:
  // the baud rate should match the baud rate in the Python file
  Serial.begin(115200);

}

void loop() {
  // this while loop will run until something appears at the Serial communication channel
  while(Serial.available()==0);
  
  // read the string from the communication channel
  stringPrint=Serial.readString();

  // print the message to the Serial port - this will be sent back to the computer
  Serial.print("I received: "+stringPrint);
  
}