Skip to content

Instantly share code, notes, and snippets.

@pondahai
Created October 3, 2019 07:38
Show Gist options
  • Save pondahai/d226bb059865c098cc05095c1da8718c to your computer and use it in GitHub Desktop.
Save pondahai/d226bb059865c098cc05095c1da8718c to your computer and use it in GitHub Desktop.
# GPIOkbd.py
# written by Roger Woollett
# modify by pondahai 2019.10.3
# This is a python equivalent to the Adafruit Retrogame program.
# It translates GPIO button presses into keyboard presses.
# It assumes that buttons will gound their GPIO when pressed.
# All testing has been done using python3
# This program must have root priviledge. This is fine if run from rc.local
# but if you are testing use sudo python3 GPIOkbd.py
# You must install uinport for this to work
# sudo pip3 install python-uinport
# Help(ui) shows a list of the symbols that represent keyboard keys.
# You can also define a button that causes system shutdown when pressed
# for more than 2 seconds.
import uinput as ui
import RPi.GPIO as gp
from os import system
from time import sleep
# create bindings between keys and gpio
# TODO - change this to suit your needs
bindings = ((ui.KEY_ENTER,20),(ui.KEY_SPACE,21),(ui.KEY_UP,16),(ui.KEY_RIGHT,19),(ui.KEY_LEFT,13),(ui.KEY_DOWN,26))
# define gpio for shutdown (exit) button
# comment out the last line of this program
# if you do not want to cause a system shutdown
# TODO change this to suit your needs
# if you do not want a shutdown key set to 0
SHUTDOWN_GPIO = 20
# make sure kernal module is loaded
system("modprobe uinput")
# always use Broadcom numbers
gp.setmode(gp.BCM)
oldkey = [1]*27
class KeyBtn:
# class to associate a GPIO button with a keyboard press
def __init__(self,device,key,gpio):
self.device = device
self.key = key
gp.setup(gpio,gp.IN,pull_up_down = gp.PUD_UP)
gp.add_event_detect(gpio,gp.BOTH,callback = self.callback)
def key_process(self, channel):
if gp.input(channel) == 0:
self.device.emit(self.key, 1)
else:
self.device.emit(self.key, 0)
# global oldkey
# sleep(0.04)
# gpinput = gp.input(channel)
# if gpinput != oldkey[channel]:
# sleep(0.1)
# if gpinput != oldkey[channel]:
# oldkey[channel] = gpinput
# if gpinput == 0:
# self.device.emit(self.key, 1)
# else:
# self.device.emit(self.key, 0)
def callback(self,channel):
# because of key bounce check button is really down
#print(oldkey)
#sleep(0.05)
self.key_process(channel)
class ExitBtn:
# class to implement a button that causes program to terminate
def __init__(self,gpio):
if gpio != 0:
gp.setup(gpio,gp.IN,pull_up_down = gp.PUD_UP)
self.gpio = gpio
def check_continue(self):
if self.gpio == 0:
return True
# return False if button pressed for longer than 2 seconds
count = 20
while count:
if gp.input(self.gpio):
# button is not pressed
return True
sleep(0.1)
count -= 1
# if we get here it is time to exit
return False
# create uinput device
events = []
for(key,gpio) in bindings:
events.append(key)
device = ui.Device(events)
# create KeyBtn objects
for(key,gpio) in bindings:
KeyBtn(device,key,gpio)
# This button causes program to exit
exit_button = ExitBtn(SHUTDOWN_GPIO)
# check if we should exit every half second
while exit_button.check_continue():
for(key,gpio) in bindings:
if gp.input(gpio) == 1:
device.emit(key,0)
sleep(0.5)
# All done so exit
device.destroy()
gp.cleanup()
#system("poweroff")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment