Tooling Tuesday PySerial

Serial connections exist no matter what device you are using. So lets learn how we can make connections from two devices and read the data in Python.

So what is it?

PySerial is an easy to use Python library from Chris Liechti and it works with Python 3. It can enable our Python code to send and receive information over a serial connection.

So why should I be interested in Serial Connections?



Serial is one of the most basic ways to get data out of a computer and it has been used as such for decades. Your Raspberry Pi, Arduino, Windows PC all have serial connections that we can use to get data in and out of a device.

So how do I install PySerial

Via pip of course! Open a terminal / command line and type the following.

On Linux / osX

$ sudo pip3 install pyserial

On Windows

pip3.exe install pyserial

I want to read some data!



Lets say for example that we have an Arduino running that we want to get the data from and print using Python. This could be a simple as a temperature sensor.

On the Arduino we write the following code to print lines of information to the Serial Monitor. In this case it just prints the same sentence.

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

void loop() {
  Serial.println("Hey bigles wrote this for the Arduino\n");
  delay(1000);
}

We see this whizzing past in the Serial Monitor, but that is actually our Serial Port which for me was /dev/ttyACM0

How can I determine the correct serial port?

For an Arduino it is rather simple, as it tells us the port in the bottom right of the screen and we can also select the port from the Tools >> Port menu. But for other devices we need to be a little more of a detective. On Linux we can insert the device and then open a terminal then type dmesg to show the output and hopefully our device /dev/ttyXXX where XXX can be something like USB0 or ACM0 etc. On Windows insert the device and right click on the Windows start button and select Device Manager now look for the device in the list of devices. If not there look for COM ports and you should find it.

The Arduino is sending data over serial, but we have nothing listening for it...yet.

Listening for data

In your favourite Python 3 editor we shall write the code to listen for the data.

As always we start by importing the libraries that we wish to work with, these are PySerial and the sleep function from the time library.

import serial
from time import sleep

We now create an object called ser which acts as our connection to the serial port. In there we store the configuration to connect to a chosen serial port, in my case /dev/ACM0 for my Arduino. We then set the speed to 9600 bps, the same as we set in the Arduino code (Serial.begin(9600);) and then we set the timeout to 1 second just in case there is an error.

with serial.Serial('/dev/ttyACM0', 9600, timeout=1) as ser:

We now create a loop that will run our code forever.

    while True:

PySerial has a great function called readline() that does exactly that! We use the function to read a line from the serial port but we then wrap str() to convert the output from the serial port into a string. This is then saved as a variable called line.

        line = str(ser.readline())

The next step is to get the length of the string that we have received over serial. But why? Well when serial data is sent over it has some extra characters that are useful to serial, but useless to us.

They look something like this...

b'Working from a Gemma M0\r\n'

We need to know how long the string is so that we can trim it later. So we use len() to get the length of the string stored in the line variable. We then store that in another variable called length.

        length = len(line)

To get the data that we want from the string, we need to slice it! String slicing is handy as we can remove only the pieces of a string that we need.

To do this we use the print() function to print the output of our slice. We then call the line variable. But just after this we use [2: to start slicing the string from the third character in the string...but where do we end? Well as we know the length of the string we need to tinker with a little maths to find the correct amount of characters to remove. For example the Arduino serial output needs ~ two characters removing. but the Adafruit Gemma M0 (CircuitPython) needed five characters.

        print(line[2:(length-5)])

Lastly we use sleep to pause for one second every time the loop goes round.

        sleep(1)

Save and run the code!



You should now see the serial data whizzing along the Python shell of your editor, proving that we can communicate between devices.

Sending data from Python to an Arduino



We can do that!

The code in Python is a simple loop that will print some old school 1980s "woz ere" to the serial port.

Python code

import serial
from time import sleep
ser = serial.Serial('/dev/ttyACM0')
while True:
    ser.write(b'@biglesp woz ere')
    print("sending")
    sleep(1)

Arduino Code

String a;

void setup() {

Serial.begin(9600);

}

void loop() {

while(Serial.available()) {

a= Serial.readString();

Serial.println(a);

}

}

Happy Hacking!