scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Python Tkinter GPIO User Interface

Wed Apr 24, 2013 9:04 am

Hi

I've written a tkinter based GUI for viewing the state of GPIO pins, setting the output high/low and setting the pin as an input or output.

The code is pretty basic (and lacking comments) at the moment but its has proved invaluable for debugging Raspberry Pi projects. Only requirement is the RPi.GPIO module.

[18 Feb 2015 Edit] - Source code now on GitHub https://github.com/scotty3785/python/bl ... UI/gpio.py

Image

Hope someone finds it useful
Last edited by scotty101 on Tue Dec 06, 2016 11:58 am, edited 4 times in total.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

simplesi
Posts: 2327
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
Contact: Website

Re: Python Tkinter GPIO User Interface

Wed Apr 24, 2013 9:59 am

Looks very useful code base :)
Ta
Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Wed Apr 24, 2013 7:06 pm

Revision 0.2

I've updated the code to add a simulated LED widget to show the current state of the GPIO pin.

[18 Feb 2015 Edit] - Source code now on GitHub https://github.com/scotty3785/python/bl ... UI/gpio.py

Changes
  • Added LED Widget to show the current state of the LED
  • There is actually some comments in the code
  • Ability to invert the state of inputs if there is a pull up resistor in the circuit
  • Runs GPIO "clean up" when the window is closed.
Last edited by scotty101 on Wed Feb 18, 2015 9:15 pm, edited 2 times in total.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

paully323
Posts: 1
Joined: Fri Apr 26, 2013 10:23 pm

Re: Python Tkinter GPIO User Interface

Fri Apr 26, 2013 10:30 pm

Where can I download the code?

User avatar
DeeJay
Posts: 2027
Joined: Tue Jan 01, 2013 9:33 pm
Location: East Midlands, UK

Re: Python Tkinter GPIO User Interface

Sat Apr 27, 2013 7:07 am

paully323 wrote:Where can I download the code?
Click on New Code in the previous post - it's a link.
How To Ask Questions The Smart Way: http://www.catb.org/~esr/faqs/smart-questions.html
How to Report Bugs Effectively: http://www.chiark.greenend.org.uk/~sgtatham/bugs.html

Spong23
Posts: 20
Joined: Wed Sep 19, 2012 2:42 pm

Re: Python Tkinter GPIO User Interface

Wed May 15, 2013 2:56 pm

Thanks very much scotty101 this is a really useful piece of software.
I'm an experienced electronics engineer and want to use the RPi as a host controller for a data acquisition/process control system and have learnt the basics of python. The next step was to try to use tkinter to create a simple visual diagnostic/control panel but after considerable time thinking how to do it and getting nowhere I came across this thread.
I'm much obliged to you,many thanks and well done.

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Thu Jun 27, 2013 1:45 pm

Very welcome. It has become invaluable for debugging my own projects.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

LloydSeaton
Posts: 5
Joined: Sun May 19, 2013 7:52 am

Re: Python Tkinter GPIO User Interface

Sat Jul 27, 2013 2:23 am

Greatly appreciative of your contribution as I'm completely new to Python and Tkinter but was able to hack a usable/useful derivative from your program to help in testing some of my PCBs of the piCocktails series. Thank you very much indeed! The following is a link to my derivative program on Google Drive in case somebody wants to download and try it:
https://docs.google.com/file/d/0B7RZGwt ... sp=sharing

LloydSeaton
Posts: 5
Joined: Sun May 19, 2013 7:52 am

Re: Python Tkinter GPIO User Interface

Thu Aug 01, 2013 10:17 am

I've improved on my previously posted program for examining/changing RasPi GPIO ports and posted it for public access as follows:
https://docs.google.com/file/d/0B7RZGwt ... sp=sharing
Main difference is that you can now control all of the GPIO ports but they remain passive until called upon to change.

spoolboyy
Posts: 23
Joined: Sat Mar 03, 2012 10:13 pm

Re: Python Tkinter GPIO User Interface

Thu Aug 01, 2013 5:08 pm

Thanks, what a great little app! This will make an excellent debugger tool.

- A

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Tue Aug 13, 2013 2:46 pm

LloydSeaton, Great updates. I had added some Pull Up/Down capability too.
I like the passive mode and will add that to my version too.
I'm very pleased to see my 1hour code "hack" being used by people.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Wed Feb 25, 2015 7:30 pm

Image

Source code now on GitHub https://github.com/scotty3785/python/bl ... UI/gpio.py

The latest version has some new features
  • Supports the 3 different GPIO revisions and will autodetect to display the correct version.
  • Shows (and disables) the GPIO pins currently assigned in an alternate function e.g. SPI
Attachments
2015-02-25-192503_690x476_scrot.png
2015-02-25-192503_690x476_scrot.png (34.62 KiB) Viewed 28455 times
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

User avatar
RogerW
Posts: 284
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Python Tkinter GPIO User Interface

Thu Feb 26, 2015 4:58 pm

A very nice piece of work and useful!

Roger Woollett

kcranley
Posts: 16
Joined: Fri Jan 20, 2012 10:33 am

Re: Python Tkinter GPIO User Interface

Wed Apr 01, 2015 10:29 am

This looks like an extremely useful GUI. It would be nice to do something similar for the Raspberry Pi Camera (control settings, take pictures etc).
Good work!

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Wed Apr 01, 2015 12:07 pm

Buy me a camera and I'll do it :D
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

SinewaveMan
Posts: 12
Joined: Sun Jul 19, 2015 5:17 am

Re: Python Tkinter GPIO User Interface

Sat Aug 01, 2015 10:25 am

Thank you scotty101 for this very useful application. I am new to Rpi and Python but have a few years with VBA. I am busy planning some time lapse photographic control apps and will use your inspirational "invention".

I do have two questions and don't know if this is the right place, but here goes:

1) During operation of your application, after a mouse click, the cursor (little arrow) disappears until I move the mouse. Is this something to do with the imported Tkinter, or can it be corrected in the Python code? Or is it maybe something to do with my USB drivers (I'm using a cable USB mouse).

So now I have found that it is NOT a problem with Tkinter or the USB drivers. In the topic "mouse pointer disappears" it is suggested to change the name of /usr/share/icons/Adwaita. This fixes the disappearing problem, but I don't know if this could cause other problems.

2) This is more to do with general Python operation, but where does Python find the "import" files? Namely Tkinter or tkinter.
Last edited by SinewaveMan on Sat Aug 01, 2015 5:35 pm, edited 1 time in total.

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Sat Aug 01, 2015 5:31 pm

1. Does this happen with all python tkinter GUIs?

2. Try this to find out where they are installed http://stackoverflow.com/questions/2697 ... le-sources
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

SinewaveMan
Posts: 12
Joined: Sun Jul 19, 2015 5:17 am

Re: Python Tkinter GPIO User Interface

Sat Aug 01, 2015 5:42 pm

scotty101 wrote:1. Does this happen with all python tkinter GUIs?
[/url]
I guess probably "yes". But see my "edit" above. It is evidently a "bug" in the raspbian code because it happens in many other places too. For example while using Chromium browser the cursor often disappears when I click on some text. Then it re-appears when I move the mouse. BTW: I love your tkinter - will be studying the usage in depth!

Co Termors
Posts: 12
Joined: Fri Mar 25, 2016 10:58 am

Re: Python Tkinter GPIO User Interface

Fri Mar 25, 2016 12:00 pm

Scotty101 and Lloys Seaton,

We thank you so much for your wonderful GPIO programs. They go a long way to setting up a Relay Control program we're trying to develop to possibly control a model railroad setup.

We're both rookies at Python. Thanks to your program we are now able to activate all four relays and read all four inputs using GPIO 17,18,27 and 22 for outputs, and GPIO 23,24,25 and 4, for inputs. We were able to modify the program labels to show Relays and Inputs, and control the Relays via Menu clicks, and alter the LED in response to Inputs.

Our next step has been a total failure so far under either of your wonderful Tkinter GPIO programs. We want to activate each of the relays, automatically via the program as a result of an input on one of the four input ports, without having to click on the menu. Something like the fan automatically coming on in the cooling system of a car, when the engine gets too hot).

The variety of errors we've managed to trigger is impressive and usually 4 or 5 of them at once, varying from 'the GPIO port has not been set' to complaints about global variables not set, but nothing has ever started the fan. We've tried to adapt 6 or 7 different programs out there, all to no avail.

We've been able to do this quite successfully in Python, but have hit a brick wall within the Tkinter menu system.

Can either of you suggest a way to do this? Your help would be greatly appreciated.

Co Termors

zjjackson101
Posts: 2
Joined: Tue Nov 17, 2015 8:49 pm

Re: Python Tkinter GPIO User Interface

Tue Jul 10, 2018 7:56 pm

Hi i am trying to use this to debug some python scripts.

I opened your gpioGUI using python3 gpioGUI.py

then in my editor on the pi(Thonny) i ran my script which basically sets pins as high or low based on my input. I can see that the pins are changing on my scope however the gpioGUI does not update to match the pins new state.

Is gpioGUI only for control? ie i cant use it to monitor pin state when testing other scripts?

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Thu Jul 26, 2018 1:46 pm

zjjackson101 wrote:
Tue Jul 10, 2018 7:56 pm
Hi i am trying to use this to debug some python scripts.

I opened your gpioGUI using python3 gpioGUI.py

then in my editor on the pi(Thonny) i ran my script which basically sets pins as high or low based on my input. I can see that the pins are changing on my scope however the gpioGUI does not update to match the pins new state.

Is gpioGUI only for control? ie i cant use it to monitor pin state when testing other scripts?
Sorry I didn't see this.
As my program uses RPi.GPIO, it will expect "exclusive" use of the GPIO pins so won't play nicely with other programs using it. I should make a pigpiod version of the program to solve this problem but I've never got round to it.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

User avatar
RogerW
Posts: 284
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Python Tkinter GPIO User Interface

Thu Jul 26, 2018 3:02 pm

This is a more primitive monitor but does use pigpio. You can run it on the same machine (localhost) or over a network.

Code: Select all

# PyMon.py
# Program to monitor GPIO pins on a raspberry pi
# can be run on the pi or a remote machine
# It uses pigpio and needs the pigpiod deamon 
# to be running on the target machine.
# Change the host variable to suit your needs.
# If you are running the monitor on the pi
# use 'localhost'
# written by Roger Woollett

import sys

if(sys.version_info[0] < 3):
    import Tkinter as tk
    import ttk
    import tkMessageBox as mb
    import tkSimpleDialog as sd
else:    
    import tkinter as tk
    import tkinter.ttk as ttk
    import tkinter.messagebox as mb
    import tkinter.simpledialog as sd

import socket as s
import pigpio as pg

# pigpiod daemon location
# This really should be configured by user
host = 'boromir'
port = 8888

REFRESH_RATE = 200  # msec between updates
COLS = 5            # columns in display
TITLE = 'Python GPIO Monitor'

# Pins to test (Broadcom,physical)
# N.B. this list is for B+ & A+ earlier pis do not have so many pins
pins = ((2,3),(3,5),(4,7),(5,29),(6,31),(7,26),(8,24),
        (9,23),(10,19),(11,23),(12,32),(13,33),(14,8),
        (15,10),(16,36),(17,11),(18,12),(19,35),(20,38),
        (21,40),(22,15),(23,16),(24,18),(25,22),(26,37),(27,13))

class Config(sd.Dialog):
    def __init__(self,master,msg,*args,**kwargs):
        
        self.msg = msg + '\nPress OK to reconfigure, Cancel to end\n'
        
        # body is called by base class __init__
        # so call it after self variables are set
        sd.Dialog.__init__(self,master,*args,**kwargs)
                        
    def body(self,master):
        # I am not sure why fist param is master not self
        ttk.Label(master,text = self.msg).grid(row = 0)
        ttk.Label(master,text = 'Host:').grid(row = 1,column = 0,sticky = tk.E)
        ttk.Label(master,text = 'Port:').grid(row = 2,column = 0,sticky = tk.E)
        
        global host
        self.s1 = tk.StringVar()
        self.s1.set(host)
        self.e1 = ttk.Entry(master,textvariable = self.s1)
        self.e1.grid(row = 1,column = 1)
        
        global port
        self.s2 = tk.StringVar()
        self.s2.set(port)
        self.e2 = ttk.Entry(master,textvariable = self.s2)
        self.e2.grid(row = 2,column = 1)
        
        return self.e1
        
    def apply(self):
        global host
        global port
        global restart
 
        host = self.e1.get()
        port = int(self.e2.get())
        restart = True
        
# A round 'light' that is red if the pin is high (on)
class Light(tk.Canvas):
    def __init__(self,master,*args,**kwargs):
        tk.Canvas.__init__(self,master,*args,**kwargs)
        
        self.id = self.create_oval(5,5,15,15,fill = 'white')
        
    def off(self):
        self.itemconfigure(self.id,fill = 'white')
        
    def on(self):
        self.itemconfigure(self.id,fill = 'red')
        
# A frame for the widgets that show one pin
class PinFrame(tk.Frame):
    def __init__(self,master,pin,phys,*args,**kwargs):
        tk.Frame.__init__(self,master,*args,**kwargs) 
        
        self.pin = pin
        self.mask = 1<<pin
        self.high = False
        
        # create a label (shows GPIO with physical pin no in brackets)
        self.lab = ttk.Label(self,width = 11,
                             text = 'GPIO ' + str(self.pin) + '(' + str(phys) + ')')
        self.lab.grid(row = 0,column = 0)
        
        # create a Light
        self.light = Light(self,height = 20,width = 30)
        self.light.grid(row = 0,column = 1)
    
    # check to see if state has changed and switch light if needed             
    def check(self,mask):
        now = mask & self.mask
       
        if(now != self.high):
            self.high = now
            if(now):
                self.light.on()
            else:
                self.light.off()
    
# a Mainframe object contains the widgets that make up the user interface              
class Mainframe(tk.Frame):
    def __init__(self,master,*args,**kwargs):
        tk.Frame.__init__(self,master,*args,**kwargs)
        
        no = len(pins)
        self.pinframes = []
        
        # lay out the frames that show pin status
        i = 0
        row = 0
        while(i < no):
            for col in range(COLS):
                if i < no:
                    pf = PinFrame(self,pins[i][0],pins[i][1])
                    pf.grid(row = row,column = col)
                    self.pinframes.append(pf)
                    i += 1
            row += 1
        
        # I like to have a quit button
        ttk.Button(self,text = 'Quit',command = master.onQuit).grid(row = 10)
        self.getpins()
    
    # called every REFRESH_RATE msec to update the display
    def getpins(self):
        mask = pi.read_bank_1()
        
        for i in range(len(self.pinframes)):
            self.pinframes[i].check(mask)
            i += 1
            
        # set up the next call
        self.after(REFRESH_RATE,self.getpins)
    
# a single App object represents the program itself
# it has a Mainframe which handles the UI
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        
        # trap close (X) button so we can cleanup
        self.protocol('WM_DELETE_WINDOW',self.onQuit)
        
        # do cosmetics to main window
        self.title(TITLE)
        
        # check to see if we can talk to the pigpio daemon
        if(not self.checkdaemon(host,port)):
            self.onQuit()
            return
        
        # if we get here we think all is well so create the pi object
        global pi        
        pi = pg.pi(host,port)
        
        Mainframe(self).grid()
        
    def checkdaemon(self,host,port):
        # check to see if the target machine is on the network
        # and the demon seems to be running
        # returns False if there is an error        # first see if host is on network
        try:
            # n.b.on a raspberry pi this can take a long time to fail
            s.gethostbyname(host)
        except:
            #mb.showerror('pigpio',"Cannot find host " + host)
            self.withdraw()
            Config(self,"Cannot find host " + host)
            # abort program
            return False
        else:
            # now see if daemon is running
            try:
                sock = s.create_connection((host,port))
            except:
                #mb.showerror('pigpio',"Daemon not running on" + host)
                self.withdraw()
                Config(self,"Daemon not running on port " + str(port))
                return False
            else:
                sock.close()
        return True
        
    # clean up and exit
    def onQuit(self):
        self.destroy()
        if(pi != None):
            pi.stop()

restart = True
while restart:
    restart = False
    # communicates with pigpiod running on the
    # raspberry pi.
    pi = None
    
    # create an App object and execute its main loop
    App().mainloop()
The comments say you should change the code to define the host but actually it will prompt you.
Let me know if you have problems.

peterm2
Posts: 39
Joined: Wed Jun 27, 2012 7:46 pm
Location: Dorset

Re: Python Tkinter GPIO User Interface

Tue Jan 29, 2019 5:00 pm

Hi, I didn't realise that this was so old. I am trying to develop a Web based interface to a R-PI to drive an RC-car using flask and not having much luck at the moment. I came acrss this and have loaded it on Raspbian Stretch, but it gives me the follwong error messages.

I would appreciate any thoughts on it.
[email protected]:~/rc-car $ python gpio_gui.py
Traceback (most recent call last):
File "gpio_gui.py", line 278, in <module>
main()
File "gpio_gui.py", line 267, in main
root = Tk()
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1823, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
[email protected]:~/rc-car $

Oh- I named the file gpio_gui. It looks like tkinter has changed since you wrote it. Also I am running it over an ssh connection.

Thanks for any thoughts.
PM

scotty101
Posts: 3649
Joined: Fri Jun 08, 2012 6:03 pm

Re: Python Tkinter GPIO User Interface

Tue Jan 29, 2019 5:02 pm

Tkinter hasn't changed.... Most of it was written circa 1998...

How did you open your SSH connection? Did you use the ssh -X [email protected] syntax?
Without the -X, tkinter doesn't know what screen to show the GUI on. I have had it working via SSH before.

With regard to flask, you may find my pi_tv_remote project helpful.
https://github.com/scotty3785/pi_tv_remote
It at the moment sends a command to LIRC but it could very easily be adapted to control GPIO pins.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

peterm2
Posts: 39
Joined: Wed Jun 27, 2012 7:46 pm
Location: Dorset

Re: Python Tkinter GPIO User Interface

Thu Jan 31, 2019 4:32 pm

Thanks Scotty for your reply. I have sorted my display problem using https://www.w3schools.com/css/css_grid.asp
to create an HTML grid instead of python.

I have resolved(?) another problem that the R-Pi kept hanging after I had just connected to it. I tried my other PI and it kept on going, so I suspect this Pi is failing somewhere.

I'll look at your other thing later. Thanks for posting it. Once I get finished documenting my current status and testing it on the car, I'll get to work on eliminating the AP and running in Ad-hoc mode if I can.

Peter

Return to “Python”