Created
October 3, 2019 07:38
-
-
Save pondahai/d226bb059865c098cc05095c1da8718c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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