Universal GPIO keyboard daemon


131 posts   Page 1 of 6   1, 2, 3, 4, 5, 6
by mmoller2k » Wed Jan 16, 2013 8:23 pm
I've just finished building my mame cabinet using Shea Silverman's PiMAME, and needed a GPIO driver for my custom keys and joystick, so I wrote one.
It has a config file in which you can define which GPIOs should emit which keyboard key sequences using uinput.
It polls and debounces the keys using about 1% of the RPi's CPU.
You can get it at https://github.com/mmoller2k/pikeyd

It's probably useful for more than just mame...
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by mmoller2k » Thu Jan 17, 2013 4:40 am
Here's a picture of my hand crafted mame box.
mamebox.jpg
Mame box
mamebox.jpg (56.6 KiB) Viewed 12175 times
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by Conner Labs » Thu Jan 17, 2013 10:09 pm
Nice... I'm looking for something like this to control my music player. I started out with the guts of a USB keyboard, but I couldn't get glitch free audio as long as I had any USB1.x devices in the system, so I had to scrap that approach.
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm
by PhillyNJ » Fri Jan 18, 2013 12:16 pm
This is great. So I downloaded the zip file, unpacked and ran "sudo make". I still have to hook up my GPIO, but wanted to ask if there is anything else I need to do?

Thx
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by Conner Labs » Fri Jan 18, 2013 1:59 pm
Probably "make install" and also figure out how the buttons are supposed to connect to the GPIO lines. Do they pull up to 3.3V or down to ground when pressed, are pullup/down resistors required, etc.

You may also need to "modprobe uinput" as it requires the uinput kernel module.
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm
by mmoller2k » Sat Jan 19, 2013 11:55 am
I did not add a 'make install'. A simple make will build one executable called pikeyd. Copy this wherever you want - perhaps /usr/local/bin.
Yes, it needs the uinput module. Load this manually with 'modprobe uinput', or automatically by adding 'uinput' to /etc/modules.
Then you need to run it as root, with perhaps the -d switch to make it ran as a daemon. Adding the line '/usr/local/bin/pikeyd -d' to /etc/rc.local makes it run as root at boot time.
The pins require pull-up resistors to 3V3 of 10k ohm, and the switches pull down. A 1K resistor in serial with the pin for protection doesn't hurt.
You define which pins does what by editing /etc/pikeyd.conf. One gpio pin can be defined to emit a series of characters as if it was a keyboard. That makes it compatible with whatever functions you want to control on whatever software - as long as it accepts keyboard input of course.
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by Conner Labs » Sat Jan 19, 2013 12:31 pm
Yay! Got it working. Thanks for sharing your code, mmoller. I'm hoping to hack it to map a rotary encoder to the arrow keys.

I found that I didn't need to modprobe uinput, so maybe Raspbian loads it already.
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm
by PhillyNJ » Sat Jan 19, 2013 1:57 pm
Not sure what I am doing wrong.

I compiled with "make" which makes the pikeyd file and I make it executable.

my config is located in /etc/pikeyd.conf

I load the module with:

Code: Select all
sudo modprobe uinput


To test, I want KEY5 to map to GPIO 25

Code: Select all
KEY_ESC 7
KEY_5 25
KEY_1 8
KEY_2 11
#KEY_ENTER 11


When I execute pikeyd, I see:

Code: Select all
Config file is /etc/pikeyd.conf
init uinput
Joystick init OK.


I run advmame [game] and press the button. The key 5 is for credits. Nothing happens.

My bread board:

Image

Any help would be appreciated. Maybe Advmame doesn't like how the keys are entered? As a note, I tested the GPIO port with a simple python script and its wired up correctly.
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by Conner Labs » Sat Jan 19, 2013 3:13 pm
I found that if any GPIO pins are assigned in the config file, but left floating in hardware, pikeyd will get confused and output garbage or nothing at all. This is understandable, as a floating pin could generate huge amounts of spurious "keystrokes".

If you only have "5" connected, then try removing everything but "5" from your config file.

Also remember that two of the GPIOs are actually a RS232 interface carrying kernel debug output. Can't say which off hand.

I got my rotary encoder working. :D
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm
by PhillyNJ » Sat Jan 19, 2013 4:34 pm
Thanks - got it to display "5" in the console but Advmame is not liking it.. Trying PiMame. I'll keep you posted
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by mmoller2k » Sat Jan 19, 2013 6:10 pm
That's a good point. Don't configure pins in pikeyd.conf that you are not using. Floating inputs are never a good a idea.
It is strange that you can get keys in the console which don't work in the application. I really have no idea what might cause that.
Did you compile natively or use the cross-compile option?
Connor Labs: How about a picture of your rotary switch setup. Sounds interesting.
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by PhillyNJ » Sun Jan 20, 2013 12:33 am
So I think my issue is with Advmame. I am able to get my key presses to the command line with both pikeyd and uinput. Is there a setting in Advmame?
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by mmoller2k » Sun Jan 20, 2013 7:07 am
I'm using advmenu and advmame from PiMAME with no issues. Advmame is configured in /home/pi/.advance/advmame.rc
It contains a number of input_map lines. Mine are all set to 'auto'. Maybe you changed these to something else?
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by PhillyNJ » Sun Jan 20, 2013 12:57 pm
hmmm can you post your .rc file? I may have messed it up.
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by PhillyNJ » Sun Jan 20, 2013 4:45 pm
hmmm I think I give up...

Image
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by Conner Labs » Sun Jan 20, 2013 9:32 pm
pitunes1.jpg
pitunes1.jpg (21.86 KiB) Viewed 11834 times

9 buttons and a rotary encoder all working nicely 8-)
The rotary encoder is a Grayhill 62A22. I modified the code a bit to handle it.
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm
by PsHouse » Mon Jan 21, 2013 1:51 pm
Can someone provide a diagram of how the resistors should be connected?
(Electronics newbie ) :)
Posts: 3
Joined: Mon Jan 21, 2013 1:49 pm
by PhillyNJ » Mon Jan 21, 2013 3:38 pm
See my pick of the breadboard above. The Red wire goes to 3.3V
Posts: 109
Joined: Sat Dec 29, 2012 4:07 am
by PsHouse » Mon Jan 21, 2013 5:30 pm
So one side of the switch goes to 3.3v with the resistor and the other side to the correct GPIO? Apologies if my questions sound stupid
Posts: 3
Joined: Mon Jan 21, 2013 1:49 pm
by mmoller2k » Tue Jan 22, 2013 8:06 am
Like this:
gpio.png
gpio.png (9.16 KiB) Viewed 11724 times
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by mmoller2k » Tue Jan 22, 2013 10:19 am
Ascii version :-) I was going to post this first, but didn't know I could mono-space the font.
Code: Select all
           ______       _______
GPIO >----|__1K__|--+--|__10K__|----< +3V3
                    |
                    |
                    o |
                      |=#
                    o |
                    |
                    |
 GND >--------------+
Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by PsHouse » Tue Jan 22, 2013 1:07 pm
Thank you Sir for your patience and diagram. Keep up the GREAT work :)
Posts: 3
Joined: Mon Jan 21, 2013 1:49 pm
by atvdude01 » Wed Jan 23, 2013 10:40 pm
could this work with the inputs of a MCP23017? its the i2c 16 i/o expander.... starting a small project with converting an old ps1 arcade stick for the pi... wanted to have all the major buttons and wanted to use the i/o expander to reduce the amount of wires from pi to controller. also could u have it so depending on an input/a couple inputs it changes key maps for different emulators? i only know python so cant really edit for my needs....
Posts: 21
Joined: Wed Oct 03, 2012 8:01 pm
by scootn405 » Thu Jan 24, 2013 2:09 pm
Ditto. I want to eventually use two MCP23017 instead the on-board GPIO pins for something like a 2 player fighter with 6 or 4 buttons per player plus the 4 switches for each joystick. Just trying to get started with GPIO for now with some classic games.
Posts: 2
Joined: Wed Jan 02, 2013 4:44 pm
by Conner Labs » Fri Jan 25, 2013 12:39 pm
Don't see why not. The R-Pi has an I2C interface and C bindings for it. Just mix mmoller's code with something like this:
http://binerry.de/post/27128825416/rasp ... uino-slave

You could treat it as an opportunity to learn C :-)

Alternatively, look for Python bindings for uinput, and reimplement in Python.

Using I2C may increase the required CPU resources a bit, using Python instead of C certainly will.
Posts: 26
Joined: Fri Jan 11, 2013 2:45 pm