DivaCon2040 is a firmware for DIY Project Diva Arcade controllers based on the RP2040 microcontroller as found on the Raspberry Pi Pico.
It is pretty much tailored to this specific use case, if you are looking for something universal, ready-to-flash and on-the-fly configurable I'd recommend to have a look at more generic approaches like GP2040-CE. If you however want build something more specialized or custom, feel free to use this project as a base, it is designed to be somewhat modular and should be easy remodel. See DonCon2040 for an example on how this could look like.
If you have any questions about the project in general or need hints how to build this thing, feel free to open a discussion anytime!
- Various controller emulation modes
- HORI PS4-161 Project Diva Arcade Controller for PS4* (compatible with Project Diva Mega Mix on Steam/PC. Project DIVA Future Tone DX on PS4 untested!)
- HORI NSW-230 Project Diva Arcade Controller for Switch (compatible with Project Diva Mega Mix on Switch/Steam/PC)
- PD-Loader Arcade Controller (Compatible with PD-Loader's Divaller driver)
- Dualshock 4 (does not work on an actual PS4!)
- Dualshock 3
- Switch Pro Controller
- XInput
- Keyboard
- MIDI
- Debug mode (will output current state via USB serial and allow direct flashing)
- Arcade Style Touch Slider for arcade controller emulation modes (In Project Diva Games enter the 'Customize' menu from song selection and enable arcade controller support under 'Game/Control Config' -> 'Arcade Controller Settings' for the slider to work properly.)
- Slider to analog stick mapping for standard controller modes
- 1000Hz Polling Rate, ~2.4ms average latency, <0.7ms Jitter (Tested with Gamepadla/GPDL)
- Slider illumination using WS2812 LED strip (can be controlled by PD-Loader)
- Button illumination (can be controlled by PD-Loader)
- Basic configuration via on-screen menu on attached OLED screen
- Player LEDs are visualized on OLED screen for DS3 and XInput, player color on the slider LEDs for DS4 (can be disabled)
- BPM counter
I highly recommend to build the firmware yourself so you can make adjustments in include/GlobalConfiguration.h
to match your specific controller build.
If you still want to use a binary release, you need to connect everything according the default configuration as described here.
Install VSCode and get the Raspberry Pi Pico extension. From the extension choose 'Import Project' and select the folder where you've checked out this repository, then use 'Compile Project'.
See pico-sdk readme for a list of pre-requisites.
Use the environment variables PICO_SDK_PATH
to use a local pico-sdk, and PICO_BOARD
to select another target board.
By default the pico-sdk will be fetched from Github and the target board will be "pico".
mkdir build && cd build
cmake ..
make
Few things which you probably want to change more regularly can be changed using the on-screen menu on the attached OLED display, hold both Start and Select for 2 seconds to enter it:
- Controller emulation mode
- Touch Slider LED brightness
- Enable/Disable setting the slider background color to the Dualshock4 lightbar color.
- Enter BOOTSEL mode for firmware flashing
Those settings are persisted to flash memory if you choose 'Save' when exiting the Menu and will survive power cycles.
Everything else is compiled statically into the firmware. You can find defaults and hardware configuration in include/GlobalConfiguration.h
. This covers default controller emulation mode, button pins, i2c pins, addresses and speed, LED colors and brightness.
This project was designed and tested on the Raspberry Pi Pico. Other RP2040 boards are probably also working if they expose enough GPIOs.
For an overview how everything is connected in the default configuration, see here.
Buttons are hooked up directly to the GPIO pins, pulling the pin to ground when pressed.
Supported are:
- Four face buttons, which are mapped according to the cardinal directions they appear on the respective controllers (North/East/South/West)
- DPad/Hat (Up/Down/Left/Right)
- Two shoulder buttons for each side (L1/L2/R1/R2)
- Two Stick buttons (L3/R3)
- Three vendor specific buttons (Options/TouchPad/PS on DS4, Start/Select/PS on DS3, +/-/Home on Switch, Start/Back/Guide on XInput)
For the four big buttons I used generic 100mm "Massive Arcade Button"s since those are much cheaper than the original Sanwa OBSA-100UMQ. They have same size an can be easily improved with the original OBSA-SP-200 200g springs and better switches, like the ridiculously expensive Sanwa OBSA-LHSXF or steelpuxnastik's excellent DIY switches for a more authentic feel.
The other buttons are cheap generic 24mm arcade buttons.
Illumination for the four face buttons can be controlled by GPIO pins. I recommend to not directly hook up the LEDs to the GPIO pins, but rather use a simple transistor based driving circuit since the power than can be delivered through the GPIOs is rather limited.
The touch slider resembles the the slider of Project Diva Arcade Controllers and Cabinets, being a row of 32 individual touch sensors. For the two arcade controller emulation modes, the 32 sensors are mapped to the analog stick axes as described here and work just like the original controllers in-game. In Project Diva games which support arcade controllers (i.e. Mega Mix on PC/Switch), enter the 'Customize' menu from song selection and enable arcade controller support under 'Game/Control Config' -> 'Arcade Controller Settings' for the slider to work properly.
For other controller emulation modes, swipes on the left half of the slider will move the left stick left and right, while swipes on the right half will do the same on the right stick.
The Touch Slider is based on three MPR121 Capacitive Touch Sensor Controllers attached to the same i2c bus, so make sure to have them use different i2c addresses accordingly. I screwed up hooking up the electrodes a little, so either refer to the table below or do it properly and change it in the code:
MPR 0 | MPR 1 | MPR 2 | |
---|---|---|---|
Pin | 0..11 | 2..9 | 0..11 |
Electrode | 31..20 | 19..12 | 11..0 |
The MPR121s are setup for auto configuration with parameters taken from the Adafruit MPR121 Arduino Library. The 'FDL falling' value has been tweaked to allow slow slides. You might want to adjust the touch and release thresholds to your specific build.
Physically, the slider is a sandwich made out of 3mm of frosted acrylic, some thin 3M 468MP adhesive, paper for the artwork and 32 strips of 5mm wide copper tape for the electrodes. Make sure to use the thinnest possible wire to connect the electrodes to the MPR121 boards.
For illumination, I used Adafruit Side Light NeoPixel LED PCB Bars which have the perfect hight and spacing to light up each segment with two LEDs, but other WS2812 compatible strips should work as well.
Just a standard SSD1306 OLED display with 128x64 resolution hooked up to the second i2c bus. Mind that the display is mandatory for changing any settings directly on the controller, if you want to omit it, change the defaults within the code accordingly (or navigate the menu blindly).
The enclosure is build with lasercut 5mm opaque balck acrylic panels held together by aluminum profiles and some 3D printed spacers. Edges and the cradles the touch slider sits in are also 3D printed. The Artwork is sandwiched behind an additional layer of 4mm transparent acrylic.
- Adafruit for the figuring out some working MPR121 settings
- daschr for the SSD1306 OLED driver
- FeralAI for the inspiration and XInput driver from the GP2040 Project
- dogtopus for his research on the arcade slider and various contributions to many controller related projects
- steelpuxnastik for the excellent SHINSANWASWITCH
- The linux kernel contributors for documenting the game controllers in their drivers