# Spice Wheel GUI # Olin College, Principles of Engineering, Fall 2007 # Mary Germino, Christina Nguyen, Leah Engelbert-Fenton, Julie Baca from Tkinter import * import tkMessageBox import tkFileDialog import tkSimpleDialog import ctypes GET_RA0 = 1 GET_RA1 = 2 GET_RA2 = 3 GET_RA3 = 4 SET_RA4 = 5 CLR_RA4 = 6 SET_RA5 = 7 CLR_RA5 = 8 usb = ctypes.cdll.LoadLibrary('usb.dll') usb.initialize() dev = usb.open_device(0x6666, 0x0003) buffer = ctypes.c_buffer(8) ############## #we won't need all these callbacks, but i left them there for now just because. def get_ra0_callback(): usb.control_transfer(dev, 0xC0, GET_RA0, 0, 0, 1, buffer) bit0 = ord(buffer[0]) #value of 1st sensor return bit0 def get_ra1_callback(): usb.control_transfer(dev, 0xC0, GET_RA1, 0, 0, 1, buffer) bit1 = ord(buffer[0]) #value of 2nd sensor return bit1 def get_ra2_callback(): usb.control_transfer(dev, 0xC0, GET_RA2, 0, 0, 1, buffer) bit2 = ord(buffer[0]) #value of 3rd sensor return bit2 def get_ra3_callback(): usb.control_transfer(dev, 0xC0, GET_RA3, 0, 0, 1, buffer) bit3 = ord(buffer[0]) #value of 4th sensor return bit3 #RA4 = wheel motor def set_ra4_callback(): usb.control_transfer(dev, 0x40, SET_RA4, 0, 0, 0, buffer) def clr_ra4_callback(): usb.control_transfer(dev, 0x40, CLR_RA4, 0, 0, 0, buffer) #RA5 = dispenser motor def set_ra5_callback(): usb.control_transfer(dev, 0x40, SET_RA5, 0, 0, 0, buffer) def clr_ra5_callback(): usb.control_transfer(dev, 0x40, CLR_RA5, 0, 0, 0, buffer) ####################### def openabout_callback(): tkMessageBox.showinfo("About", "Version 0.1\n Copyright 2007") def exit_callback(): root.destroy() def openwheelsetup_callback(): global wheelSetup wheelSetup.deiconify() def openrecipemaker_callback(): pass def submitSpices(): print 'Changes are saved!' global row1, row2, row3, row4, row5, row6, row7, row8 global spice1name, spice2name, spice3name, spice4name, spice5name, spice6name, spice7name, spice8name global var1, var2, var3, var4, var5, var6, var7, var8 global check1, check2, check3, check4, check5, check6, check7, check8 global font1, font2, font3 spice1name = Variable.get(s1) spice2name = Variable.get(s2) spice3name = Variable.get(s3) spice4name = Variable.get(s4) spice5name = Variable.get(s5) spice6name = Variable.get(s6) spice7name = Variable.get(s7) spice8name = Variable.get(s8) check1.configure(text = spice1name, font = font2) check2.configure(text = spice2name, font = font2) check3.configure(text = spice3name, font = font2) check4.configure(text = spice4name, font = font2) check5.configure(text = spice5name, font = font2) check6.configure(text = spice6name, font = font2) check7.configure(text = spice7name, font = font2) check8.configure(text = spice8name, font = font2) def GetCheckbuttonVariables(): global var1, var2, var3, var4, var5, var6, var7, var8, Variable, GetCheckbuttonVariables checkbuttonVariables = [Variable.get(var1), Variable.get(var2), Variable.get(var3), Variable.get(var4), Variable.get(var5), Variable.get(var6), Variable.get(var7), Variable.get(var8)] return checkbuttonVariables def GetSpiceAmounts(): global spice1amount, spice2amount, spice3amount, spice4amount, spice5amount, spice6amount, spice7amount, spice8amount spiceAmounts = [Variable.get(spice1amount), Variable.get(spice2amount), Variable.get(spice3amount), Variable.get(spice4amount), Variable.get(spice5amount), Variable.get(spice6amount), Variable.get(spice7amount), Variable.get(spice8amount)] return spiceAmounts def ObtainSensorValuesforPosition(position): print "btw, these positions are completely bogus." if position == 0: return [1,1,0,0] if position == 1: return [1,1,1,1] if position == 2: return [1,1,1,1] if position == 3: return [1,1,1,1] if position == 4: return [1,1,1,1] if position == 5: return [1,1,1,1] if position == 6: return [1,1,1,1] if position == 7: return [0,0,0,0] #This function obtains the current reading of all four sensors (in 1's and 0's) and #returns them as a list of four numbers. def getCurrentSensorReadings(): global theCurrentSensorReadings bit0 = get_ra0_callback() bit1 = get_ra1_callback() bit2 = get_ra2_callback() bit3 = get_ra3_callback() theCurrentSensorReadings = [bit0, bit1, bit2, bit3] def MoveWheel(sensorValues): #set RA4 high until the right sensor values are read print "Actually, no." print "Sensor values\n", sensorValues running = True while running: getCurrentSensorReadings() #print "running", running if theCurrentSensorReadings != sensorValues: set_ra4_callback() print "bits:", theCurrentSensorReadings else: running = False print "Done" print "Yay, Done" clr_ra4_callback() def DispenseSpice(amount): #set RA5 high until the right spice amount has been dispensed print "There is no spice to dispense yet darling." time_to_dispense = 200*amount #200 programming loops to dispense 1 teaspoon print "time to dispense", time_to_dispense running = True while running: for i in range(1,time_to_dispense): set_ra5_callback() print "time now", i else: running = False print "Done" print "Done dispensing" clr_ra5_callback() def initiateMovement(): print "Please STAND BACK - Spice Wheel is in action." stopWheel() checkbuttonVariables = GetCheckbuttonVariables() spiceAmounts = GetSpiceAmounts() for i in range(len(checkbuttonVariables)): if checkbuttonVariables[i] == '1': placeToStop = ObtainSensorValuesforPosition(i) MoveWheel(placeToStop) amount = spiceAmounts[i] DispenseSpice(amount) def stopWheel(): print "The Spice Wheel is coming to a halt." clr_ra4_callback() clr_ra5_callback() #set up some fonts for use in prettifying the gui global font1, font2, font3 font1 = ('corbel', '14', 'italic', 'bold') font2 = ('corbel', '12', 'bold') font3 = ('corbel', '12') #Create the main window root = Tk() root.wm_minsize(width = 590, height = 645) root.resizable(width=FALSE, height=FALSE) root.title('Spice Wheel Launcher') # create a menu menu = Menu(root) root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Exit", command=exit_callback) propertiesmenu = Menu(menu) menu.add_cascade(label="Properties", menu=propertiesmenu) propertiesmenu.add_command(label="Wheel Set Up", command=openwheelsetup_callback) propertiesmenu.add_command(label="Recipe Maker", command=openrecipemaker_callback) helpmenu = Menu(menu) menu.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=openabout_callback) #this makes a wheel setup window global wheelSetup wheelSetup = Toplevel() wheelSetup.resizable(width=FALSE, height=FALSE) #organize the wheel setup window into rows . . . bigrow1 = Frame(wheelSetup, pady = 5) bigrow1.pack(side = TOP) bigrow2 = Frame(wheelSetup) bigrow2.pack(side = TOP) bigrow3 = Frame(wheelSetup, pady = 5) bigrow3.pack(side = TOP) # . . . and columns column1 = Frame(bigrow2, padx = 5) column1.pack(side = LEFT, fill=X) column2 = Frame(bigrow2, bd = 2, relief = GROOVE) column2.pack(side = LEFT, fill=X) column3 = Frame(bigrow2, padx = 5) column3.pack(side = LEFT, fill=X) wheelSetupLabel = Label(bigrow1, text = "Enter the spices in each position.", font = font1).pack(side = TOP, fill = X) #initializing the textbox variables #(these have to be global for the model to be able to see them) global s1, s2, s3, s4, s5, s6, s7, s8 s1 = StringVar() s2 = StringVar() s3 = StringVar() s4 = StringVar() s5 = StringVar() s6 = StringVar() s7 = StringVar() s8 = StringVar() #Make some labelled textboxes in the wheel setup window to input the spice names spice1 = Entry(column1, width=15, textvariable = s1).pack(side = TOP, anchor=SW, fill=X) label1 = Label(column1, text='Position 1', font = font2).pack(side=TOP, anchor=S) spice2 = Entry(column1, width=15, textvariable = s2).pack(side = TOP, anchor=SW, fill=X) label2 = Label(column1, text='Position 2', font = font2).pack(side=TOP, anchor=S) spice3 = Entry(column1, width=14, textvariable = s3).pack(side = TOP, anchor=SW, fill=X) label3 = Label(column1, text='Position 3', font = font2).pack(side=TOP, anchor=S) spice4 = Entry(column1, width=14, textvariable = s4).pack(side = TOP, anchor=SW, fill=X) label4 = Label(column1, text='Position 4', font = font2).pack(side=TOP, anchor=S) spice5 = Entry(column3, width=15, textvariable = s5).pack(side = TOP, anchor=SW, fill=X) label5 = Label(column3, text='Position 5', font = font2).pack(side=TOP, anchor=S) spice6 = Entry(column3, width=15, textvariable = s6).pack(side = TOP, anchor=SW, fill=X) label6 = Label(column3, text='Position 6', font = font2).pack(side=TOP, anchor=S) spice7 = Entry(column3, width=15, textvariable = s7).pack(side = TOP, anchor=SW, fill=X) label7 = Label(column3, text='Position 7', font = font2).pack(side=TOP, anchor=S) spice8 = Entry(column3, width=15, textvariable = s8).pack(side = TOP, anchor=SW, fill=X) label8 = Label(column3, text='Position 8', font = font2).pack(side=TOP, anchor=S) #the following lines of code insert the image for designating the spice positions photo = PhotoImage(file="spicecircle.gif") w = Label(column2, image=photo) w.photo = photo w.pack(anchor=CENTER) #a button to save changes in the wheel setup window (and make the modified names appear in the root window) submitbutton = Button(bigrow3, text = "Save Changes", command = submitSpices, font = font3).pack(side = TOP, fill = X) global spice1amount, spice2amount, spice3amount, spice4amount, spice5amount, spice6amount, spice7amount, spice8amount spice1amount = IntVar() spice2amount = IntVar() spice3amount = IntVar() spice4amount = IntVar() spice5amount = IntVar() spice6amount = IntVar() spice7amount = IntVar() spice8amount = IntVar() #headers row0 = Frame(root) row0.pack(side = TOP, fill=X, padx = 25) currentSpicesLabel = Label(row0, text = 'Current Spices', font = font1).pack(side = LEFT) amountsLabel = Label(row0, text = 'Amounts (tsp.)', font = font1).pack(anchor = N) #some rows to put in the checkbuttons and sliders global row1, row2, row3, row4, row5, row6, row7, row8 row1 = Frame(root, padx = 8) row1.pack(side = TOP, fill=X) row2 = Frame(root, padx = 8) row2.pack(side = TOP, fill=X) row3 = Frame(root, padx = 8) row3.pack(side = TOP, fill=X) row4 = Frame(root, padx = 8) row4.pack(side = TOP, fill=X) row5 = Frame(root, padx = 8) row5.pack(side = TOP, fill=X) row6 = Frame(root, padx = 8) row6.pack(side = TOP, fill=X) row7 = Frame(root, padx = 8) row7.pack(side = TOP, fill=X) row8 = Frame(root, padx = 8) row8.pack(side = TOP, fill=X) #initializing the checkbutton variables global var1, var2, var3, var4, var5, var6, var7, var8, Variable var1 = IntVar() var2 = IntVar() var3 = IntVar() var4 = IntVar() var5 = IntVar() var6 = IntVar() var7 = IntVar() var8 = IntVar() global check1, check2, check3, check4, check5, check6, check7, check8 global spice1name, spice2name, spice3name, spice4name, spice5name, spice6name, spice7name, spice8name #initializing the spicenames to nothing, since they haven't been entered yet spice1name = " " spice2name = " " spice3name = " " spice4name = " " spice5name = " " spice6name = " " spice7name = " " spice8name = " " #instantiating the checkbuttons check1 = Checkbutton(row1,text=spice1name, font = font2, variable=var1) check1.pack(side = LEFT) check2 = Checkbutton(row2,text=spice2name, font = font2, variable=var2) check2.pack(side = LEFT) check3 = Checkbutton(row3,text=spice3name, font = font2, variable=var3) check3.pack(side = LEFT) check4 = Checkbutton(row4,text=spice4name, font = font2, variable=var4) check4.pack(side = LEFT) check5 = Checkbutton(row5,text=spice5name, font = font2, variable=var5) check5.pack(side = LEFT) check6 = Checkbutton(row6,text=spice6name, font = font2, variable=var6) check6.pack(side = LEFT) check7 = Checkbutton(row7,text=spice7name, font = font2, variable=var7) check7.pack(side = LEFT) check8 = Checkbutton(row8,text=spice8name, font = font2, variable=var8) check8.pack(side = LEFT) #instantiating the sliders scale1 = Scale(row1, variable = spice1amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale2 = Scale(row2, variable = spice2amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale3 = Scale(row3, variable = spice3amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale4 = Scale(row4, variable = spice4amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale5 = Scale(row5, variable = spice5amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale6 = Scale(row6, variable = spice6amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale7 = Scale(row7, variable = spice7amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) scale8 = Scale(row8, variable = spice8amount, from_=0, to=4, length=400, tickinterval=.5, resolution = .25, showvalue=YES,orient= 'horizontal', font = font3).pack(side=RIGHT) row9 = Frame(root, pady = 10) row9.pack(side = TOP, fill = X) GO = Button(row9, text = "COMMENCE", command = initiateMovement, font = font3, padx = 20).pack() STOP = Button(row9, text = "ABORT", command = stopWheel, font = font3, padx = 20).pack() root.mainloop() ############################## #usb stuff if dev<0: print "No matching device found...\n" else: ret = usb.control_transfer(dev, 0x00, 0x09, 1, 0, 0, buffer) if ret<0: print "Unable to send SET_CONFIGURATION standard request.\n" root.mainloop() usb.close_device(dev)