IMG_1439

Plotting real-time data from Arduino using Python

Arduino is fantastic as an intermediary between your computer and a raw electronic circuit. Using the serial interface, you can retrieve information from sensors attached to your Arduino. (You can also send information via the serial interface to actuate circuits and devices (LEDs, relays, servos, etc.) connected to your Arduino.) Once you have the data in your computer, you can do all sorts of things with it – analyze it, display it, or share it on the internet, for instance.

In this post, I will be reading and displaying analog data from a pair of LDRs connected to an Arduino. Here is the schematic:

IMG_1443

Here is how you hook it up to the Arduino:

IMG_1439

The Arduino sketch is very simple – it just reads the values from analog pins A0 and A1 (in the range [0, 1023]) and prints it to the serial port. Here is the code:

The serial port sends values in the format:

512 300
513 280
400 200
...

On the computer side, I need to read these values, and plot them as a function of time. I am using Python and the Matplotlib library for this. I wanted to display this as a scrolling graph that moves to the right as data keeps coming in. For that, I am using the Python deque class to keep and update a fixed number of data points for each time frame.

You can see the full implementation here:

UPDATE: I have upgraded the code below to use the matplotlib animation class. You can still get to the old code here.

And here is what the plot looks like. It scrolls to the right as data keeps coming in.

plot

37 thoughts on “Plotting real-time data from Arduino using Python”

  1. Hello! I can use this code to plot an signal acquired at 1000Hz with Arduino Uno?
    Greetings from Brazil

  2. At 1000Hz, assuming you are sending binary data of 4 bytes (1 float) for a single Y axis, that’s 4000 bytes per second sent to your python code.

    I am now sending around 10 bytes (ascii) every 50 ms – so that’s 200 bytes per second.

    I don’t think you can increase the refresh rate much more on the Python end because of bottleneck in updating matplotlib. If you need more speed in updating here are some options:

    1. Filter your data to reduce the number of samples sent per second.

    2. I think you can improve the refresh rate of matplotlib using a timer. Take a look at:

    http://hardsoftlucid.wordpress.com/various-stuff/realtime-plotting/

    3. Take a look at pyqtgraph:

    http://pyqtgraph.org/

    4. Consider plotting data yourself using something like OpenGL.

    Regards

  3. Great post!
    I’m new to programming in python and I’m learning by examples.
    I’m trying to run your script, but I get an error!
    The program goes to print “Example usage: python showdata.py” / dev/tty.usbmodem411 “and gives the message to kill him.
    You can take a my doubt?
    I’m on a Windows system and to identify the serial port on this scrip must modify “sys.argv [1];” (line 62: strPort = sys.argv [1];). Right?
    Because it has port identification! And arriving port values ​​are converted to the string “sys.argv”. Right?
    The problem is how to do!
    I don’t understand how to write this modification.

    Sorry my bad English.

  4. Oh thanks for replying so fast!
    And sorry not to have responded to their response before!!!
    When testing I commented:
    .
    .
    .
       # expects 1 arg – serial port string
       # if (len (sys.argv) != 2)
       # print ‘Example usage: python showdata.py “/ dev/tty.usbmodem411″‘
       # exit (1)
    .
    .
    .
    and replace “sys.argv” on line 71 (ser = serial.Serial (‘COM3′, 9600) opened a window but showed nothing! Starting an infinite loop to execultar the script!
    Because of that I thought I would need to modify the “sys.argv”!

  5. I did the tests and everything went well!
    I ran other scripts and I had no problem. To confirm tested it on another machine and had no problem also.

  6. Got a positive response and two negative!
    To make sure it was not a problem with the operating system reinstalled and tested!
    I connected a 10K potentiometer in my arduino due and tested to changes in the python script again.
    I commented part of the script (again) and added a print within “While True” before “except:” to know if him is being read.
    I get the print that I entered, but the graph window is still blank and the chart title appears (unanswered).
    When I disconnected / connected the arduino from usb arose a problem! Disappeared serial port “COM3″, but in the Windows Device Manager appears connected to the Arduino “COM3″ port. I could only see the “COM3″ after I connected the arduino on another machine and went back to connect on the first machine.

  7. The post “Plotting Data in Arduino IPython Notebook” at address (http://nbviewer.ipython.org/gist/damontallen/5721739) is yours?
    The script has modifications, in relation to this page, you know what the meaning of “!” on:
    .
    .
    # Run prior to plugging in the Arduino
    pre_list =! ls/dev/tty *
    .
    .
    It’s just to score? Or have some meaning for python on linux?

    The “/dev/tty *” refers to the door which the arduino is connected in linux, to adapt to the syntax in Windows how I should change! The question is how to reference the “com_”? It is a basic question but I can’t find much information on the internet.
    Thanks for all help!

    Sorry my bad English.

  8. Ohh … Chief

    Now I know what is problem when running this code on Windows!
    It’s own WINDOWS (XP, Started, 7)!
    Is related to windows insist on working with pythonw.exe (prevents pop up windows) to inves python.exe!
    I haven’t found a satisfactory answer to this question!!!

    For those who want to work with arduino and python on windows (even with the bugs) I leave some tips:

    1° Do not operate Pythonxy! Install what you really need.
    2° Install Python (preferably python 2.X) and for each version of python2.X install packages with longer working (not the newest): matplotlib, numpy, pyserial.
    3° Have lots of patience!!!It will work but not always!

    I will no longer insist on working with Windows!
    I want to avoid anger and stress!!

    Chief … to work with the graph in full screen I have to insert some command? Both in Linux and Windows I can’t maximize the graph window.
    This should really happen?

    Thanks for your help!

  9. Hi,

    I have a problem.
    I am using your code to plot the serial analog output of a temperature measurement circuit with an Arduino Uno. So far it works. I was able to grab the data from the serial port and plot it with your code. However I cannot do anything without freezing the plot window.
    If I just click on the window it freezes. if I move the window it freezes.

    I tried to deactivate the plotting and just give out the readings in the terminal window. That works fine without any problems. So I think It is just somehow connected to the GUI.

    Have you heard about that problem?

    THX
    John

  10. Hi,

    yeah, thanks. When I run that code that you stated the window is stable and I can adjust things.

    The tricky part for me now is the transfer to your code. ;)

    Thanks!

  11. By the way: Do you happen to know why I don’t see any window if I run the code on my Mac? I only see the data being output in the terminal window.

  12. cool, thanks!

    I get the error

    ” File “showdata.py”, line 21
    def __init__(self, strPort, maxLen):
    ^
    IndentationError: expected an indented block”

    I don’t get what’s wrong?!

    1. I think you may be copying it wrong – white space matters in Python, unlike C++, Java, etc.

      Click on the “view raw” button to the bottom right of the github code snippet above. Then save the page as a python file, and try again.

  13. hello chief, can you help me. I get wrong message like this :
    Python 2.7.3 (default, Mar 18 2014, 05:13:23)
    [GCC 4.6.3] on linux2
    Type “copyright”, “credits” or “license()” for more information.
    >>> ================================ RESTART ================================
    >>>
    usage: showdataupdate.py [-h] –port PORT
    showdataupdate.py: error: argument –port is required

    Traceback (most recent call last):
    File “/home/pi/Desktop/ical/showdataupdate.py”, line 105, in
    main()
    File “/home/pi/Desktop/ical/showdataupdate.py”, line 73, in main
    args = parser.parse_args()
    File “/usr/lib/python2.7/argparse.py”, line 1688, in parse_args
    args, argv = self.parse_known_args(args, namespace)
    File “/usr/lib/python2.7/argparse.py”, line 1723, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
    File “/usr/lib/python2.7/argparse.py”, line 1947, in _parse_known_args
    self.error(_(‘argument %s is required’) % name)
    File “/usr/lib/python2.7/argparse.py”, line 2353, in error
    self.exit(2, _(‘%s: error: %s\n’) % (self.prog, message))
    File “/usr/lib/python2.7/argparse.py”, line 2341, in exit
    _sys.exit(status)
    SystemExit: 2
    >>>

    what should I do ?

    1. Are you using the –port option? You should be running it like this:

      $python ldr.py --port /dev/your-serial-port

      Also, while copying the code, use the “Raw” option in the github widget so you don’t mess up the indentation during cut & paste.

      Regards

  14. Thank you chief, finally I success to plot data, but the data can’t change(update), even I adjust value in Analog input.

    :)

    1. Try printing out the values in the Python script to ensure that you are getting valid data. You could also test the plotting code by generating your own random values instead of using the serial data.

  15. Chief,
    I am running python 3.3.5 on a windows 7 mc and have hooked up the arduino reading a pressure sensor and see com3 port sending data in the arduino serial monitor window.

    When i run the above python script in 3.3.5 i get
    usage:plotdata2.py [-h] –port PORT
    plotdata2.py: error: the following arguments are required: –port

    thanks

        1. Are you running this from inside the python interpretor? (I ask because you have the ‘>>>’ prompt.)

          You need to run it from the cmd shell directly.

          Also, your file name is plotdata2.py. Have you made any changes to my code in ldr.py? If so, please post the code.

  16. THank you for your help.
    I ran it from the command prompt and the shell.
    I now know i should run it from the command prompt with the correct directory i have the file in. Sorry about that.
    The first time i ran it i got access to port errors.
    I had arduino and python open.
    I closed Arduino and python and ran from the cmd prompt and now works well.
    Now for some fun!

  17. Hii Electronut

    i have used your tutorial to print real time data on python reading from photo detector here the problem is on arduino the data response was fast but on python there is a delay how to reduce the delay

    Thanks
    Rohith

    1. When you say “on python there is a delay”, what do you mean? Is the animation slow? Did you use the version of my code that uses matplotlib animation class?

Add Comment Register



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>