const int PHOTO = A0; // Analog input pin int voltage = 0; void setup() { Serial.begin(9600); } void loop() { voltage = analogRead(PHOTO); // 0-5v <-> 0-1023 Serial.println(voltage); // Plain ASCII delay(250); // update at 4 Hz }
The circuit is even more simpleminded: the photoresistor's resistance varies from about 10k when dark, to just under 1k when I have my phone's flashlight on it. Placing the analog in port between this and a 10K resistor makes a nice voltage divider which goes from about 50% to 95% of whatever you feed it, which in this case, is 5V:
Actually, if you just want to see data sent from an Arduino chip over the serial port, the built in serial monitor works right away.
However, if you want a nice plot, you have to deal with that yourself. I know Java pretty well, so that was my first instinct. I keep hearing about Python though and how amazing it is. I decided to give it a shot and downloaded Python 3.x for windows. Then I read up on connecting to a COM port and apparently, the best bet is to install a module known as pySerial. I went an got ahold of that, and ... it didn't work. I was having trouble with loading the python module and after a brief search, concluded that I'd better downgrade to Python 2.x. I got that and after dome fiddling, could read from the COM port, albeit with some lag. To fix the lag, it turns out that you have to poll the arduino faster than the arduino is writing out, otherwise you get a backbuffer. I believe you can also solve this with a flush of the serial port.
OK, but I still haven't plotted anything. To get going on that , I read about MatPlotLib for Python for which I needed numPy. I went to download that, and as it turns out, I should have installed a Scientific Python distribution instead of plain old Python. Again, I uninstalled Python and installed EndThought Canopy - a gargantuan download/install which in the end, had major trouble with pySerial. At this point, what was another uninstall, so I dumped it and went for Continuum Anaconda. Using this, I could get a plot up and running - well up, but not running.
Long story short, if you want to plot things in real time with MatPlotLib, you need to give the graphics library to sort itself out, or the window will hang. This can be done via a simple 'sleep' command. The program that eventually worked is shown below:
# Poll a COM port for Serial data and plot real time # Thanks to http://www.lebsanft.org/?p=48 for the code idea import sys sys.path.append('C:\\Python27\\lib\\site-packages') import serial import time import numpy as nm from matplotlib import pyplot as plt ser = serial.Serial('COM3', 9600, timeout=0) yData = [0]*50 ax1=plt.axes() line, = plt.plot(yData) plt.ylim([800,1100]) while 1: # First, read from the device try: currVal = ser.readline() print(currVal) time.sleep(.1); except ser.SerialTimeoutException: print('Error acquiring data') # Check if the data was a valid number ... # may be blank in asynchronous mode try: cV=float(currVal) runnit = True except: runnit = False # If the value was a legit number, plot it. if runnit: ymin = float(min(yData))-10 # Set the y-scaling ymax = float(max(yData))+10 plt.ylim([ymin,ymax]) yData.append(currVal) # tag on newest point del yData[0] # and bump oldest point line.set_xdata(np.arange(len(yData))) line.set_ydata(yData) # update the data plt.show() # update the plot plt.pause(.01) # Doesnt exit nicely here ... need to fix
Finally, real time monitoring of, well ... of my shadow here. But I see it as a next step to bigger and better projects:)
No comments:
Post a Comment