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