loading

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 instructable, I will be reading and displaying analog data from a pair of LDRs connected to an Arduino. Attached is the schematic.

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:

https://gist.github.com/electronut/5641938

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:

https://gist.github.com/electronut/d5e5f68c610821e311b0
<p>Works 'out of the box' which is seriously just fantastic in the world of analog and digital communication. Serial port can be found by looking in your arduino IDE under tools-&gt; serial port. for me it was /dev/ttyACM0</p><p>Great work!</p>
<p>Great! How to reverse the flow of the graph from right to left?</p>
<p>good day apologize for my English, I'm from Colombia I am currently developing my thesis project and have been almost impossible to create the code acquisition 4 sensors, I wonder if I can use some of their code in my project. and I wonder if there is any way to predefine the port COM6 not run the program from the console. thank you very much for contribution.</p>
<p>Hi,<br><br>I also tried your code and I also get a nice Tk Window, BUT no plot&hellip; <br>apparently analogPlot.update is not called or at least does not do <br>anything. I already tried some things to fix it, but without success. <br>Any hint?<br><br>Could it be the backend, that doesn&rsquo;t want to show me anything?</p><p>Otherwise, a nice, easy and understandable code!!! Well done!<br><br>Thanks in advance.<br><br>Robert</p>
<p>Woohooo! I made it - it was only some wrong or missing dependencies between matplotlib and Tkinter. Found some nice solution for that here: </p><p><a href="http://www.pyimagesearch.com/2015/08/24/resolved-matplotlib-figures-not-showing-up-or-displaying/" rel="nofollow">http://www.pyimagesearch.com/2015/08/24/resolved-m...</a></p><p>Thanks again!</p><p>Robert</p>
<p>Awesome....neat and quick way without using octave or matlab</p>
<p>Hello Elecronut,</p><p>Thank you for the code. I am very new to this, so I have been facing quite a few issues with running the code. I keep getting errors while running the argparse command. I replaced port with COM3 like below, but keep getting errors!</p><p>def main():</p><p> # create parser</p><p> parser = argparse.ArgumentParser(description=&quot;LDR serial&quot;)</p><p> # add expected arguments</p><p> parser.add_argument('--COM3', dest='COM3', required=True)</p><p>Error in python:</p><p>usage: test_python.py [-h] --COM3 COM3</p><p>test_python.py: error: argument --COM3 is required</p><p>My problem is I am not sure where to replace strPort or port with COM3.</p><p>Please help!</p><p>Thanks!</p><p>Ritwika</p>
<p>Without changing the code, run it as:</p><p>&gt;python ldr.py --port COM3</p><p>What is the output?</p>
<p>Thanks, it works!!! I am trying now to add the data to a csv file. Thank you for all the help again!</p>
Awesome!
<p>I love the combination of Python and the Arduino. So I have created a collection about it. I have added your instructable, you can see the collection at: &gt;&gt; <a href="https://www.instructables.com/id/Arduino-and-Python-and-perhaps-a-Rasberry-Pi/"> https://www.instructables.com/id/Arduino-and-Pytho...</a></p>
<p>Hello elecronut,</p><p>Thank you for sharing. I like your project and I will use with my robot.</p><p>I have a ultrasonic attached to a servo to mapping obstacles. I send to serial port to numbers: angle of the servo and detected distance. Now, I want to graphic the obstacles.</p><p>I try your code but I need a XY praph. I mean, use the first number (angle) for X and the second number (distance) as Y.</p><p>I tried to make some modification but without any success.</p><p>Could you give me any suggestions?</p><p>Thank you in advance!</p>
<p>Hello,</p><p>You need to specify the axes data differently. Take a look at the matplotlib tutorial below:</p><p>http://matplotlib.org/users/pyplot_tutorial.html</p><p>Regards</p>
<p>Thank you!</p><p>Now I can see the problem. I have made some changes and... it works :)!</p>
<p>Hello, I am currently working with the same thing but in a different project. I am just a newbie in python programming would you mind if I ask a copy of the changes you made to make the x axis have a different value instead of time or could you tell me how? I am trying to plot x-axis as velocity and y-axis as position for a phase plot in my case study. Thank You in Advance.</p><p>By the way I've already tried this line: a1,=ax.plot([0], [1]), 0-velocity and 1-position, however i didn't get anything on the plotting window.</p>
<p>Hello,</p><p>The axes can be anything. I've created an example for you - an animation that shows an oscillating circle:</p><p><a href="https://gist.github.com/electronut/332b9097179f33c7fcd7" rel="nofollow">https://gist.github.com/electronut/332b9097179f33c...</a><br><br>For phase plots, also take a look at:<br></p><p><a href="http://kitchingroup.cheme.cmu.edu/blog/2013/02/21/Phase-portraits-of-a-system-of-ODEs/" rel="nofollow">http://kitchingroup.cheme.cmu.edu/blog/2013/02/21/...</a></p>
<p>Thank you for the example you've made, i will try this in my vertical spring oscillation with arduino, hoping it would work :)</p>
<p>Great, good luck!</p>
<p>Awesome!</p>
<p>Hello, electronut,</p><p>Thanks for your tutorial. This code works. </p><p>However, when my arduino device writes the serial at 200Hz, I notice there is a significant delay (about 7 seconds) of drawing. </p><p>I have tried to reduce the interval to 1, but it does not solve this problem.</p><p>is there any way to reduce such delay?</p>
<p>Hello,</p><p>I don't think the plot will be able to keep up at 200 Hz. Have you tried blit=True?</p>
<p>yes, I have tried blit=true, it helps, but does not solve it completely. </p><p>I was wondering:</p><p>1)what is the reason for such degraded performance? what is the bottleneck?</p><p>2) is there any way to draw real data sampled at high frequency, i.e., 300 Hz</p>
<p>Matplotlib I don't think was designed to update animations at the rate you mentioned. If you need to draw things that update very fast, you'll have to look a low level API - something which uses OpenGL for example. Here's one:<br></p><p>http://pyqtgraph.org/</p>
<p>Made it work. I find it odd, that the performance degrades when removing the delay between reads. I'll try to change the code for a single Ain read in order to see if I can increase the baud rate on the serial comms to get higher sampling rates. Thanks for your post! :)</p>
<p>Great!</p>
<p>The code work, but when I put blit=True for better performance, I get overlapped plots. Probably missing init_func?</p>
<p>Probably the older frame is not getting cleared in the animation. I did not use this flag because it wasn't working well across different OS.</p>
<p>I've made a similar program but with 6 subplots (12 arduino vari&aacute;veis). It is almost impossible to run without blit. I think init function can fix it since it works for a single plot, but I have no idea how to perform it since init should stay inside the class and must receive some parameters. The documentation doesn't cover how to use init_func with parameters. Can you point some direction or how to perform serial communication outside a class.</p>
<p>I am not sure what you mean by init_func. As for serial comms, you can just take the code out of the class:</p><p>ser = serial.Serial(strPort, 9600)</p><p>line = ser.readline()</p><p># close when done</p><p>ser.flush()</p><p>ser.close()</p>
<p>I made an equivalent tool in python that print real time data from ADXL345 accelerometer.</p><p><a href="https://github.com/mba7/SerialPort-RealTime-Data-Plotter" rel="nofollow">https://github.com/mba7/SerialPort-RealTime-Data-P...</a></p><p>may be it will be helpful for someone</p>
<p>sweet!!! was just setting up to do just such an adxl345 project (actually 2 of them but thats advanced version). Will be back with more comments as I progress</p>
<p>Hello electronut,</p><p>I am trying to plot x and y axis of my joystick sensor.But I didn't understand this line;</p><p>parser.add_argument('--port', dest='port', required=True)</p><p>What should I write to '--port' section?</p><p>Thank you</p>
<p>Hello,</p><p>The --port argument is for your serial port name. (For eg. something like COM3 under windows or /dev/tty.* under OS X) One easy way to find this information is look under Tools-&gt;Port in the Arduino software.</p><p>Regards</p>
<p>I really have finally finished making this work. I would like to thank @bartons2 for asking those noob questions. They really helped me.. Everything to make this work is in this comments.</p><p>I used </p><p>python-mserial.tools.list_ports </p><p>python-mserial.tools.miniterm -h </p><p>(1)I used this to list the ports and find the one I needed. (this is a given from documentation). (2) I used this to figure out how to output the port. I also have to make sure the output data on serial screen was in correct format.</p><p>My ploy data is analog, and I was originally receiving input every 33 mili-seconds. The plot could not keep up. I lowered it to 150.</p><p>I will now try to figure out how to make it discrete. The plot is of a position sensor, and I just put my hand in front of it.</p>
<p>Hello Electronut,</p><p>Thanks for this excellent foolproof ;) howto, I had my 5 MQ135 gas sensors up and running in no time.<br>Could <br> you point me in the right direction if I wanted to have your program <br>additionally store / log the values it receives from the serial device, <br>in a separate log file?</p><p>Thanks for your time, \W.</p>
I am glad my code was useful to you. For logging data, you can do something like this:<br><br>&gt;&gt;&gt; f = open('log.txt', 'w')<br>&gt;&gt;&gt; str = &quot;10 100\n&quot;<br>&gt;&gt;&gt; f.write(str)<br>&gt;&gt;&gt; f.close()<br>&gt;&gt;&gt; exit()<br><br>Do the open() right after serial.Serial() and do the file write in update() after retrieving line from serial port.<br><br>Hope that gets you started. Good luck!
Dear electronut,<br> <br> It's bin a while, I ordered some new MQ135's and started my project again last week. The plotting still works fine with your original program. However, I have entered the code lines to additionally log to a file as you suggested but &quot;NameError: global name 'f' is not defined&quot; keeps bugging me. I am doing some very basic thing wrong, but my mileage is way too low to figure it out myself. Could you help me out?<br> Not sure I'm allowed to paste the code in this box, but here goes nothing.. My alterations are commented with double hashes ##.<br> <br> &quot;&quot;&quot;<br> pyplotlog_v2.py<br> <br> Display analog data from Arduino using Python (matplotlib)<br> ... and log the serial output to a file as well<br> 5 MQ135 airquality sensors simultaneous measuring<br> Author: Mahesh Venkitachalam<br> Website: electronut.in<br> <br> &quot;&quot;&quot;<br> <br> import sys, serial, argparse, threading<br> import numpy as np<br> import time<br> from time import sleep<br> from datetime import datetime<br> from collections import deque<br> <br> import matplotlib.pyplot as plt<br> import matplotlib.animation as animation<br> <br> # plot class<br> class AnalogPlot:<br> &nbsp; # constr<br> &nbsp; def __init__(self, strPort, maxLen):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # open serial port<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ser = serial.Serial(strPort, 9600)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f = open('probe.log', 'w')&nbsp; ## open log file, write &quot;w&quot; or append &quot;a&quot;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str=&quot;a0+' '+a1+' '+a2+' '+a3+' '+a4+'\n&quot; ## parse serial string to be logged<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.av = deque([0.0]*maxLen)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.aw = deque([0.0]*maxLen)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ax = deque([0.0]*maxLen)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ay = deque([0.0]*maxLen)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.az = deque([0.0]*maxLen)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.maxLen = maxLen<br> <br> &nbsp; # add to buffer<br> &nbsp; def addToBuf(self, buf, val):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if len(buf) &lt; self.maxLen:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.append(val)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.pop()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.appendleft(val)<br> <br> &nbsp; # add data<br> &nbsp; def add(self, data):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert(len(data) == 5)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.addToBuf(self.av, data[0])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.addToBuf(self.aw, data[1])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.addToBuf(self.ax, data[2])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.addToBuf(self.ay, data[3])<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.addToBuf(self.az, data[4])<br> <br> &nbsp; # update plot<br> &nbsp; def update(self, frameNum, a0, a1, a2, a3, a4):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.write(str)&nbsp; # write to log<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.close()&nbsp;&nbsp;&nbsp;&nbsp; # close log<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # exit logwrite (?)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = self.ser.readline()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = [float(val) for val in line.split()]<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # print data<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(len(data) == 5):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.add(data)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a0.set_data(range(self.maxLen), self.av)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a1.set_data(range(self.maxLen), self.aw)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a2.set_data(range(self.maxLen), self.ax)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a3.set_data(range(self.maxLen), self.ay)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a4.set_data(range(self.maxLen), self.az)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except KeyboardInterrupt:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print('exiting')<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return a0,<br> <br> &nbsp; # clean up<br> &nbsp; def close(self):<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # close serial<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ser.flush()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.ser.close()<br> <br> # main() function<br> def main():<br> &nbsp; # create parser<br> &nbsp; parser = argparse.ArgumentParser(description=&quot;LDR serial&quot;)<br> &nbsp; # add expected arguments<br> &nbsp; parser.add_argument('--port', dest='port', required=True)<br> <br> &nbsp; # parse args<br> &nbsp; args = parser.parse_args()<br> <br> &nbsp; #strPort = '/dev/ttyACM0'<br> &nbsp; strPort = args.port<br> <br> &nbsp; print('reading from serial port %s...' % strPort)<br> <br> &nbsp; # plot parameters<br> &nbsp; analogPlot = AnalogPlot(strPort, 5000)<br> <br> &nbsp; print('plotting data...')<br> <br> &nbsp; # set up animation<br> &nbsp; fig = plt.figure()<br> &nbsp; ax = plt.axes(xlim=(0, 5000), ylim=(0, 1023))<br> &nbsp; a0, = ax.plot([], [])<br> &nbsp; a1, = ax.plot([], [])<br> &nbsp; a2, = ax.plot([], [])<br> &nbsp; a3, = ax.plot([], [])<br> &nbsp; a4, = ax.plot([], [])<br> &nbsp; anim = animation.FuncAnimation(fig, analogPlot.update,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fargs=(a0, a1, a2, a3, a4),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; interval=5000)<br> ## Taken from:<br> # https://www.instructables.com/id/Using-an-Arduino-and-Python-to-plotsave-data<br> # the following does not work:<br> #&nbsp; row = (a0, a1, a2, a3, a4)&nbsp;&nbsp; #combines lists together<br> #&nbsp; row_arr = np.array(row)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #creates array from list<br> #&nbsp; np.savetxt(&quot;probe.log&quot;, row_arr)&nbsp; #save data in file<br> ##<br> <br> &nbsp; # show plot<br> &nbsp; plt.show()<br> <br> &nbsp; # clean up<br> &nbsp; analogPlot.close()<br> <br> &nbsp; print('exiting.')<br> <br> <br> # call main<br> if __name__ == '__main__':<br> &nbsp; main()<br> <br>
<p>Make `f` a member of the AnalogPlot class. So use `self.f` everywhere and it should be fine.</p>
<p>Hi Electronut,</p><p>I appreciate your spirit to share your code with us :-) However, you can make your code more simple, faster, no error outputs when you hit keyboard interrupt, and naturally save the output file as a text file :-) </p><p>I would probably not use class objects since our task is so simple, but you can keep the parsers (user inputs from terminal). Here is my version with only two methods (your Arduino is required to have 2 outputs, for instance V0 and V1, but you can simply change the number of expected columns from Arduino):</p><p>___________________________________________________________</p><p>import sys, serial, argparse<br>import numpy as np<br>from time import sleep<br>from collections import deque<br><br>import matplotlib.pyplot as plt <br>import matplotlib.animation as animation<br><br># constants<br>maxLen = 200<br>v0 = deque([0.0]*maxLen)<br>v1 = deque([0.0]*maxLen)<br>#ardtime = deque([0.0]*maxLen)<br><br>strPort = '/dev/ttyACM0'<br>ser = serial.Serial(strPort, 9600)<br><br># set up animation<br>fig = plt.figure(1, figsize=(15,10))<br>ax = plt.axes(xlim=(0, 200), ylim=(0, 1023))<br>line_1, = ax.plot([], [], 'ko-')<br>line_2, = ax.plot([], [], 'ro-')<br><br># initialization function: plot the background of each frame<br>def init():<br> line_1.set_data([], [])<br> line_2.set_data([], [])<br> return line_1, line_2,<br><br># animation function. This is called sequentially<br>def animate(i):<br> try:<br> line = ser.readline()<br> data = [float(val) for val in line.split()]<br> if(len(data) == 2): # expected no. of columns from Arduino<br> <br> ###################<br> # save data locally and put header<br> my_file='alpha_step_rd.txt'<br> if i==0:<br> thefile = open(my_file, 'w')<br> thefile.write('Microcontroller time [ms], Arb. unit [bits]\n')<br> thefile.close()<br> with open(my_file, 'a') as thefile: <br> thefile.write(&quot;%s\n&quot; % line.strip())<br> ###################<br> <br> v0.pop()<br> v0.appendleft(data[1])<br> v1.pop()<br> v1.appendleft(data[2])<br> '''<br> ardtime.pop()<br> ardtime.appendleft(data[0])<br> '''<br> line_1.set_data(range(maxLen),v0)<br> line_2.set_data(range(maxLen),v1)<br> except KeyboardInterrupt:<br> print('exiting')<br> <br> return line_1, line_2<br><br># call the animator. blit=True means only re-draw the parts that have changed.<br>anim = animation.FuncAnimation(fig, animate, init_func=init, interval=50, blit=True)<br><br>string_1 = ''.join([r'$\Delta$time $\approx$ Arduino_delay'])<br>plt.xlabel(string_1, fontsize=20)<br>plt.ylabel(&quot;Bits, arb. units&quot;, fontsize=20)<br>plt.tick_params(axis=&quot;both&quot;, labelsize=20)<br><br># show plot<br>plt.show()<br><br># flush and close the serial port<br>ser.flush()<br>ser.close()</p>
Thanks, but your code indentation is all mangled, making it hard to understand. (I recommend creating a github gist.) <br><br>Also, a few points: <br><br>1. blit=True does not work across all platforms. On OS X it crashes for me, which is why I did not use the flag.<br>2. Using classes makes your code modular and much easier to comprehend.<br>3. Your code doesn't support command line args.
<p>Hi electronut,</p><p>My code has no parsers, that's correct. It is just because I prefer to make changes and typing in the editor :-)</p><p>Your functions &quot;addToBuf&quot; and &quot;add&quot; can be included in the &quot;update&quot; function by adding only 3 lines. The most importing thing to remember is that matplotlib method FuncAnimation expects array returns from method &quot;set_data&quot; :-) The rest of the coding is just matter of taste.</p><p>All the best,</p><p>Copernicus</p>
<p>Hi, total newb here. When I run your scripts, I get:</p><p>Traceback (most recent call last):</p><p> File &quot;/Users/barton/Documents/Arduino/ldr.py&quot;, line 10, in &lt;module&gt;</p><p> import sys, serial, argparse</p><p>ImportError: No module named serial</p><p>Using a Mega with macbook and OSX10. I can see from discussion below that Python doesn't know which serial port I am using. Where do I put that in?</p>
<p>Hello,</p><p>I think you need to install pyserial:</p><p><a href="http://pyserial.sourceforge.net/pyserial.html#installation" rel="nofollow">http://pyserial.sourceforge.net/pyserial.html#inst...</a></p><p>Also, your Arduino IDE Tools-&gt;Serial Port will tell you the name of the serial port used on your Mac. My code takes this as the --port command line argument.</p><p>Good luck!</p>
<p>Thanks, you were right. I was missing many elements of Python (which I've never used before). The code runs and makes a plot with no data. The plot doesn't look like yours (see pic). I've checked the serial window in Arduino and the data is flowing. I changed the line about the serial port to strPort = '/dev/tty.usbmodem1411' which is what my port is called in the Arduino IDE. Any more advice? I appreciate the help. If it matters, I am building a logger for my fermenter.</p>
<p>When you deal with serial port (or other real-time comms) it won't work from inside the Python interpreter. Try running it from the shell as in:</p><p>&gt;python test.py</p><p>Also, print your data out (instead of plotting) to ensure that the values make sense.</p><p>I'd love to see pics of your project. By the way, my Python book is going to be out soon:</p><p>http://www.nostarch.com/pythonplayground</p>
<p>Right again. Next problem seems to be that the data from the arduino is not formatted the way your python code wants or like you specified above. Instead of </p><p>512 300<br>513 280</p><p>I am getting </p><p>512 </p><p> 300<br>513 </p><p> 280</p><p>My sketch is identical to yours. </p><p>I will send pics once it's pretty! </p>
<p>Are you using the updated Python code below?</p><p><a href="https://gist.github.com/electronut/d5e5f68c610821e311b0" rel="nofollow">https://gist.github.com/electronut/d5e5f68c610821e...</a></p><p>Also, please post your code that's printing the values. Instead of cut &amp; paste, please upload it as a github gist and post the link here (useful to have a gthub account anyway) so we can see it properly. Or you can just use pastebin - no setup required:</p><p><a href="http://pastebin.com/" rel="nofollow">http://pastebin.com/</a></p>
<p>I am using your new Python code. Here is my sketch:</p><p><a href="http://pastebin.com/5HiBa1hQ" rel="nofollow">http://pastebin.com/5HiBa1hQ</a></p>
<p>The sketch looks fine. Where did you put the print statement in my code? To debug, I recommend simplified the code - take out all the matplotlib stuff out and just see if you can print data from the serial port correctly.</p>
<p>Thanks for your patience with this. I printed the data from the Arduino IDE and by adding print(line) right after line is assigned in your code. I also added print(len(data)) which returns 0 or 1 rather than 2. This is why there is no data in the plot. </p>

About This Instructable

97,482views

43favorites

License:

Bio: Open Source Hardware Projects - Microcontrollers, Programming, and new prototyping technologies.
More by electronut:Touch Activated Blinky Badge Temperature/Altitude/Pressure Display using Arduino & BMP180 A simple hack to adapt an 8 pin male dual row header to a breadboard. 
Add instructable to: