#!/usr/bin/env python # coding: utf-8 # Import library functions we need import PicoBorgRev import Tkinter import sys import time from PIL import Image, ImageTk # If ImageTk fails to import run: # sudo apt-get install python-imaging-tk # Settings for motors # Board #1 - 9v pumpMin = -50 pumpMax = +50 pumpDemo = -31 wheelMin = -66 wheelMax = +66 wheelDemo = -33 # Board #2 - 9v vibeMin = -100 vibeMax = +100 vibeDemo = -15 slowMin = -100 slowMax = +100 slowDemo = +30 # Board #3 - 7.2v stepsPerDeg = 1440 / 360.0 stepPower = 0.7 stepDelay = 0.002 # Board #4 - 12v fanMin = 0 fanMax = +100 fanDemo = +30 gruntyMin = -100 gruntyMax = +100 gruntyDemo = -33 # Name the global variables global step global PBR1 global PBR2 global PBR3 global PBR4 # Setup the PicoBorg Reverses PBR1 = PicoBorgRev.PicoBorgRev() PBR1.i2cAddress = 0x61 PBR1.Init() if not PBR1.foundChip: print 'Could not find board 1 (0x%02X)' % (PBR1.i2cAddress) sys.exit() PBR1.ResetEpo() PBR2 = PicoBorgRev.PicoBorgRev() PBR2.i2cAddress = 0x62 PBR2.Init() if not PBR2.foundChip: print 'Could not find board 2 (0x%02X)' % (PBR2.i2cAddress) sys.exit() PBR2.ResetEpo() PBR3 = PicoBorgRev.PicoBorgRev() PBR3.i2cAddress = 0x63 PBR3.Init() if not PBR3.foundChip: print 'Could not find board 3 (0x%02X)' % (PBR3.i2cAddress) sys.exit() PBR3.ResetEpo() PBR4 = PicoBorgRev.PicoBorgRev() PBR4.i2cAddress = 0x64 PBR4.Init() if not PBR4.foundChip: print 'Could not find board 4 (0x%02X)' % (PBR4.i2cAddress) sys.exit() PBR4.ResetEpo() # Setup the stepper stepperSeq = [ [+stepPower, +stepPower], [+stepPower, -stepPower], [-stepPower, -stepPower], [-stepPower, +stepPower] ] step = 0 # Function to perform a sequence of steps as fast as allowed def MoveDeg(deg): global step global PBR3 # Calculate a move count count = int(stepsPerDeg * deg) # Choose direction based on sign (+/-) if count < 0: direction = -1 count *= -1 else: direction = 1 # Loop through the steps while count > 0: # Set a starting position if this is the first move if step == -1: drive = stepperSeq[-1] PBR3.SetMotor1(drive[0]) PBR3.SetMotor2(drive[1]) step = 0 else: step += direction # Wrap step when we reach the end of the sequence if step < 0: step = len(stepperSeq) - 1 elif step >= len(stepperSeq): step = 0 # For this step set the required drive values if step < len(stepperSeq): drive = stepperSeq[step] PBR3.SetMotor1(drive[0]) PBR3.SetMotor2(drive[1]) time.sleep(stepDelay) count -= 1 # Turn off the coil power when finished PBR3.MotorsOff() # Class representing the GUI dialog class PicoBorgRev_tk(Tkinter.Tk): # Constructor (called when the object is first created) def __init__(self, parent): Tkinter.Tk.__init__(self, parent) self.parent = parent self.protocol("WM_DELETE_WINDOW", self.OnExit) # Call the OnExit function when user closes the dialog self.Initialise() # Initialise the dialog def Initialise(self): global PBR1 global PBR2 global PBR3 global PBR4 self.title('PicoBorg multi-board demo GUI') self.grid() # Row 0 - Images self.imgPump = Image.open('images/pump.jpg') self.itkPump = ImageTk.PhotoImage(self.imgPump) self.picPump = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picPump.grid(column = 0, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.imgWheel = Image.open('images/wheel.jpg') self.itkWheel = ImageTk.PhotoImage(self.imgWheel) self.picWheel = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picWheel.grid(column = 1, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.imgVibe = Image.open('images/vibe.jpg') self.itkVibe = ImageTk.PhotoImage(self.imgVibe) self.picVibe = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picVibe.grid(column = 2, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.imgSlow = Image.open('images/slow.jpg') self.itkSlow = ImageTk.PhotoImage(self.imgSlow) self.picSlow = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picSlow.grid(column = 3, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.imgStepper = Image.open('images/stepper.jpg') self.itkStepper = ImageTk.PhotoImage(self.imgStepper) self.picStepper = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picStepper.grid(column = 4, row = 0, rowspan = 1, columnspan = 2, sticky = 'NSEW') self.imgFan = Image.open('images/fan.jpg') self.itkFan = ImageTk.PhotoImage(self.imgFan) self.picFan = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picFan.grid(column = 6, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.imgGrunty = Image.open('images/grunty.jpg') self.itkGrunty = ImageTk.PhotoImage(self.imgGrunty) self.picGrunty = Tkinter.Canvas(self, bd = 0, highlightthickness = 0, height = 40) self.picGrunty.grid(column = 7, row = 0, rowspan = 1, columnspan = 1, sticky = 'NSEW') # Row 1 - Names self.lblPump = Tkinter.Label(self, text = 'Pump', justify = Tkinter.CENTER) self.lblPump['font'] = ('Trebuchet', 12, 'bold') self.lblPump.grid(column = 0, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.lblWheel = Tkinter.Label(self, text = 'Wheel', justify = Tkinter.CENTER) self.lblWheel['font'] = ('Trebuchet', 12, 'bold') self.lblWheel.grid(column = 1, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.lblVibe = Tkinter.Label(self, text = 'Vibe', justify = Tkinter.CENTER) self.lblVibe['font'] = ('Trebuchet', 12, 'bold') self.lblVibe.grid(column = 2, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.lblSlow = Tkinter.Label(self, text = 'Slow', justify = Tkinter.CENTER) self.lblSlow['font'] = ('Trebuchet', 12, 'bold') self.lblSlow.grid(column = 3, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.lblStepper = Tkinter.Label(self, text = 'Stepper', justify = Tkinter.CENTER) self.lblStepper['font'] = ('Trebuchet', 12, 'bold') self.lblStepper.grid(column = 4, row = 1, rowspan = 1, columnspan = 2, sticky = 'NSEW') self.lblFan = Tkinter.Label(self, text = 'Fan', justify = Tkinter.CENTER) self.lblFan['font'] = ('Trebuchet', 12, 'bold') self.lblFan.grid(column = 6, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.lblGrunty = Tkinter.Label(self, text = 'Grunty', justify = Tkinter.CENTER) self.lblGrunty['font'] = ('Trebuchet', 12, 'bold') self.lblGrunty.grid(column = 7, row = 1, rowspan = 1, columnspan = 1, sticky = 'NSEW') # Rows 2 to 4 - Controls self.sldPump = Tkinter.Scale(self, from_ = pumpMax, to = pumpMin, orient = Tkinter.VERTICAL, command = self.sldPump_move) self.sldPump.set(0) self.sldPump.grid(column = 0, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') self.sldWheel = Tkinter.Scale(self, from_ = wheelMax, to = wheelMin, orient = Tkinter.VERTICAL, command = self.sldWheel_move) self.sldWheel.set(0) self.sldWheel.grid(column = 1, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') self.sldVibe = Tkinter.Scale(self, from_ = vibeMax, to = vibeMin, orient = Tkinter.VERTICAL, command = self.sldVibe_move) self.sldVibe.set(0) self.sldVibe.grid(column = 2, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') self.sldSlow = Tkinter.Scale(self, from_ = slowMax, to = slowMin, orient = Tkinter.VERTICAL, command = self.sldSlow_move) self.sldSlow.set(0) self.sldSlow.grid(column = 3, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') self.lblStepper2 = Tkinter.Label(self, text = 'Degrees:', justify = Tkinter.CENTER) self.lblStepper2['font'] = ('Trebuchet', 12, '') self.lblStepper2.grid(column = 4, row = 2, rowspan = 1, columnspan = 2, sticky = 'SEW') self.sldStepDeg = Tkinter.Scale(self, from_ = 1, to = +360, orient = Tkinter.HORIZONTAL) self.sldStepDeg.set(180) self.sldStepDeg.grid(column = 4, row = 3, rowspan = 1, columnspan = 2, sticky = 'EW') self.butStepFwd = Tkinter.Button(self, text = '+', command = self.butStepFwd_click) self.butStepFwd['font'] = ('Trebuchet', 12, 'bold') self.butStepFwd.grid(column = 4, row = 4, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.butStepBack = Tkinter.Button(self, text = '-', command = self.butStepBack_click) self.butStepBack['font'] = ('Trebuchet', 12, 'bold') self.butStepBack.grid(column = 5, row = 4, rowspan = 1, columnspan = 1, sticky = 'NSEW') self.sldFan = Tkinter.Scale(self, from_ = fanMax, to = fanMin, orient = Tkinter.VERTICAL, command = self.sldFan_move) self.sldFan.set(0) self.sldFan.grid(column = 6, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') self.sldGrunty = Tkinter.Scale(self, from_ = gruntyMax, to = gruntyMin, orient = Tkinter.VERTICAL, command = self.sldGrunty_move) self.sldGrunty.set(0) self.sldGrunty.grid(column = 7, row = 2, rowspan = 3, columnspan = 1, sticky = 'NS') # Row 5 - All motor actions self.butDemo = Tkinter.Button(self, text = 'Demo', command = self.butDemo_click) self.butDemo['font'] = ('Trebuchet', 18, 'bold') self.butDemo.grid(column = 0, row = 5, rowspan = 1, columnspan = 4, sticky = 'NSEW') self.butOff = Tkinter.Button(self, text = 'All Off', command = self.butOff_click) self.butOff['font'] = ('Trebuchet', 18, 'bold') self.butOff.grid(column = 4, row = 5, rowspan = 1, columnspan = 4, sticky = 'NSEW') self.grid_columnconfigure(0, weight = 2) self.grid_columnconfigure(1, weight = 2) self.grid_columnconfigure(2, weight = 2) self.grid_columnconfigure(3, weight = 2) self.grid_columnconfigure(4, weight = 1) self.grid_columnconfigure(5, weight = 1) self.grid_columnconfigure(6, weight = 2) self.grid_columnconfigure(7, weight = 2) self.grid_rowconfigure(0, weight = 2) self.grid_rowconfigure(1, weight = 0) self.grid_rowconfigure(2, weight = 2) self.grid_rowconfigure(3, weight = 2) self.grid_rowconfigure(4, weight = 2) self.grid_rowconfigure(5, weight = 2) # Set the size of the dialog self.resizable(True, True) self.geometry('800x500') self.picPump.bind('', self.picPump_resize) self.picWheel.bind('', self.picWheel_resize) self.picVibe.bind('', self.picVibe_resize) self.picSlow.bind('', self.picSlow_resize) self.picStepper.bind('', self.picStepper_resize) self.picFan.bind('', self.picFan_resize) self.picGrunty.bind('', self.picGrunty_resize) # Setup the initial motor state PBR1.MotorsOff() PBR2.MotorsOff() PBR3.MotorsOff() PBR4.MotorsOff() # Called when the user closes the dialog def OnExit(self): global PBR1 global PBR2 global PBR3 global PBR4 # Turn drives off and end the program PBR1.MotorsOff() PBR2.MotorsOff() PBR3.MotorsOff() PBR4.MotorsOff() self.quit() # Called when the picPump object is resized def picPump_resize(self, event): size = (event.width, event.height) resized = self.imgPump.resize(size, Image.ANTIALIAS) self.itkPump = ImageTk.PhotoImage(resized) self.picPump.delete('IMG') self.picPump.create_image(0, 0, image = self.itkPump, anchor = Tkinter.NW, tags = 'IMG') # Called when the picWheel object is resized def picWheel_resize(self, event): size = (event.width, event.height) resized = self.imgWheel.resize(size, Image.ANTIALIAS) self.itkWheel = ImageTk.PhotoImage(resized) self.picWheel.delete('IMG') self.picWheel.create_image(0, 0, image = self.itkWheel, anchor = Tkinter.NW, tags = 'IMG') # Called when the picVibe object is resized def picVibe_resize(self, event): size = (event.width, event.height) resized = self.imgVibe.resize(size, Image.ANTIALIAS) self.itkVibe = ImageTk.PhotoImage(resized) self.picVibe.delete('IMG') self.picVibe.create_image(0, 0, image = self.itkVibe, anchor = Tkinter.NW, tags = 'IMG') # Called when the picSlow object is resized def picSlow_resize(self, event): size = (event.width, event.height) resized = self.imgSlow.resize(size, Image.ANTIALIAS) self.itkSlow = ImageTk.PhotoImage(resized) self.picSlow.delete('IMG') self.picSlow.create_image(0, 0, image = self.itkSlow, anchor = Tkinter.NW, tags = 'IMG') # Called when the picStepper object is resized def picStepper_resize(self, event): size = (event.width, event.height) resized = self.imgStepper.resize(size, Image.ANTIALIAS) self.itkStepper = ImageTk.PhotoImage(resized) self.picStepper.delete('IMG') self.picStepper.create_image(0, 0, image = self.itkStepper, anchor = Tkinter.NW, tags = 'IMG') # Called when the picFan object is resized def picFan_resize(self, event): size = (event.width, event.height) resized = self.imgFan.resize(size, Image.ANTIALIAS) self.itkFan = ImageTk.PhotoImage(resized) self.picFan.delete('IMG') self.picFan.create_image(0, 0, image = self.itkFan, anchor = Tkinter.NW, tags = 'IMG') # Called when the picGrunty object is resized def picGrunty_resize(self, event): size = (event.width, event.height) resized = self.imgGrunty.resize(size, Image.ANTIALIAS) self.itkGrunty = ImageTk.PhotoImage(resized) self.picGrunty.delete('IMG') self.picGrunty.create_image(0, 0, image = self.itkGrunty, anchor = Tkinter.NW, tags = 'IMG') # Called when sldPump is moved def sldPump_move(self, value): global PBR1 PBR1.SetMotor1(float(value) / 100.0) # Called when sldWheel is moved def sldWheel_move(self, value): global PBR1 PBR1.SetMotor2(float(value) / 100.0) # Called when sldVibe is moved def sldVibe_move(self, value): global PBR2 PBR2.SetMotor1(float(value) / 100.0) # Called when sldSlow is moved def sldSlow_move(self, value): global PBR2 PBR2.SetMotor2(float(value) / 100.0) # Called when butStepFwd is clicked def butStepFwd_click(self): deg = float(self.sldStepDeg.get()) MoveDeg(deg) # Called when butStepBack is clicked def butStepBack_click(self): deg = float(self.sldStepDeg.get()) MoveDeg(-deg) # Called when sldFan is moved def sldFan_move(self, value): global PBR4 PBR4.SetMotor1(float(value) / 100.0) # Called when sldGrunty is moved def sldGrunty_move(self, value): global PBR4 PBR4.SetMotor2(float(value) / 100.0) # Called when butOff is clicked def butOff_click(self): global PBR1 global PBR2 global PBR3 global PBR4 PBR1.MotorsOff() PBR2.MotorsOff() PBR3.MotorsOff() PBR4.MotorsOff() self.sldPump.set(0) self.sldWheel.set(0) self.sldVibe.set(0) self.sldSlow.set(0) self.sldFan.set(0) self.sldGrunty.set(0) # Called when butDemo is clicked def butDemo_click(self): global PBR1 global PBR2 global PBR3 global PBR4 PBR1.SetMotor1(float(pumpDemo) / 100.0) PBR1.SetMotor2(float(wheelDemo) / 100.0) PBR2.SetMotor1(float(vibeDemo) / 100.0) PBR2.SetMotor2(float(slowDemo) / 100.0) PBR4.SetMotor1(float(fanDemo) / 100.0) PBR4.SetMotor2(float(gruntyDemo) / 100.0) self.sldPump.set(pumpDemo) self.sldWheel.set(wheelDemo) self.sldVibe.set(vibeDemo) self.sldSlow.set(slowDemo) self.sldFan.set(fanDemo) self.sldGrunty.set(gruntyDemo) # if we are the main program (python was passed a script) load the dialog automatically if __name__ == "__main__": app = PicoBorgRev_tk(None) app.mainloop()