#Combine and modify FTDI python code (Neil Gershenfeld hello.light.45.py)and the R graphing code (RthreeB.py--Laura Perovich, patched together from rPy2 manual) # #plots pressure sensor readings in real(ish) time #Currently off one pressure sensor # #serial port on Linux is /dev/ttyUSB0 #Trying to get models to match to the dance from Tkinter import * import serial #Creating an R vector or matrix, and filling its cells using Python code import rpy2.robjects as robjects from rpy2.robjects.packages import importr import rpy2.rinterface as rinterface import rpy2.robjects.lib.ggplot2 as ggplot2 import time #Python way to write csvs.... import csv #maybe try threading module #http://docs.python.org/2/library/threading.html#module-threading #Make a function that runs just the central r loop, not the intro bit. def r_refreshB(): # Ctrl-C to interrupt while True: idle() #Don't use sleep--it messes up the FTDI stuff base = importr('base') grdevices = importr('grDevices') r = robjects.r #SET UP DATAFRAME #Create a dataframe with two columns and dummy numbers #Note: range includes the bottom, but not the top number #Space doesn't need to be a perfect fit, rows get added as time goes past ttime=robjects.IntVector(range(1,101)) press=robjects.FloatVector(r.rep(robjects.NA_Real,100)) foot=robjects.StrVector(r.rep('R',100)) for i in range(1,100, 2): foot.rx[i]='L' i=robjects.IntVector((1,1)) counter=robjects.IntVector((1,1)) d = {'ttime': ttime, 'press': press, 'foot': foot} dataf = robjects.DataFrame(d) r.X11() #Add something where we write out the database (graph?) on quitting #Variables for interpreting what's read in. eps = 0.5 # filter time constant filter = 0.0 # filtered value def idle(): global filter, eps, counter, i, dataf # # idle routine # byte2 = 0 byte3 = 0 byte4 = 0 ser.flush() while 1: # # find framing # byte1 = byte2 byte2 = byte3 byte3 = byte4 byte4 = ord(ser.read()) if ((byte1 == 1) & (byte2 == 2) & (byte3 == 3) & (byte4 == 4)): break low = ord(ser.read()) high = ord(ser.read()) newvalue=ord(ser.read()) value = 256*high + low #This is what I need to add to the dataset filter = (1-eps)*filter + eps*value #I need something here that says return the values, then run the dataset and graphing part when you have a value. #Main loop #Add to the dataset # print(filter) # print(value) # print(high) # print(low) # print(dataf) jj=counter.rx(1)[0]+1 counter=robjects.IntVector((jj,1)) ttime.rx[counter]=jj press.rx[counter]=filter foot.rx[counter]='L' d = {'ttime': ttime, 'press': press, 'foot': foot} dataf = robjects.DataFrame(d) robjects.DataFrame(d).to_csvfile("/home/perovich/Desktop/irumbaJV.csv", row_names=False) #Make the variables visible for themodel robjects.globalenv["press"]=press robjects.globalenv["ttime"]=ttime #Try to see what the shape of the data is--fit a model lmCube = (r.lm('press ~ ttime + I(ttime^2) + I(ttime^3)')) #NORMALIZE BY LENGTH OF OFF/ON SOMEHOW? #ratio of nearby "on" timepoints. #Right now plot every 10 data points. #This looks kind of spaztic--maybe average every 10 to get a smoother value? or every 5 or something else. if jj%20==0: gp=ggplot2.ggplot(dataf) pp = gp + \ ggplot2.aes_string(x='ttime', y='press', col='factor(foot)') + \ ggplot2.opts(title=foot) + \ ggplot2.xlim(0, 2500) + \ ggplot2.ylim(0, 1100) + \ ggplot2.geom_point() +\ ggplot2.stat_smooth(method = 'lm', formula='y~x +I(cos(x))+I(cos(2*x))+I(sin(x))+I(sin(2*x))+I(cos(3*x))+I(sin(3*x))+I(cos(4*x))+I(sin(4*x))') #poly(cos(x), 2) #Make sure there's enough points before you add the model or else weird things happen. pp.plot() # # check command line arguments # if (len(sys.argv) != 2): print "command line: hello.pressuredoubleCheatVCC.44.py serial_port" sys.exit() port = sys.argv[1] # # open serial port # ser = serial.Serial(port,9600) ser.setDTR() # #Figure out how to add to the plot without redrawing the whole thing #(really the window flashing is the main problem here) # # start idle loop # r_refreshB() #idle() #r.mainloop()