RetroPie config doesn't recognize custom gamepad joystick axes
-
Hi, I'm trying to get my custom controller working with Retropie and all the buttons are working fine, but my joystick axes aren't responding. I found similar issues here and on google but they don't seem similar enough to my situation. (Mainly, those people couldn't get jstest to work, but mine does).
========================
Pi Model or other hardware: Pi 3 A+
Power Supply used: Micro USB cable going into a 5V cellphone wall outlet adapter
RetroPie Version Used: 4.6
Built From: SD image from installation guide (https://retropie.org.uk/docs/First-Installation/); I think it's this file - https://github.com/RetroPie/RetroPie-Setup/releases/download/4.6/retropie-buster-4.6-rpi2_rpi3.img.gz
USB Devices connected: Only my gamepad (see below)
Controller used: Custom arduino pro micro (leonardo) gamepad + ninendo switch thumbstick (see below)
Error messages received: Joystick axes not responding in input configuration wizard========================
So, I'm making a custom gamepad controller using an arduino. I've wired up push button switches to the GPIO and I got a replacement nintendo switch thumbstick that I've also soldered into the arduino. I'm using NicoHood's HID library to make it recognizable by host devices as a gamepad.
I've got this working just fine on my Windows computer and it can recognize the joystick input in the properties window. I also have this working on the raspberry pi to some extent. When I use
jstest
, I can see it updating when I push buttons and when I move the controller:When I open the retropie menu and go to "Configure Input", the wizard won't let me bind any buttons to my analog stick. (I have the thumbstick tied to the x and y axes, a.k.a Axis 0 and Axis 1 in the jstest output above). As expected, I can't use the thumbstick to navigate menus or inside emulators either.
I guess there's something going wrong between the udev/linux layer and where retropie binds to the driver, but I don't know enough about retropie to figure out where to look..
Also, here's my configuration file:
https://pastebin.com/x7WZvbkWAnd if I manually try to add bindings to the config file, it doesn't work:
https://pastebin.com/uncEa9LwThanks for your attention!
-
@Cory-Parsnipson said in RetroPie config doesn't recognize custom gamepad joystick axes:
I guess there's something going wrong between the udev/linux layer and where retropie binds to the driver, but I don't know enough about retropie to figure out where to look..
EmulationStation relies on SDL2 for gamepad/joystick support, there's nothing special added by RetroPie. You can test to see how your joystick is recognized by SDL2 using sdl-jstest.
The pastebin for the joystick test is not easily readable, but the joystick axis movement doesn't seem to reach the standard -32,767 +32,767 values. You maybe want to calibrate the joystick using
jscal
(seeman jscal
). -
Sorry, I've tried to reformat the jstest output. I've taken out the button statuses and left only the axes:
This is after I ran jscal and got the calibration coefficients out of it (here: https://pastebin.com/2kyq9H5E).
I apply this calibration upon startup using a systemd init service, and as you can see the joystick ranges are now between -32767 and +32767. Unfortunately, the behavior I'm seeing is the same. When I go into the menu and use the "configure input" utility, my thumbstick movement isn't detected as any button press.
This seems to indicate to me that the joystick is recognized by SDL but for some reason isn't being picked up inside retropie. Does anything seem weird about my setup?
Also in my last post, my configuration file says "linuxraw" for the driver but it's actually "udev". I changed it to "linuxraw" just to see what would happen but nothing changed.
-
@Cory-Parsnipson said in RetroPie config doesn't recognize custom gamepad joystick axes:
This seems to indicate to me that the joystick is recognized by SDL but for some reason isn't being picked up inside retropie. Does anything seem weird about my setup?
There is no 'inside retropie', it's either EmulationStation (which uses SDL2) or RetroArch.
When you say my thumbstick movement isn't detected as any button press, are you trying to configure a button for the joystick axis, or the Analog Left/Right joysticks (Up/Down/Left/Right) ? I assume the latter, in which case try to use thesdl2-jstest
and see if the axis (calibrated) are detected.Also in my last post, my configuration file says "linuxraw" for the driver but it's actually "udev". I changed it to "linuxraw" just to see what would happen but nothing changed.
The input driver is set in the main
retroarch.cfg
file (in/opt/retropie/configs/all
), can't by set in the auto-configuration file.
Did you try with the the 1st of 2nd configuration file ? The 2nd one seems better, since it uses the_axis
options. -
There is no 'inside retropie', it's either EmulationStation (which uses SDL2) or RetroArch.
Ok I see. I still don't know my way around the amalgamation of tools and software layers. I think I mean "inside retroarch" then? There must be some program/script that ingests the retroarch-joypads configurations.
my thumbstick movement isn't detected as any button press
I'm trying to configure the joystrick directions to left analog up/down/left/right.
The input driver is set in the main retroarch.cfg file (in /opt/retropie/configs/all), can't by set in the auto-configuration file.
Did you try with the the 1st of 2nd configuration file ? The 2nd one seems better, since it uses the _axis options.I tried both before. Actually, I have an update for this part. I manually added the left x and y axis to the Arduino joypad config and then went in the default GBA emulator and switched the controller 1 analog to digital to use the left joystick. If I press all the way down or all the way down/left, I can get "flickering" movement of my game character. This is a good sign, it seems like the binding is working but my calibration is bad?
My arduino image has it outputting axes values between approx. 0 and 16684, so maybe SDL is ignoring the jscal calibration.
I'm going to run
sdl2-jstest
, but I can't find it on my system. I see there's a git repo, but is there a prebuilt package I can download instead? I'm building from source now, just curious, I guess.EDIT:
Your hunch is right! I built sdl2-jstest and running it shows that my axis are only reporting values between 0 and 16384.
Also I didn't realize jstest and sdl-jstest were different until you posted. I thought sdl_jstest was just the gui version of jstest. Sorry about that.
-
@Cory-Parsnipson said in RetroPie config doesn't recognize custom gamepad joystick axes:
I think I mean "inside retroarch" then? There must be some program/script that ingests the retroarch-joypads configurations.
That's
retroarch
itself. If you run with verbose logging enabled, you can see in/dev/shm/runcommand.log
the input configuration messages.Also I didn't realize jstest and sdl-jstest were different until you posted. I thought sdl_jstest was just the gui version of jstest. Sorry about that.
No, they're different. SDL has its own Joystick and Gamepad handling and although it's based on OS's event handling (
udev
/Linux event APi), it has some extra configuration/handling that's specific. You can use the test programs distributed with libSDL itself to test directly - https://github.com/spurious/SDL-mirror/tree/master/test, see 'testjoystick' and 'testgamecontroller'. -
Ok cool, thanks! I'm seeing movement now, although the exact calibration needs some work. So I think the problem was that the joystick wasn't calibrated to work with SDL and its original range is 0 <-> 16384 so it wasn't registering even though the input was being passed through correctly.
I needed to calibrate my joystick with
evdev-joystick --e /dev/input/by-id/usb-Arduino_LLC_Arduino_Leonardo_HIDAF-if02-event-joystick --minimum 0 --maximum 16384
I can browse emulation station menus and it works in the emulators too! Thank you so much for your help!
There's still a couple of smaller issues I need to work out.
-
Just make sure the calibration sticks around after reboot.
-
The mapping isn't correct. It's so sensitive that now that the axes are binary values between min and max. And they seem to overflow and wrap around, meaning if I go all the way right, it overflows and assumes the -32767 value, making the software think it's all the left. I think these problems can be solved with additional calibration.
I might edit this post or make additional ones if there's anything noteworthy in the fix for the above. Thanks again, mitu!
-
-
@Cory-Parsnipson said in RetroPie config doesn't recognize custom gamepad joystick axes:
Just make sure the calibration sticks around after reboot.
See a similar topic here.
-
I have everything working almost perfectly now, so here's a final post for closure.
There were two problems with my joystick setup, mostly due to the fact that I'm making it custom. This probably won't apply for anyone using off the shelf hardware, but I'll put it here in case anyone else is thinking of hacking a controller together:
-
The first issue was my voltage level was wrong. (Warning: science ahead) The nintendo switch
thumbstick I have is apparently designed to run off 1.8V input (https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering). I am inferring this from the documentation on the linked page where it says "Joycon runs at 1.8V". This is important because I noticed that when I moved my thumbstick axes to the minimum position, the delta in output value was about 4000 and when I moved the axes to the maximum position, the delta was about 12k. For example, my x-axis center position read around 4015 and the minimum (all the way to the left) was 0 and the maxiumum (right) was 16384. This can be attributed to running the thumbstick at the wrong voltage of 5V. I had to stick in a voltage divider to bring my 5V source down to 1.75V (close as I could get with the resistors lying around. I used a 100 ohm resistor on top of a 47 ohm and 10 ohm resister in series). -
In my arduino code, I changed my mapping from 0 <-> 16384 to the expected -32767 <-> 32767 because why not. This means I don't need to calibrate the joystick with
evdev-joystick
anymore. One thing to note is that the "raw" values coming out of the switch thumbstick on the 1.8V input was around ~80 <-> ~315 for the x axis and ~50 <-> ~303 for the y axis. There is some noise due to being real life, so I had to expand the input range a little to avoid overflow (this manifests to the user as the joystick pointing the wrong direction at full tilt. If you move the thumbstick all the way to the left, it should read -32767 but instead reads 32767 because of integer underflow, etc). So the actual values I used was something like 70 <-> 325 for the x axis and 45 <-> 315 for the y axis. This works like a charm. It controls like an actual switch controller as far as I can tell.
Here's my code sample for #2 if that helps:
https://github.com/CoryParsnipson/arduino-hid-gamepad-test -
-
Uh dang, I need to make some retractions here.
I went back to re-examine the joystick circuitry and stuff and it looks like the thumbstick works fine at any voltage. (I felt my logic was odd when lying in bed the other day). The "lopsided-ness" I was talking about is actually caused by setting the range incorrectly. Ignore what I said for #1 in the previous post. The thumbstick appears to behave the same with 1.8V as with 5V (from a design standpoint, you'll probably save a little power by driving it at 1.8V).
Most modern joysticks expect something in the range of -32767 to +32767 with the center/neutral point (when the joystick is not being touched) being 0. Why? Because this is the min and max values you can represent with a signed 16 bit integer. To be extremely pedantic, you can actually go to -32768, but we pretend it's -32767 to make it symmetric.
When I did the mapping function, I take an input range of values going from ~70 to ~325 to 0 <-> 16384. I think this is where the "lopsided-ness" comes in. I'm using a built in function from the Arduino library called
map()
so I don't exactly know what is going on, but it places the center point somewhere around 4000 instead of ~8150 as you would expect. This isn't a problem if the output range is -32767 to 32767 for some reason.
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.