turning gpio buttons into keys


32 posts   Page 1 of 2   1, 2
by Tenocticatl » Fri Jan 11, 2013 11:24 pm
Hello, I'm a complete newb to programming, and I think I've bitten off more than I can chew.

I'm using my Pi as a media center, and I wanted to install some basic hardware controls on the casing.

Now, from various tutorials I've gotten as far as this:

Code: Select all
#!/usr/bin/env python

from time import sleep
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)

while True:
        if ( GPIO.input(23) == False ):
                [do something]
        sleep(1);


Thing is, I would like the 'do something' bit to be something like 'pretend the up arrow key is pressed', but I can't find how to say that in Python. This leads me to believe it's either really easy, or really hard.

Can it be done? Can you tell me how? Also, if it can be done, I'd like to run the script all the time, from startup. And I also use the GPIO to control a character LCD through lcdproc, can I use these things together, or do they conflict?
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by cae2100 » Sun Jan 13, 2013 8:33 pm
I did something like this a while back, but for a game controller, and used python-uinput from here to translate the button presses to keyboard keys, for use in the python game. Here's the link for the python-uinput:
http://tjjr.fi/sw/python-uinput/
hope this helps.
If it isnt smoking and blown into pieces, it's not pushed far enough yet. :P
http://cae2100.wordpress.com
Posts: 142
Joined: Tue Jan 08, 2013 10:35 am
by cae2100 » Sun Jan 13, 2013 9:44 pm
sorry for two posts, but remembered something to mention, dont forget to add button debouncing after the command otherwise it'll just spam the key while the button is pressed down. a simple debounce can be achieved by using:

time.sleep(0.1)
If it isnt smoking and blown into pieces, it's not pushed far enough yet. :P
http://cae2100.wordpress.com
Posts: 142
Joined: Tue Jan 08, 2013 10:35 am
by -rst- » Mon Jan 14, 2013 2:53 pm
I remember seeing on this forum someone implementing a lcd menu system (seems like the OP is after something like this) in Python ...here viewtopic.php?f=32&t=23375.

So seems doable - as long as the inputs/outputs (pins) for the buttons and the lcd don't overlap there should be no issues.

Obviously you would then want to control the media player application? Just answered someone asking how to control mixer from Python - search...

And there are numerous threads about running scripts 'at startup', 'at boot', 'at login'...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Wed Jan 23, 2013 10:53 pm
Thanks for the replies, the info might be useful.

I'm using raspbmc. XBMC has its own python interpreter as it turns out, and the whole system seems to be rather particular about how you add functionality. I'm still not entirely sure what is easier; trying to use the xbmc stuff, or trying to work around it (in the last case I may be able to use the uinput stuff). The thing that seemed the most straightforward:

Code: Select all
from time import sleep
import xbmc
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.IN)
GPIO.set_falling_event(22)

if GPIO.event_detected(22):
   xbmc.ExecuteBuiltin(right)
sleep(1);


didn't work. But considering how much of a noob I am, I may have made an extremely obvious mistake.
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by -rst- » Thu Jan 24, 2013 12:51 pm
Hmm, that GPIO code should most likely run in a loop, so it does not exit before you push the button...

If you break that up to it's parts ('read GPIO', 'command XBMC'), do either of them work alone?

Something along:
Code: Select all
import xbmc

xbmc.ExecuteBuiltin(right)
...could try first from the interactive Python interpreter

and

Code: Select all
from time import sleep
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.IN)
GPIO.set_falling_event(22)

# loop forever (or until Ctrl-C hit)
while True:
    if GPIO.event_detected(22):
        print "Button pressed" # or print("Button pressed")

    sleep(1);

http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Thu Jan 24, 2013 11:51 pm
Thanks, good advice.

The GPIO part works fine (from the ssh command line), like this:
Code: Select all
import RPi.GPIO as GPIO
import time
GPIO.setmode(BCM)
GPIO.setup(22, GPIO.IN)
while True:
    if ( GPIO.input(22) == False )
             print("Button pressed")
    time.sleep(0.2); #so I don't have to keep it pressed for too long.

Wasn't really expecting a problem there.
I had to install RPi.GPIO, python-dev and gcc though (don't know what that last one does), through apt-get.

My problem is in getting it to work inside raspbmc. XBMC gives a 'failed to run script' message when I boot up, so it at least notices the script. In command line, trying to run the 'executebuiltin' part gives 'ImportError: No module named xbmc'. Maybe installing python-dev overwrites the xbmc-specific modules? That would suck. Is there any way to check that / (re)install those modules? If there isn't, I'll probably try the uinput method.
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by -rst- » Fri Jan 25, 2013 10:28 am
Are you sure you use the same Python version 'in command line' as with IDLE (I assume the other option use are using is)?

Some Python libraries seem to be only installed for 'python' (2.x, 'IDLE') and not for 'python3' (3.x, 'IDLE3') - maybe some the other way around...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Fri Jan 25, 2013 11:11 am
No, I'm not sure. I don't know about IDLE. There's very little info about what xbmc actually uses to do python, and there isn't anything I can do from within the XBMC gui except see what addons are installed.

On their wiki, it says that its python interpreter is based on Python 2.4, which is definitely something different from what 'apt-get install python-dev' installs (either 2.7 or 3, can't recall). Where can I see which modules are installed?
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by -rst- » Fri Jan 25, 2013 2:04 pm
Ah, I didn't realise you were on Raspbmc - so no wonder no IDLE ;)

Doesn't the Python interpreter output the version info when started in interactive mode? If not, maybe try 'python --version'?

There is a way to see what packages are installed, but can't remember from the top of my head, sorry.

Raspbmc have their own sub-forum here and also their very own forum http://www.raspbmc.com/forum/
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Fri Jan 25, 2013 10:53 pm
Yeah, their forum hasn't been any help so far. Python version seems to be okay; all 2.x. I think the problem is that XBMC wants you to install additional Python modules in a specific folder (i.e., ~/.xbmc/scripts/python/Lib). If you install the RPi.GPIO module (with apt-get or 'python setup.py install'), it automatically installs it in some standard python folder (I think /usr/lib/blablabla), and I don't know if you can change that. Or what the relevant files are, so I could move them after installation.
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by -rst- » Sat Jan 26, 2013 5:58 pm
Unfortunately I don't know XBMC, but I would be somewhat surprised if it required all the python libs in that special folder - I'd assume that's the place for 'XBMC extension libs', so your script should most likely go there, but the script should be able to access standard libs from standard place ...of course I could be wrong :oops:
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by thivtulz » Tue Jan 29, 2013 7:01 am
When i run my code i get this error..(gpio.py:4: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(21, GPIO.OUT)..

Please help me to solve this problem.thanks. :(
Posts: 56
Joined: Tue Dec 18, 2012 10:05 am
by -rst- » Tue Jan 29, 2013 10:32 am
That is a known issue with the RPi.GPIO module - it just warns you that some program has already opened the same GPIO pin and if you would happen to have two programs accessing the same pin, you might get erratic behaviour.

Most likely it is just that your script has not properly cleaned up on previous run, so should not be a problem and you can ignore the message.

To avoid this message, at the end of your script before exiting you should call GPIO.cleanup()
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by thivtulz » Wed Jan 30, 2013 1:34 am
This is my coding.My objective is i want to control the LED lights and switch that connect to the raspberry pi board.
Code: Select all
from Tkinter import *

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.setup(7, GPIO.IN)
def hi_there():
   print "Lighting up LED"
   GPIO.output(8, GPIO.OUT)
   
      
def check_button():
   if (GPIO.input(7) == GPIO.IN):
      labelText.set("Button Pressed.")
   else:
      labelText.set("")
   root.after(10,check_button)
   
root = Tk()
button = Button(root, text="Quit.", fg="red", command=quit)
hi_there = Button(root, text="Light my LED!", command=hi_there)
hi_there.pack(side=LEFT, padx=10, pady=10, ipadx=10, ipady=10)
labelText = StringVar()
labelText.set("Button Pressed.")
label1 = Label(root, textvariable=labelText, height=4)
label1.pack(side=LEFT)
root.title("LED Blinker")
root.geometry('500x300+200+200')
root.after(10,check_button)
 
Posts: 56
Joined: Tue Dec 18, 2012 10:05 am
by thivtulz » Wed Jan 30, 2013 1:45 am
This coding also same but i used gtk modules.Here the problem is when i clicked the button the LED didn't response.Here my objective is when i pressed the attached switch the LED must response.Help me to solve the problems.Thanks

Code: Select all
import pygtk
import gtk
import RPi.GPIO as GPIO


GPIO.setmode(GPIO.BOARD)
GPIO.setup(21, GPIO.OUT)
GPIO.setup(22, GPIO.IN)

class toggle:

      
   def callback(self,widget,data):
      print "%s was toggled %s" % (data, ("OFF","ON")[widget.get_active()])

   
   def delete_event(self,widget,event,data=None):
      gtk.main_quit()
      return gtk.FALSE

   def __init__(self):
               
      self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
      
      self.window.set_title("Toggle Button")

      self.window.connect("delete_event",self.delete_event)
      
      self.window.set_default_size(100,100)
         
      self.window.set_border_width(20)
      
      self.button = gtk.ToggleButton("Toggle Button")
      
      self.button.connect("toggled",self.callback,"Toggle Button")
      
      self.window.add(self.button)
   
      self.button.show()
      
      self.window.show()
   def main(self):
      gtk.main()

 


if __name__ == "__main__":
   togglebutton = toggle()
   togglebutton.main()
   
Posts: 56
Joined: Tue Dec 18, 2012 10:05 am
by -rst- » Wed Jan 30, 2013 6:38 pm
Did the Tk version work, but gave the warning? You could fix it by adding a function that does the GPIO cleanup and quits - replace the quit button to call this instead of directly quitting...

The Gtk version does not seem to call any code that lights the led or reads the switch... :roll:
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by thivtulz » Thu Jan 31, 2013 1:42 am
Thanks for your help.Now i'm facing another problem.I cannot display the output.After i run the code it's shows that"press enter to continue".That's all i cannot get the result.Help me.Is there any mistakes in my coding..

Code: Select all
from Tkinter import *

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.setup(7, GPIO.IN)

def hi_there():
   print "Lighting up LED"
   GPIO.output(8, GPIO.OUT)
   
      
def check_button():
   if (GPIO.input(7) == GPIO.IN):
      labelText.set("Button Pressed.")
   else:
      labelText.set("")
   root.after(10,check_button)
   
   
root= Tk()
button = Button(root, text="Quit.", fg="red", command=quit)
hi_there = Button(root, text="Light my LED!", command=hi_there)
hi_there.pack(side=LEFT, padx=10, pady=10, ipadx=10, ipady=10)
labelText = StringVar()
labelText.set("Button Pressed.")
label1 = Label(root, textvariable=labelText, height=4)
label1.pack(side=LEFT)
root.title("LED Blinker")
root.geometry('500x300+200+200')
root.after(10,check_button)

 
Posts: 56
Joined: Tue Dec 18, 2012 10:05 am
by -rst- » Thu Jan 31, 2013 11:09 am
Your code just 'runs through' and exits - looks like it does not even open the window properly (or maybe just exits too quick). You would need to look at some Tk examples how to create and display a window - and how to gracefully exit the application - do not put any GPIO code in yet. Look here http://docs.python.org/2/library/tkinter.html ...after you get that to work, add your own buttons and other functions - just print a 'debug message' like: 'check_button() called' ...and when all of that works, add the GPIO stuff in ...and if you haven't already done, might be best to create simple GPIO test app first to get those bits right...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Thu Jan 31, 2013 2:26 pm
Looks like my problem has to do with what permissions xbmc has; it hasn't got root permission, which means it can't access the gpio. On the openelec forum, someone used this as a solution:
I have one script called pwroff.py:
Code: Select all
import subprocess
import xbmc
xbmc.executebuiltin( "SetVolume(1,True)" )
xbmc.executebuiltin( "PlayerControl(Stop)" )
xbmc.executebuiltin( "ActivateWindow(Screensaver)" )
subprocess.call("sudo python /home/pi/.xbmc/userdata/pyscript/ledoff.py", shell=True)

then another script called ledoff.py:
Code: Select all
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.OUT)
GPIO.output(11, GPIO.HIGH)


I'll have to figure out how to make it work for inputs, but it seems promising.
Link to that thread: http://forum.stmlabs.com/showthread.php?tid=4293
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by -rst- » Thu Jan 31, 2013 2:43 pm
Tenocticatl wrote:I'll have to figure out how to make it work for inputs, but it seems promising.


You would most likely need to have the xbmc plugin to execute the GPIO script and get the output of that process - not sure if possible and polling for a button-press might be a bit awkward... maybe with os.popen().

I wonder if it would be easier to create a kind of 'communications plugin' on the xbmc side and have another application run in normal Python... Something like:

GPIO <<->> Python_app <<->> TCP/sockets <<->> Python-xbmc-plugin <<->> XBMC

...obviously provided that xbmc allows it.
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 898
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by Tenocticatl » Thu Jan 31, 2013 8:26 pm
So that the python app will notify the xbmc script when a button is pressed, basically? Yeah that might be the way to go.
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by ErikH » Sun Apr 07, 2013 7:15 pm
I was doing this by universal GPIO keyboard daemon from this article viewtopic.php?t=29962.
I was define new keys (F1, F2...) which are not used in XBMC and assign various function in different parts of xbmc navigation definition keyboard.xml in keymaps. They can act as arrow keys in general, but as play, stop... during video playback.
Posts: 5
Joined: Tue Apr 02, 2013 8:25 pm
by Tenocticatl » Sun Apr 14, 2013 4:16 pm
I'm confused, ErikH. Did you do this already, or was it a suggestion I might try?

I've moved to using a teensy, a microcontroller that can emulate a USB keyboard. Works quite well, but it is extra hardware.
Posts: 17
Joined: Fri Jan 11, 2013 11:11 pm
by cleverca22 » Mon Apr 15, 2013 4:53 pm
https://github.com/cleverca22/xorg

the code ive started in here may also be of use, its got seperate functions for press and release, so you could make the keys properly work when you hold gpio buttons
Posts: 168
Joined: Sat Aug 18, 2012 2:33 pm