This week our goal is to program / modify a program to interface with our input board
I decided after a bit of exploring to learn about Tkinter by modifying the hello.light.45.py program.
I began by changing colors and fonts and then added an arrow that points to the current value on the bar graph.
This got me to thinking, this reminded me of the Sickbay monitors on the original Star Trek. I decided to try to remake the program to resemble those monitors. First, I had to change the x and y coordinates to make the bar graph up and down instead of left and right. Next, I had to reverse the direction, as I wanted the full bar to be on the top of the graph. I used Tkinter to add an appropriate scale, and labels to match the theme. I left the changing numbers at the top, but they can be removed to create a more accurate depection of the TV monitors. The entire project is graphically scaleable, except for the textual elements.
Overall not bad, I not only learned a lot about Tkinter, but also I now understand most of the original program.
Download the program: hello.light.45.trek.py
# hello.light.45.trek.py # # receive and display light level # hello.light.45.trek.py serial_port # heavily based on hello.light.45.py with the following authorship ## Neil Gershenfeld ## CBA MIT 10/24/09 ## ## (c) Massachusetts Institute of Technology 2009 ## Permission granted for experimental and personal use; ## license for commercial sale available from MIT ## # Modified 4/13 by Chris Wiemer to resemble Star Trek TOS Sickbay/Medical Tricorder Monitors from Tkinter import * import serial WINDOW = 600 # window size eps = 0.5 # filter time constant filter = 0.0 # filtered value def idle(parent,canvas): global filter, eps # global variables # # 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()) value = 256*high + low filter = (1-eps)*filter + eps*value x = int(.1*WINDOW + (.9-.1)*WINDOW*filter/1024.0) canvas.itemconfigure("text",text="%.1f"%filter) # # moves arrow polygon to match input # canvas.coords('marker',.31*WINDOW,x,.42*WINDOW,x+.03*WINDOW,.42*WINDOW,x+.05*WINDOW,.45*WINDOW,x+.05*WINDOW,.45*WINDOW,x+.03*WINDOW,.46*WINDOW,x+.01*WINDOW,.46*WINDOW,x-.01*WINDOW,.45*WINDOW,x-.03*WINDOW,.45*WINDOW,x-.05*WINDOW,.42*WINDOW,x-.05*WINDOW,.42*WINDOW,x-.03*WINDOW) canvas.update() parent.after_idle(idle,parent,canvas) # # check command line arguments # if (len(sys.argv) != 2): print "command line: hello.light.45.py serial_port" sys.exit() port = sys.argv[1] # # open serial port # ser = serial.Serial(port,9600) ser.setDTR() # # set up GUI # root = Tk() # # sets the text that appears in the title bar # root.title('Light Level -- hello.light.45.py (q to exit)') # # sets the letter q on the keyboard to trigger exiting the script # root.bind('q','exit') # # creates the blank window # canvas = Canvas(root, width=.5*WINDOW, height=WINDOW, background='black') # # sets the font and size of the type used for the number readings and label # the next text line can be commented out for a more accurate appearance # canvas.create_text(.15*WINDOW,.075*WINDOW,text=".33",font=("Helvetica", 20),tags="text",fill="yellow") canvas.create_text(.15*WINDOW,.95*WINDOW,text="LIGHT",font=("Helvetica", 20),tags="label",fill="yellow") # # creates scale # canvas.create_rectangle(.15*WINDOW,.1*WINDOW,.16*WINDOW,.26*WINDOW, tags="scale1", fill='red') canvas.create_line(.12*WINDOW,.1*WINDOW,.19*WINDOW,.1*WINDOW,fill='red') canvas.create_text(.10*WINDOW,.1*WINDOW,text="0",font=("Helvetica", 10),fill="red") canvas.create_line(.14*WINDOW,.18*WINDOW,.17*WINDOW,.18*WINDOW,fill='red') canvas.create_line(.12*WINDOW,.26*WINDOW,.19*WINDOW,.26*WINDOW,fill='red') canvas.create_text(.10*WINDOW,.26*WINDOW,text="200",font=("Helvetica", 10),fill="red") canvas.create_line(.14*WINDOW,.33*WINDOW,.17*WINDOW,.33*WINDOW,fill='yellow') canvas.create_line(.12*WINDOW,.41*WINDOW,.19*WINDOW,.41*WINDOW,fill='yellow') canvas.create_text(.10*WINDOW,.41*WINDOW,text="400",font=("Helvetica", 10),fill="yellow") canvas.create_rectangle(.15*WINDOW,.26*WINDOW,.16*WINDOW,.49*WINDOW, tags="scale2", fill='yellow') canvas.create_line(.14*WINDOW,.49*WINDOW,.17*WINDOW,.49*WINDOW,fill='green') canvas.create_line(.12*WINDOW,.57*WINDOW,.19*WINDOW,.57*WINDOW,fill='green') canvas.create_text(.10*WINDOW,.57*WINDOW,text="600",font=("Helvetica", 10),fill="green") canvas.create_rectangle(.15*WINDOW,.49*WINDOW,.16*WINDOW,.73*WINDOW, tags="scale3", fill='green') canvas.create_line(.14*WINDOW,.65*WINDOW,.17*WINDOW,.65*WINDOW,fill='green') canvas.create_line(.12*WINDOW,.73*WINDOW,.19*WINDOW,.73*WINDOW,fill='green') canvas.create_text(.10*WINDOW,.73*WINDOW,text="800",font=("Helvetica", 10),fill="green") canvas.create_line(.14*WINDOW,.80*WINDOW,.17*WINDOW,.80*WINDOW,fill='yellow') canvas.create_rectangle(.15*WINDOW,.73*WINDOW,.16*WINDOW,.80*WINDOW, tags="scale4", fill='yellow') canvas.create_rectangle(.15*WINDOW,.80*WINDOW,.16*WINDOW,.9*WINDOW, tags="scale5", fill='red') canvas.create_line(.12*WINDOW,.88*WINDOW,.19*WINDOW,.88*WINDOW,fill='red') canvas.create_text(.10*WINDOW,.88*WINDOW,text="1000",font=("Helvetica", 10),fill="red") canvas.create_polygon(.05*WINDOW,.49*WINDOW,.07*WINDOW,.49*WINDOW,.07*WINDOW,.73*WINDOW,.05*WINDOW,.73*WINDOW,.05*WINDOW,.725*WINDOW,.06*WINDOW,.725*WINDOW,.06*WINDOW,.495*WINDOW,.05*WINDOW,.495*WINDOW, tags="scaleside", fill='green') # # create the triangle that shows current levels # canvas.create_polygon(.31*WINDOW,.3*WINDOW,.42*WINDOW,.33*WINDOW,.42*WINDOW,.35*WINDOW,.45*WINDOW,.35*WINDOW,.45*WINDOW,.35*WINDOW,.46*WINDOW,.36*WINDOW,.46*WINDOW,.29*WINDOW,.45*WINDOW,.27*WINDOW,.45*WINDOW,.25*WINDOW,.42*WINDOW,.25*WINDOW,.42*WINDOW,.27*WINDOW, tags='marker',fill='white') canvas.pack() # # start idle loop # root.after(100,idle,root,canvas) root.mainloop()back to index