BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
Free firmware and browser configurator for DIY Guitar Hero / Rock Band controllers on the Raspberry Pi Pico: any-pin button mapping, whammy, RGB LEDs, Bluetooth, XInput, PS3, Switch, PS4/PS5 and Xbox
GamesC · JavaScriptGitHub @Cr4zySh4rkOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Free firmware + browser configurator for DIY Guitar Hero / Rock Band controllers on Raspberry Pi Pico (RP2040/RP2350): any-pin mapping, whammy, RGB LEDs, Bluetooth, XInput/PS3/Switch/PS4/Xbox modes. Clone Hero, YARG, Fortnite Festival.
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Free, open-source firmware and browser configurator for DIY Guitar Hero and Rock Band guitar controllers on the Raspberry Pi Pico family (Pico, Pico W, Pico 2, Pico 2 W and RP2040 boards such as the Waveshare RP2040-Zero, SparkFun Pro Micro RP2040 and Adafruit KB2040). Flash the board, plug it in, and the web app walks you through mapping every button, whichever pins you wired them to. Play Clone Hero, YARG, Fortnite Festival, Rock Band and Guitar Hero over USB or Bluetooth.
Web app: https://cr4zysh4rk.github.io/YAGCC/ (GitHub Pages) · also deployable on Vercel (see below)
Requires a Chromium-based browser (Chrome, Edge, Brave, …) for WebUSB. Downloading firmware works in any browser.
An earlier 5-minute walkthrough with voice-over (from v0.4; the setup flow is the same, newer features are missing) is here. No real guitar was used in either; a simulated controller feeds the configurator the same data the firmware sends.
RPI-RP2 drive.Changes apply live; one bar at the bottom appears whenever something isn't saved yet, with Save to guitar and Undo changes. Expert settings (tilt sensors and accelerometer filters, rumble, PS2 / Wii ports, USB host port, Steam receiver option, Bluetooth debug log, colour order) are behind the Advanced switch in the header; anything already set to a non-default value stays visible.
| Hold at plug-in (default) | Mode | What it is | Best for |
|---|---|---|---|
| (nothing: the default for new setups) | Auto | Detects the host, then restarts as the matching mode below and stays that way until unplugged (firmware 0.30+) | Anything: see Auto mode below |
| Green | XInput | Xbox 360 guitar (Guitar Hero or Rock Band type, selectable). Answers Xbox 360 security (XSM3). On a host with no XInput driver (macOS) it switches itself to the HID gamepad | Windows / Linux / macOS, Clone Hero / YARG / Fortnite Festival (PC), Xbox 360 (experimental) |
| Red | PS3 Rock Band | Rock Band guitar 12BA:0200 (Santroller report layout: tilt → R1, star power → select) | Rock Band on PS3 / RPCS3, YARG |
| Yellow | HID gamepad | Generic gamepad (16 buttons, hat, 4 axes) | macOS, Linux, Android, emulators |
| Blue | PS3 Guitar Hero | RedOctane 12BA:0100 with the PS3 guitar handshake | Guitar Hero on PS3 / RPCS3, Clone Hero |
| Orange | Nintendo Switch | HORI Pokkén pad 0F0D:0092: green A, red B, yellow X, blue Y, orange L, tilt R, star − , plus +, strum on the D-pad, whammy on the right stick (rests at the centre, pushes toward the minimum) | Fortnite Festival on Switch, other Switch games |
| (assign on Modes tab) | Fortnite Festival (keyboard) | USB keyboard with the Fortnite Festival Pro guitar default keys (frets 1–5, strum Right Shift / Right Ctrl, star power PageDown, plus Esc) | Fortnite Festival on PS4, PS5, Xbox One/Series and PC: consoles accept a keyboard with no authentication |
| (assign on Modes tab) | Wii Rock Band | Harmonix Wii guitar 1BAD:0004 | Rock Band on Wii / Dolphin |
| (assign on Modes tab) | OG Xbox | Original Xbox controller (XID) | Guitar Hero II / III on original Xbox (experimental) |
| (assign on Modes tab) |
The mode picked by holding a fret is remembered (like GP2040-CE), and every fret → mode assignment can be changed on the Modes tab.
Fortnite Festival. On a Switch, hold orange while plugging in (Switch mode). On PS4, PS5, Xbox and PC, assign keyboard mode to a fret on the Modes tab and hold that fret while plugging in; in Fortnite turn on Pro input for guitar and choose the keyboard layout that matches the bindings shown on the Modes tab (Pro guitar is the default; a Lead-lane preset — D F J K L, arrows, Space — is one click away, and every key is rebindable). On PC you can also use XInput mode with Star power → D-pad left switched on.
XInput options. The guitar can report as a Guitar Hero (subtype 7) or Rock Band (subtype 6) guitar. Whammy sits on right stick X and tilt on right stick Y, both resting at the bottom like real guitars. When a game sends star power / overdrive state over the rumble channel, the fret LEDs can glow cyan (Star power glow on the Lights tab).
Auto mode. The guitar starts as a HID gamepad that also carries the PS3 / PS4 feature reports, an Xbox 360 security interface and the Microsoft OS descriptors, and watches how the host enumerates it (Santroller's detection, firmware/src/auto_detect.c):
| Host does | Host is | Becomes |
|---|---|---|
| reads the Microsoft OS descriptors and the strings | Windows | XInput (as a wireless receiver slot, for Steam) |
| reads the Microsoft OS descriptors, never a string | Xbox One / Series | Xbox One guitar with an auth controller on the host port, otherwise the Fortnite Festival keyboard |
| starts the Xbox 360 security handshake | Xbox 360 | XInput |
| asks for a PS3 feature report (or RPCS3's) | PS3 / RPCS3 | PS3 Guitar Hero or Rock Band guitar (the XInput guitar type picks which) |
| asks for feature report 3 with 48 bytes | PS4 / PS5 | PS4 guitar (PS5 guitar if the auth dongle is a P5General) with an auth controller on the host port, otherwise the PS3 Rock Band guitar Rock Band 4 takes as a legacy instrument |
| clears both endpoints, or reads only the report descriptor | Switch / Switch 2 | Switch |
| asks for the XID descriptor | original Xbox | OG Xbox |
| configures it, then goes quiet | Wii / Wii U | Wii Rock Band guitar |
| reads descriptors but never configures it | PS2 | PS3 guitar (what PS2 games and OPL's PADEMU take) |
| reads strings and uses it as it is | macOS, Linux, Android | stays the HID gamepad |
It decides within a few seconds, restarts in that mode, and goes back to Auto when unplugged. Windows caches the Microsoft OS descriptors, so on a PC that has seen the guitar before it may stay the HID gamepad (Clone Hero and YARG take both); pick XInput explicitly if a game needs it.
Steam on Windows (firmware 0.30+). Steam's controller driver chokes on a wired XInput pad that shares its USB device with another interface (the configurator's). Like Santroller, the guitar presents itself to Windows as one controller slot of an Xbox 360 wireless receiver instead, with its own Microsoft OS descriptor entry so Windows binds the receiver driver. A real Xbox 360 never reads those descriptors and still gets the wired pad. From 0.38 this is off by default (it left the guitar unrecognised on at least one Windows PC): turn on Steam receiver mode on Windows (experimental) on the Modes page (Advanced) to use it. Wired XInput is used otherwise. 0.39: the wired pad and the receiver slot now report different USB serial numbers (Windows keys its driver records on vendor id, product id and serial, so a record from one layout can no longer block the other; after updating, Windows installs the Xbox 360 driver for the guitar afresh), Auto mode stays off the bus for 300 ms before it re-enumerates, the XInput serial reply is stable, and automatic saves (hold-a-fret mode, Bluetooth pairing) never overwrite a saved config this firmware could not read; only Save to guitar does. 0.40: the wired XInput pad also sends the XUSB10 compatible id in its Microsoft OS 2.0 descriptor, which binds Windows' own Xbox 360 driver (xusb22) without a Windows Update download; before, a PC that could not fetch that driver showed the guitar as an unknown device (Code 28).
XInput on a Mac. macOS has no driver for Xbox 360 controllers, so in XInput mode nothing would read the guitar. If no XInput driver has used it within 10 seconds of plugging in (and the host isn't Windows), the guitar re-connects as the HID gamepad, which Clone Hero and YARG pick up as usual; the configurator shows XInput → HID. The saved mode stays XInput, and the next plug-in starts as XInput again, so the same guitar works on Windows, Linux and macOS without changing modes. (0.37+) In Auto mode this switch never happens once Auto has recognised Windows or an Xbox 360, so a Windows PC keeps the XInput pad and the configurator connection.
PS3 Guitar Hero and Switch reports (compatibility fixes, from Santroller 24e78967, 6f3d291f, beb9b937). The PS3 Guitar Hero guitar now rests its whammy axis at 0x80 and goes up to 0xFF like a real RedOctane guitar, and its fret pressure bytes read 0 or 0xFF (yellow, green / strum up, orange / strum down, blue, red; a fret held together with the strum direction that shares its byte reads 0, as on the real guitar). The PS3 Rock Band report is unchanged. In Switch mode the whammy rests at the stick centre and moves down toward the minimum, and yellow / blue are now the X / Y buttons (they were Y / X). Unverified on a console.
USB suspend and remote wakeup. When the host suspends the bus (the PC sleeps), pressing a fret, strum, star power or plus wakes it, as long as the host allowed remote wakeup (PS4, PS5 and Switch modes don't advertise it). For a wired XInput pad that isn't on Windows (an Xbox 360) the firmware also reads the USB controller's suspended state and signals resume regardless of the host's setting, because a 360 never enables remote wakeup but still powers on for a pad that signals it. The whammy bar and the tilt swing never wake the host. Lights and Bluetooth behave as before. Unverified on hardware.
HID gamepad layout. Frets are buttons 1–5, star power button 6, plus button 7, strum up/down buttons 8/9 and the hat; whammy is the Z axis and the tilt sensor the Rz axis (tilt also presses button 6). Pressing star power changes only button 6, so games' remap screens record it as a plain button.
Configuring in other modes: XInput, HID and keyboard modes keep the WebUSB config channel (browsers grant permission per mode, so press Connect once after switching). PS3, Wii, Switch and OG Xbox modes have to look exactly like the real device, so they have no config channel: the Setup page finds PS3/Wii guitars over WebHID (Find it) and restarts them in setup mode with one click; for the others hold Plus while plugging in. macOS has no XInput driver, so use HID mode for games on a Mac.
Console authentication (USB host port) — experimental. PS4, PS5 and Xbox One / Series only accept licensed controllers. Like GP2040-CE, YAGCC can run a second, software USB port (Pico-PIO-USB on PIO1) and pass the console's security check through to a licensed controller plugged into it:
This is ported from GP2040-CE's PS4 and Xbox One drivers but has not yet been tested on a real console; reports are welcome.
Backup and restore. The Backup tab (right after Tune) can download all settings (wiring, tuning, lights, modes) as a JSON file and restore any of those sections later, onto the same guitar or another one. Files are checked before anything is written, and pins that would clash on the target are skipped.
Mapping prompts. While Setup > Buttons asks for a fret, that fret lights up in its own colour (your LED colours when the LEDs are on) on the 2D and 3D guitar, in its tile and in the prompt; other inputs keep the standard highlight.
Live 3D guitar. The Setup and Tune pages show a 3D Les Paul (blue-purple front plate, black trim) that copies the real guitar as you play it: frets press in and light up in their LED colours, the strum bar rocks up and down, the whammy bar dips as far as you push it, Star power and Plus light up, and the guitar lifts its neck when the tilt sensor fires. Drag to turn it, double-click to reset. It loads only when a page with the guitar is opened. If the browser has no hardware graphics acceleration, the flat drawing is shown instead (add ?2d to the address to force it).
Firmware updates. When a guitar connects, the configurator compares its firmware version with the latest one on the site. If the guitar is older, a banner offers the update: it opens the Flash page with your board already picked, and the guitar can restart itself into update mode (no BOOTSEL button needed), so you only drop the new file on the drive that appears. Settings are kept.
See the Compatibility page in the web app for a game-by-game / console-by-console table with honest status labels (Supported, Experimental, Planned).
Modes page, firmware 0.31+. Ported from Santroller; they work next to whatever USB mode is running and stay quiet until a console talks to them. Not yet tested on a console with YAGCC.
Tune page, firmware 0.30+. A small vibration motor (coin / ERM) on any free GPIO, switched by an NPN transistor (base through ~1 kΩ) or a logic-level MOSFET, with a flyback diode across the motor; never drive it straight from the pin. The pin runs 20 kHz PWM, scaled by a strength setting. It can:
Set up in the Setup wizard's Tilt sensors step (right after the tilt switch; firmware 0.29+) or on the Tune page. The Setup step asks Do you have an accelerometer or an analog tilt sensor wired? (Accelerometer (I²C), Analog tilt sensor (GP26–28) or No, skip, which changes nothing), then runs the same guided capture as Tune (pins and found check for an accelerometer, or a GP26–28 pin that isn't the whammy's or a stick's, then capture level / tilted and Assign to), with Add a second tilt sensor at the end. Besides the digital tilt switch from Setup there are two sensor slots, and each one reads from:
Guided setup. Pick the accelerometer's SDA / SCL pins and the Tune page confirms when the chip is found (✓ ADXL345 found). Then choose what tilting should do (Star power, Whammy or A button, where you pick the input from a list; firmware 0.41+), hold the guitar level and press Capture level, tilt the neck up and press Capture tilted. The axis is worked out for you (the one that moved most), a live meter and a Star power at slider appear, and Redo starts over. With two accelerometers you also pick which chip. The detailed controls below the guided setup are still there for picking an axis by hand, thresholds and two sensors.
Each slot either adds to the whammy (the whammy bar and the sensor work together; whichever is pushed further wins, and the whammy dead zone applies) or presses an input once the guitar tilts past a threshold you set (with a little hysteresis so it doesn't flicker). Each sensor card, and the Tilt switch panel, has an Acts as list: Whammy (sensors only), Star power (the default), the five frets, strum up / down or Plus / Start. A tilt acting as a button counts exactly like the physical button for every output mode, the LEDs and the live guitar view; as star power it behaves as before. Settings live in config bytes 242..244 (tilt switch, sensor 1, sensor 2: 0 = star power, n = function n-1; the sensor's target must be "press"), inside the existing 256 byte layout, so older configs keep working and older configurators leave them alone. Calibrate with Set rest (guitar level) and Set tilted (neck up); the direction is worked out from the two. So a guitar can have a whammy bar, a star power button, a tilt sensor on the whammy and another on star power, all at once.
Two accelerometers (0.36+). Wire both to the same SDA / SCL / 3V3 / GND and give the second a different address: ADXL345 SDO to GND = 0x53 and SDO to 3V3 = 0x1D; LIS3DH SA0/SDO to 3V3 = 0x19 (default 0x18); MPU-6050 AD0 high = 0x69 (default 0x68). Mixed chip types work too. The first chip found is Accelerometer 1, the next one at another address Accelerometer 2; the Tune page shows both chips and their live X / Y / Z, and each sensor slot can read any axis of either (sources 9..11 in the config). Each chip has its own filters and is found again if unplugged. The LIS3DH auxiliary ADC inputs are read from chip 1 only.
The accelerometer readings go through the same filters Santroller uses, each off at 0: a 2nd order Butterworth low pass (default 20 Hz), a median of 3–9 samples (default 3) that drops single spikes, and a gravity gate that holds the last reading while the guitar is being shaken (a hard strum) rather than tilted. The chip is polled with its data-ready flag so each sample is used once, and it is found again if it's unplugged.
YAGCC uses a lockout + glitch filter engine, designed after reading how Santroller and GP2040-CE do it:
The only knob is the lockout time (presets from Off to 20 ms, or a slider up to 25 ms). Inputs are sampled at up to 10 kHz.
Needs firmware 0.42 or newer; older firmware simply doesn't show any of this.
Test page. Pick a console mode (XInput, HID, PS3 Guitar Hero, PS3 Rock Band, Wii Rock Band, Switch, PS4, PS5, Xbox One, Original Xbox) and press things on the guitar. The live guitar is on top; below it is a gamepad that lights up with what that mode would send to the console, labelled the way that console names its buttons (A / B / X / Y, Cross / Circle / Square / Triangle, or Nintendo's B / A / Y / X). For the mode the guitar is actually running, the gamepad shows the guitar's own report (a badge says "Live from the guitar"); for any other mode it shows a preview worked out from your inputs. D-pad, Select, Home, stick and tilt inputs show in a strip under the guitar.
Changing what an input does. Every input has its own list per mode, so Select can be Back in one mode and Guide in another. Use the dropdown in the table, or click an input (on the guitar or in the list) and then click the gamepad button, trigger or stick direction it should press. Digital inputs on a stick direction press that half of the axis; the whammy bar on a stick direction ("Left stick up" and friends) pushes that half of the axis, and on a whole stick axis it goes from the centre (at rest) to full deflection (0.43; it used to rest at full negative). Analog inputs (whammy bar, tilt sensors or accelerometer axes) have a Response curve (firmware 0.43+): a slider from -100 to +100 with Linear / Expo + / Expo - chips and a small live graph; it shapes the analog value before it reaches a stick or trigger, never the press threshold. Outputs a mode can't carry are greyed out. "Mode default" keeps what the guitar always did (for example "A (green fret)"). Changes go to the guitar straight away and join the usual Save bar, so Undo and Save to guitar cover them.
Extra controls (Setup, "More controls"). An optional D-pad (four pins), Select, Home and stick click button, each with a pin picker or a Detect button (press it twice). Pins used by anything else aren't offered. With Advanced on (or once set) there is also an analog stick: pick the two analog pins (not the whammy's or a tilt sensor's), flip or swap its axes, set the dead zone, and run the guided calibration (let go for the centre, then circle the edge). A live dot shows the result.
Firmware side. The configurator part is documented with the Test page.
min / mid / max (12-bit, min < mid < max), then the deadzone (0..50 %, rescaled so full deflection stays full), then swap X/Y, then invert X / Y (stick_flags bit0 / bit1 / bit2 = invert X / invert Y / swap). Result is -32767..32767.0xFF = the default, 0 = nothing. The generic pad is then packed into the mode's native report; with the default map every report is byte for byte what 0.41 sent (firmware/tests/host_map compares them). Keyboard mode and Auto have no map; Bluetooth uses the HID row. The PS2 and Wii extension ports are not mapped.firmware/src/ext_config.h) in the two flash pages after the main config page, same sector, saved and reset together with it (0x34, 0x35). A missing or invalid page means defaults; one that is present but unreadable is kept by automatic saves until you save explicitly.0x3D get ext page (IN, 512 bytes), 0x3E set it (OUT, 512 bytes, validated, applied live, not saved; an invalid page stalls). 0x31 status is 96 bytes (bytes 55..95: map row, generic buttons / axes, stick, flags) when the host asks for 96.Since 0.47 Bluetooth pairing never completed: the LE Secure Connections key exchange needs about 2.4 KB of stack, the Pico W builds had 2 KB, and 0.47's new stack-overflow check reset the guitar the moment a host started pairing (older versions overflowed into unused memory without noticing). 0.50 gives the Pico W / Pico 2 W builds a 4 KB stack, logs the unused stack bytes and the reset reason, advertises as discoverable whenever no host is paired (so the guitar can never lock itself out), removes half-finished pairings, logs each connection once, and logs every pairing step (requests, IO capabilities, result, encryption, disconnect reasons) for the Bluetooth log viewer.
0.47 made Bluetooth connect unreliably (Windows and macOS). 0.48 goes back to two Bluetooth connection slots (a host reconnecting before the old link is freed needs the second), turns link-time optimisation off again by default, raises the running watchdog timeout to 8 s (pairing key writes and radio stalls must never trip it), and only skips Bluetooth for one start-up right after the radio hung while starting (crashes alone no longer turn it off). The 0.47 latency and other reliability changes stay.
| Build | Board |
|---|---|
pico_clone | Generic RP2040 "Pico-compatible" clones, including boards with an ESP8285 (Wi-Fi only) instead of a real Pico W radio. Uses the generic flash boot stage, slower flash clock and longer crystal start-up, like Santroller's pico_w_compat. If unsure, use this one. |
pico / pico_w | Official Raspberry Pi Pico / Pico W |
pico2 / pico2_w | Official Pico 2 / Pico 2 W (RP2350) |
waveshare_rp2040_zero | Waveshare RP2040-Zero (tiny, fits inside most guitar necks) |
waveshare_rp2040_one | Waveshare RP2040-One |
sparkfun_promicro | SparkFun Pro Micro RP2040 (Pro Micro footprint, drop-in for old Arduino builds) |
adafruit_kb2040 | Adafruit KB2040 (Pro Micro footprint) |
The Hardware page in the web app describes each board, the LED types, whammy pots, tilt sensors and wiring, and warns about fake "Pico W" boards. Arduino (ATmega32U4 / 328P) and other microcontrollers are not supported: YAGCC is RP2040/RP2350 only.
Bluetooth (tested on a Pico W with Windows: pairing and reconnecting after power cycles in every mode; Pico 2 W built from the same code but not yet tried) needs the CYW43 radio of a genuine Pico W / Pico 2 W; the ESP8285 on clone boards is Wi-Fi only, so the toggle is disabled there. Over Bluetooth LE (HID over GATT, BTstack) the guitar presents the same device as over USB in the running mode: the same input report layout and bytes and the same vendor / product ids (the report map keeps only the input report; the USB output / feature reports are console handshakes) (PS3 Guitar Hero, PS3 / Wii Rock Band, Switch, keyboard, HID gamepad, PS4). XInput, original Xbox and Xbox One aren't HID devices over USB, so over Bluetooth they use the generic gamepad. Each mode is its own Bluetooth device ("YAGCC PS3 GH", "YAGCC Switch", …) with its own address, so a host never mixes up two modes' layouts. Whether a console accepts it is up to the console: most only take their own wireless controllers.
YAGCC is guitar-only for now (drums and other instruments are out of scope). Experimental and untested on consoles: PS4 / PS5 and Xbox One / Series guitar modes with authentication passthrough. Bluetooth LE gamepad output is tested on Pico W with Windows. Planned, not yet implemented: wireless receivers, peripheral (wired neck) support over I²C.
firmware/ pico-sdk + TinyUSB firmware (XInput, PS3 GH/RB, HID, keyboard, Switch, Wii RB, OG Xbox + WebUSB config),
PS4 / Xbox One modes with auth passthrough (src/host), LED drivers, flash nuke,
lib/xsm3 (Xbox 360 security, LGPL-2.1), lib/pico_pio_usb (USB host port, MIT)
web/ static web app (no build step) – deployed as-is; models/guitar.glb + models/pad_*.glb + vendor/three-yagcc.js for the 3D guitar and controller views
tools/ model/build_glb.py rebuilds the 3D guitar from the Sketchfab download
tests/ unit tests for pin and whammy detection
.github/ CI: builds all firmware variants and deploys the site to GitHub Pages
assets/ logo and demo media
vercel.json Vercel configuration (serves web/)
git clone --depth 1 -b 2.1.1 https://github.com/raspberrypi/pico-sdk
git -C pico-sdk submodule update --init --depth 1 lib/tinyusb
cmake -S firmware -B build -G Ninja -DPICO_BOARD=pico_clone -DPICO_SDK_PATH=$PWD/pico-sdk
cmake --build build # build/yacc.uf2 (published as yagcc-<board>.uf2) and build/nuke/yacc_nuke.uf2
Pico W / Pico 2 W builds use Santroller's BTstack fork (sanjay900/btstack, a BTstack 1.8 development version with their Bluetooth gamepad fixes) instead of the BTstack 1.6.2 that ships with the Pico SDK, so the guitar runs the same Bluetooth stack as Santroller's Pico W controllers. The commit is pinned in firmware/CMakeLists.txt (YACC_BTSTACK_COMMIT):
git clone https://github.com/sanjay900/btstack && git -C btstack checkout $(sed -n 's/^set(YACC_BTSTACK_COMMIT \([0-9a-f]*\))/\1/p' firmware/CMakeLists.txt)
git -C pico-sdk submodule update --init --depth 1 lib/cyw43-driver lib/lwip
cmake -S firmware -B build-w -G Ninja -DPICO_BOARD=pico_w -DPICO_SDK_PATH=$PWD/pico-sdk -DPICO_BTSTACK_PATH=$PWD/btstack
cmake --build build-w
The firmware is built for size (-Os, newlib-nano, no printf engine on the plain Pico boards; timing-critical code such as the PIO USB host, the PS2 port and the Wii extension stays at -O2/-O3). Flash use from firmware 0.34: about 100 KB on the Pico, Pico 2 and RP2040 boards and about 450 KB on the Pico W / Pico 2 W, of which 232 KB is the CYW43439 radio firmware that the chip needs even for Bluetooth only. Each CI run lists every board's flash and RAM use in its summary. -DYACC_LTO=ON builds with link-time optimisation (a further ~7–11 KB; off by default, not hardware-tested).
Off by default: the guitar records nothing about its Bluetooth connections. Switching on Debug logging on the Setup page's Bluetooth step (saved straight away) makes the Pico W / Pico 2 W keep a Bluetooth event log in 16 KB of flash, grouped by power-on and kept across power cycles until Clear is pressed. It also records every Bluetooth GATT, pairing and L2CAP signalling message in both directions (except the guitar's own input reports), so the log shows the last thing a host asked for before it disconnected. Switch it off again once the problem is found.
node tests/detect.test.mjs
node tests/firmware_version.test.mjs # web/firmware.json must match firmware/CMakeLists.txt
When you bump YACC_VERSION_MINOR, update web/firmware.json too: the configurator compares a connected guitar's version with it and offers an update when the guitar is older.
python3 -m http.server -d web 8000 # then open http://localhost:8000 in Chrome
main builds the firmware for all boards and publishes web/ plus fresh UF2s. Asset URLs are cache-busted per deploy, and the deploy step retries once on transient GitHub errors.vercel.json already points the output directory at web/ and needs no build step. The UF2 files committed in web/downloads/ are served directly.Configuration travels over WebUSB vendor control transfers on interface 1 (WinUSB via MS OS 2.0 descriptors):
0x30 info · 0x31 live status (GPIO levels, ADCs, debounced press counters) · 0x32/0x33 get/set config (96 bytes, version 4, CRC32, byte 73 = USB host port D+ pin, bytes 74–88 = LED layout (no fret LEDs, strum LED count, positions, colour, roles; strum LEDs 5–8 at 84–88); older 64-byte v3 configs are migrated on boot) · 0x34 save · 0x35 defaults · 0x36 reboot/bootloader · 0x37 set mode · 0x38 light one LED (wizard).
In the PS3 and Wii modes the configurator sends HID feature report YAGCC! to restart the controller once in setup mode.
See firmware/src/config.h, firmware/src/usb_common.h and web/js/protocol.js.
Inspired by and compatible in spirit with Santroller and GP2040-CE; USB identities and handshakes were studied from Santroller. Xbox 360 security uses libxsm3 (from Santroller, LGPL-2.1, firmware/lib/xsm3). The 3D guitar is based on "Guitar Hero Controller" by CamSear16, licensed under CC BY 4.0; it was split into moving parts, given a blue-purple front plate with black trim, and brand marks were removed (see tools/model/README.md). The 3D controllers on the Test page are based on models by matok39x (Xbox 360 pad, CGTrader), CREATRBOI (Xbox One / Series pad, Sketchfab), shaielwolf (DualShock 4, Sketchfab), EROLDINA (DualSense, Sketchfab) and Hayley Jacka (Joy-Cons, Sketchfab); they were modified (split into moving parts, textures resized, button labels added, the left Joy-Con made from a recoloured copy) as described in tools/model/README.md. It is rendered with three.js (MIT). The PS4 and Xbox One authentication passthrough is adapted from GP2040-CE (MIT; firmware/src/host, including its xgip_protocol and XInput host driver), and the Rock Band 4 guitar identities and report layouts follow Santroller. The USB host port uses Pico-PIO-USB 0.6.1 by sekigon-gonnoc (MIT, firmware/lib/pico_pio_usb). Ported from Santroller (GPL-3.0, at 0662a9ff): the console detection behind Auto mode, the PS5 / P5General passthrough, the Xbox 360 wireless receiver identity, the accelerometer driver and filters, the PS2 controller port emulation (), the Wii extension emulation and extension encryption () and the Wii Remote emulation (, itself built on the WiimoteEmulator work Santroller credits). YAGCC is licensed under (see ).
map_spec.md; tests: firmware/tests/host_map/build.sh.range with the mapping.bt_sleep (bytes 328..507 were reserved 0 until 0.46): 0 = default (2 minutes), 1..60 = minutes, 255 = never; any other value makes the whole ext page invalid. Old pages hold 0, so they get the 2 minute default. The configurator offers 1, 2 (default), 5, 10, 15, 30, 60 minutes and Never, and Backups include it (section Bluetooth sleep).firmware/src/idle_sleep.h) and tested on a PC (firmware/tests/host_map/idle_sleep_test.c, run by build.sh). A watchdog restart with SLEEPWAKE_MAGIC ("YSLP") in scratch 0 wakes into the saved mode without the hold-a-button shortcuts.0.51 change: the name is now the whole device name (up to 25 characters, ext bytes 328..353). In 0.46 to 0.50 it was a prefix of at most 10 characters that got Guitar Controller and similar appended. Migration: a prefix such as Adi saved by 0.46 to 0.50 now shows up as exactly Adi (no longer Adi Guitar Controller); edit the name to what you want to see. The configurator says so once in the field hint (Since 0.51 this is the whole name). Empty still gives the old defaults exactly (YAGCC Guitar Controller, YAGCC Guitar (HID), YAGCC Guitar (Keyboard), YAGCC Guitar in Auto, YAGCC Guitar (PS4), YAGCC Guitar (PS5), Bluetooth YAGCC <mode>). With a custom name every one of those product strings (and the Bluetooth GAP / Device Information model name) is exactly the name, no mode suffix; the USB manufacturer string stays YAGCC. Identities that imitate real devices are unchanged. Validation: printable ASCII 0x20..0x7E, 1..25 characters, no leading or trailing space, zeros after the first NUL; 0.46 pages (bytes 344..353 were reserved 0) stay valid. The field is offered for firmware 0.51+ only (0.46 to 0.50 reject names over 10 characters). The older notes below describe the 0.46 prefix behaviour.
dev_name (bytes 344..507 stay reserved 0): a UTF-8/ASCII name prefix, NUL padded in 16 bytes, at most 10 characters, printable ASCII 0x20..0x7E only, no leading or trailing space; empty (old pages) = YAGCC. Anything else makes the whole ext page invalid (the configurator trims and filters as you type, so it never sends one). USB strings are UTF-16 and Bluetooth advertising is byte oriented, hence ASCII only.<name> Guitar Controller for XInput and the other defaults, <name> Guitar (HID), (Keyboard), (PS4), (PS5), <name> Guitar in Auto), the Bluetooth device name (<name> <mode>, e.g. "Adi XInput"; the advertisement keeps the SHORTENED name flag when it does not fit 18 bytes, the GAP name and the Device Information manufacturer are complete). Strings that must imitate real hardware (PS3 Guitar Hero / Rock Band, Wii, Switch HORI, Rock Band 4 Stratocaster, the OG Xbox, the Xbox 360 security string) and the "YAGCC Configuration" interface name are untouched.YAGCC, preview "Shows up as: ... Guitar Controller") in the last Setup step ("All done") and a Name panel at the top of Tune. Backups include it (section Controller name). Pure helpers in firmware/src/dev_name.h, tested in firmware/tests/host_map/dev_name_test.c (run by build.sh).The SW-520D is a cheap ball tilt switch: two legs, a metal ball closes the contacts when the switch points down within about 45 degrees, and the ball rattles and bounces a lot. It is a digital tilt switch like the mercury one (same tilt pin, enable and normally open / normally closed option) but needs a much stronger filter.
tilt_sw_type (0 = mercury / generic, today's behaviour; 1 = SW-520D) and 355 tilt_sw_filter_ms (0 = type default, 1..250 = settle time in ms). Anything else makes the ext page invalid; old pages hold 0, so behaviour is exactly as before (golden tests unchanged). Bytes 356..507 stay reserved 0.firmware/src/tilt_filter.h, used by input.c, tested on a PC in firmware/tests/host_map/tilt_filter_test.c): type 0 with settle 0 keeps the old lockout debouncer (at least 20 ms). Otherwise the tilt state changes only after the raw pin (already inverted for a normally closed switch) has been stable for the settle time, separate from the fret debounce. Type 1 additionally runs a majority window with hysteresis in front: 8 samples 1 ms apart, high at 6 or more, low at 2 or fewer, in between it holds, so a rattling ball while strumming does not flicker star power; the default settle time is 40 ms. The filtered state is what every tilt switch consumer uses (Acts as, Assign to and the status report).Bytes 328..353 dev_name (26, NUL padded), 354 tilt_sw_type, 355 tilt_sw_filter_ms, 356..507 reserved 0, 508 crc32.
Rock Band 4 PS4 guitar (1532:0401); console authentication is passed through to a controller on the USB host port |
| Rock Band 4 on PS4 / PS5 (experimental, untested on a console) |
| (assign on Modes tab) | PS5 guitar | Third-party PS5 Rock Band guitar; the console's security check and the signing of every input report are done by a Besavior P5General dongle on the USB host port (Santroller's approach) | PS5 games (experimental, untested on a console) |
| (assign on Modes tab) | Xbox One / Series guitar | Rock Band 4 Stratocaster over GIP (0738:02EA); authentication passed through to a controller on the USB host port | Rock Band 4 on Xbox One / Series (experimental, untested on a console) |
| Plus | Setup mode | XInput + web config for this boot only, nothing saved |
| Star + Plus | Bootloader | Jumps to UF2 mode so you can reflash without touching BOOTSEL |
| Star | Bluetooth pairing | Pico W / Pico 2 W: forget the old host and pair a new one (the USB mode is the default one) |
firmware/lib/psx_emulationfirmware/lib/wii_extension_emulationfirmware/lib/wii_remote_emulationLICENSE