Saturday, March 11, 2017

Serial Communication in Raspberry Pi Using Python

This is the fourth part of our Raspberry Pi tutorial series, in this post i will show you, how to use Serial Communication in Raspberry Pi using Python programming language. The following are the links to the previous tutorials on the Raspberry Pi.
Serial Communication is one of the most important type of communication for Embedded Engineers, as it is simple as compared to other types of communication and most of the embedded devices still use this communication and that's why to connect these devices with Raspberry Pi, serial communication is must. Using serial communication in Raspberry Pi is little bit tricky, but after this tutorial you will be able to successfully use Serial Communication in Raspberry Pi using Python programming language.

You can watch the following video or follow the steps given below.




Install PySerial Package
I don't know whether PySerial package is pre-installed or not with the Rasbian OS, but in my case it was not installed as i am using the Lite version of Raspbian OS, so our first step is to install the PySerial package, and then using the API's present in this package, we will send and receive data from Raspberry Pi to our Windows 10 PC, the connection diagram is shown below.
Connection Diagram
If your Raspberry Pi is connected with internet then use the following command in LXTerminal to install the PySerial library for Python.

sudo apt-get install python-serial

And in case you don't have working internet connection on Raspberry Pi, then you can download the PySerial package by clicking here, on Windows/Linux/Mac platforms and then copy these files into your Raspberry Pi, and then by using LXTerminal go to the directory where you have copied the files and after that use the following command to install the PySerial package.

sudo python setup.py install

So after this stage we have PySerial package installed and now we can proceed with writing the simple program for serial read and write operations, but before that we have to enable the Serial communication in Raspberry Pi, which is disabled by default.

Configuring Raspberry Pi for Serial Communication
There are two ways to do this, one is with Advanced Serial Setting in raspi-config and another is by editing the config.txt file, present in the boot directory of Raspberry Pi file system. Use the following command in LXTerminal to open the config.txt file using nano editor.

cd /boot
sudo nano config.txt
Configuration File
After using the above command, config.txt file will get opened in nano editor, and now you have to search for the following line.

enable_uart = 0

To enable serial communication, update the value from zero to one.

enable_uart = 1

After completing this step, save the config.txt file and reboot your Raspberry Pi, and we will write the Python program for serial communication using Raspberry Pi.
Note: If this line is not present in your config.txt file, then manually add this line and set the value to one.

Writing Program
The Python program for serial communication is as follow:
Save the above program in a file with any name, just make sure that it is a python file with extension *.py and after this connect your Raspberry Pi with USB to TTL converter and open the communication port on PC using any serial terminal PC application, like I am using HW Hercules, after running this script you will see the following data on HW Hercules running on PC, and if you type anything of HW Hercules terminal, it will be displayed on Raspberry Pi, character by character.
Serial Communication Using RPi Program Output
I hope you guys like this post, the program is simple and self-explanatory, but still, if anyone faces any problem just drop a comment below in the comment box or mail me directly, I will try to help you as soon as possible.

20 comments:

  1. Traceback (most recent call last):
    File "serial_new.py", line 2, in
    import serial
    File "/home/pi/My_Prog/serial.py", line 4, in
    ser = serial.Serial("/dev/ttyAMA0") #Open named port

    ReplyDelete
    Replies
    1. On Raspberry Pi you shouldn't get this error.
      Are you using RPi???
      Or you are on Linux or Windows Platform???

      Delete
    2. I am using BeaglBoneBlack following same as your way but iam not getting any values from the hercules serial communication so please help me

      Delete
    3. Since it is written in Python, it should work on all platforms.
      I don't have any idea about Beagle Bone board, but i suggest you yo check if uart is enabled on this board or not.

      Delete
  2. Hi. Thank you very much for this great tutorial.
    Currently, I am trying to read data from some Serial Ultrasonic Device, which is connected to a Raspberry Pi.
    The US device is sending data via serial connection, but unfortunately, no data is listed by the script shown above.
    Could you give me a hint, what I am doing wrong?
    Thank you very much.
    Thomas

    ReplyDelete
  3. This code does not work at all. I know that my serial cable, Raspberry Pi Zero, and Hercules are all operating properly because I can log into my Pi on startup with the standard 115,200 baudrate over a serial connection in Hercules. When I run the above code, no errors are given. It simply hangs on the write command. I've tried countless other Python scripts to no avail, they all seem to hang on write. Perhaps there's a bug in the current version of PySerial (3.2.1-1).

    ReplyDelete
    Replies
    1. I searched for your problem on google and saw various posts with solution.
      One such post is at
      https://github.com/pyserial/pyserial/issues/71

      Please use google and i am sure that you will be able to solve your problem.

      Delete
    2. It could be because the port definition. Depending on your raspberry pi version you should use one port or another. For example I have got raspi3 and I connected wires to GPIO uart, so my port is /dev/ttyS0
      also the version of your serial library tells you if you should use inWaiting() or in_waiting()

      Delete
  4. could you please inform me on which version of python and pyserial was used to create run script on this tutorial? Currrently trying to do serial communication from windows putty to raspberry pi 3 running python 3.5.3. any info would be much appreciated.

    ReplyDelete
    Replies
    1. I think it was 3.6 version of Python.
      What is the problem you are facing..

      Delete
    2. Thank you for responding. The problem I'm having is when I'm transmitting ser.write (or ser.readline) data to a terminal emulator it translates to unreadable characters on the terminal emulator(garbage data). I have verified my port settings on both my script setup and terminal emulator to make sure they match. i can only write with a byterarry function ex. x= ser.write(b'hello') I've also tried encoding my ser.write .encode('utf-8') with no luck.

      Also i have verified that i have correctly configured uart setting made from the CL. I even tried using a USB to serial adapter and changed my port settings correctly.

      Ive used you script and also played around with multiple variations of my own ex:

      import serial
      import time
      from time import sleep

      ser = serial.Serial(port='/dev/ttyUSB0',
      baudrate=115200,
      parity=serial.PARITY_NONE,
      stopbits=serial.STOPBITS_ONE,
      bytesize=serial.EIGHTBITS,
      timeout=1)



      while True:

      x= ser.readline()
      print(x)

      ser.write(b'hello')
      sleep(1)

      Any input would we much appreciated.Currently using python 3.5.3

      Delete
    3. I don't think that there is a special need to write a post for Python 3.5.3, I believe the same code shall run.
      Regarding the unreadable characters which you are talking about, I can think of only two possibilities.
      1) Mismatch in Baud Rate Setting, this is common cause of the problem, you must have same baud rate at both the ends.
      2) Cheap Chinese USB to TTL Converters, they can also be a problem at times, I have faces the issue with one of the adapter, so please use a different one.
      Sorry I can't think of any other solution at this time.

      Delete
  5. Hello, I am using your code as a basis for understanding some serial port usage. I can't seem to figure out why a variable won't work.

    I have..
    var = raw_input("Enter string")
    ser.write(var)

    This seems so basic, but I can't find an answer as to what is wrong. Python 3 shows to use .encode(), but Python 2 appears as if it should work as is.


    Thank you for any help

    ReplyDelete
  6. you can ignore that last submission.. I figured it out. Using a tiny portable keyboard with a screen that is too far away leads to random unseeable typos.... :/.

    Thank you for the code lesson though.

    ReplyDelete
  7. Hello.
    When I run the program, the data sent by my Rpi3 just appear in the terminal window and doesn't appear in Hercules, how can I fix it?

    ReplyDelete
    Replies
    1. Hi Kevin,
      In the above program, the RPi transmit the data only at the starting of the program, after that it waits continuously in while and wait for the data coming from PC over serial port, and once a byte is received, it is displayed on the terminal.
      If you are using the same program, then I think you didn't enabled the Local Echo mode in Hercules. Please check the video also.

      And if you have modified the program, then share your program at matlab.academy@gmail.com
      I will check it and reply you over email.

      Delete
  8. Hi may i know if i read the data via this way using Serial.read, the data i get will be in a byte form or what. For example, i want to use that data and use it. Like ( datagetfrompyserial > 30)....Can i do that or i need to decode it before use?

    ReplyDelete
  9. Hi, I just wanted to say thanks for this. I'm new to python, but took it a few steps further to add http post, and text logging.
    https://github.com/vrdriver/Serial-PI-thon/blob/master/data_reader.py
    Cheers! Steve

    ReplyDelete
  10. hi, thanks for you post it was great tutorial.
    I have two usb serial converter and two absolute encoders connected to the rasperry. I can read the data transferred from one usb, but I don't understand how to read two ports in the same time Can you please help me

    ReplyDelete