Yay! My article on Arduino and Raspberry Pi is this month’s cover of The MagPi! Read it on Issuu, or download the PDF.
Thanks to Ash and the rest of the team at the magazine.
Yay! My article on Arduino and Raspberry Pi is this month’s cover of The MagPi! Read it on Issuu, or download the PDF.
Thanks to Ash and the rest of the team at the magazine.
[…] Whee! This entry was the basis of the cover article of The MagPi issue 7. Read it on Issuu, or download the PDF. […]
Dear Stewart,
I just wanted to thank you for the fantastic article in the MagPi. Articles like this are very inspiring and help us beginners to see the possibilities that exist in the world of the experienced!
I have tried to expand on the code that you kindly published and would like some help if you can spare the time!
1. Closing the programme is very difficult. I have created a button to .destroy()
This successfully kills the Tkinter widget but the terminal window hangs and sometimes causes an issue with the Arduinio. This means I have to remove the Ardion USB and close the terminal window to get it working.
2. I am trying to add a time and date label. I can get it to display once or by following the get_temp code lines I can get the label to update but it sits in the same place as the temp window. Please can you explain why the labels are placed in this place for I cannot see a .pack command for the temp label.
How can I add my timeDate function and display somewhere else in the widget!!!!
I tried adding anchor in the label.config but this seems to have no effect.
Sorry for the additional work but I really want to learn and expand on the already great article you created.
My code below…..
#!/usr/bin/python import pyfirmata from Tkinter import * import time from datetime import datetime # create a new board header, # specify a serial port; # could be /dev/ttyusb0 for older Arduinos board = pyfirmata.Arduino('/dev/ttyACM0') # start an iterator thread so serial buffer doesn't overflow iter8 = pyfirmata.util.Iterator(board) iter8.start() # set up pins # A0 Input LM35 pin0 = board.get_pin('a:0:i') # D3 PWM Output (LED) pin3 = board.get_pin ('d:3:p') # IMPORTANT! Discard first reads until A0 has something valid while pin0.read() is None: pass def get_temp(): #LM35 reading is degrees C to label label_text = "Temp: %6.1f C" % ( pin0.read() * 5 * 100) label.config(text = label_text) # reshedule after half a second root.after(500, get_temp) def set_brightness(x): # set LED # Scale widget returns 0..100 # Pyfirma expects 0..1.0 pin3.write(float(x) / 100.0) def get_timeDate(): #get the time and date label_text_time = (datetime.now().strftime('%b %d %H:%M:%S\n')) label.config(text = label_text_time) root.after(500, get_timeDate) def cleanup(): # clean up on exit # and turn LED back off pin3.write(0) board.exit() # set up GUI root = Tk() #ensure cleanup() is called on exit root.wm_protocol("WM_DELETE_WINDOW",cleanup) #Exit button use '.destroy()' to quit window button = Button(root, command = lambda:root.destroy(), text = "Quit", fg= "red") button.pack(side = BOTTOM) title=Label (root, text="Indoor Temperature Reading", fg= "blue") title.pack(side=TOP) # draw a big slider for LED brightness scale = Scale(root, command = set_brightness, orient = HORIZONTAL, length = 400, label = 'Brightness') scale.pack(anchor = CENTER) # place label up against scale widget label = Label(root) label.pack(anchor = 'nw') # start temperature read loop root.after(500, get_temp) #start time and date loop root.after(500, get_timeDate) # run Tk event loop root.mainloop()
Thanks for getting in touch. To your points:
1) Yes, I find the program doesn’t quit cleanly sometimes. I think it’s the serial iterator thread getting hung up, but I can’t be sure.
2) Your code was trying to put the time label into the temperature label widget. Under the label.pack(anchor='nw')
code, I added two lines of code to my original program:
timelabel = Label(root) timelabel.pack(anchor='nw')
and I changed the get_temp function to read:
def get_temp(): # LM35 reading in °C to label selection = "Temperature: %6.1f °C" % (pin0.read() * 5 * 100) label.config(text = selection) timelabel_text_time = (datetime.now().strftime('%b %d %H:%M:%S\n')) timelabel.config(text = timelabel_text_time) root.after(500, get_temp) # reschedule after half second
So the function isn’t quite just updating the temperature any more. Clean code? Maybe not. It works, though.
Tk’s pack() geometry manager is weird. For anything more than a couple of widgets, I recommend grid(), which is much more logical.
Hi Stewart,
I have been working quite a bit with PyFirmata for my console-based command program and I also had been experiencing serial-port issues after exiting my PyFirmata programs. I’ve looked over several examples throughout the web and took at peek at the source as well and after reading the comment above, I think I may be able to offer some help on how I cleanly exit a PyFirmata script.
There appears to be another overlooked/undocumented function that seems to ‘cleanly’ destory the board object and restore the serial port.
I use the following line in my except: blocks just in case there is an error while troubleshooting and also before my destroy() calls so the USB port will be left tied up:
board.exit() # properly exit pyfirmata board instance and restore serial port
Hope this helps!
Matt
Thanks, Matt — I’ll certainly try that.
Leave a Reply