Skip to the content
2 layers194.3 × 109.2 mmUsb controller-32, the printed circuit board in 3D

A USB HID gamepad controller built on the PIC32MX250F128B microcontroller.

Size
194.3 × 109.2 mm
Copper layers
2
Thickness
1.6 mm
Parts
93
Nets
77
Pads
301
Tracks, vias
554, 5,349
Pours
2
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
16 Mar 2026
Updated
6 Jun 2026

Overview

Usb controller-32 is an open-source printed circuit board by jcksnvllxr80, from the jcksnvllxr80/usb-controller-32 repository on GitHub. It is a 2-layer board of 194.3 × 109.2 mm with 93 parts on 77 nets, routed with 554 tracks and 5,349 vias.

It is built around the PIC32MX250F128B-I/SS and MAX3232ID. Its parts include 38 resistors, 27 capacitors, 18 switches, 3 ICs and 3 connectors. It belongs with the keyboards and input boards and the PIC boards of this library.

Main components

2

README

README.md

USB Controller 32

A USB HID gamepad controller built on the PIC32MX250F128B microcontroller. The firmware reads button inputs from GPIO pins, two potentiometers on the PIC32 ADC, and an MCP23017 I2C I/O expander, then reports them to a host PC as a standard USB HID gamepad. The board-level serial path uses a MAX3232 level shifter, and the MCU clock is provided by a 20 MHz crystal. Built with MPLAB Harmony 3, FreeRTOS, and C++.

Block Diagram

Features

  • USB HID gamepad with 18 button inputs (2 direct GPIO + 16 via MCP23017)
  • 8-byte HID input report with 18 buttons, hat switch, and two live analog axes
  • MCP23017 I2C I/O expander with interrupt-driven input detection
  • MAX3232-backed debug serial / RS-232 path
  • POT_1 and POT_2 sampled on AN4 / AN5 for Z and Rz
  • Send-on-change HID reports for buttons and potentiometer axes
  • Rate-limited serial logging for potentiometer changes with POT_1 / POT_2 identification
  • FreeRTOS-based task scheduling
  • UART debug logging and USB/HID diagnostics
  • Green and red status LEDs

Hardware Used

Main ICs and timing parts on this design:

  • PIC32MX250F128B - main microcontroller, USB device controller, ADC, GPIO, I2C, and UART
  • MCP23017 - 16-bit I2C GPIO expander for the additional button inputs
  • MAX3232 - UART level shifter for the board's serial / RS-232 debug path
  • 20 MHz crystal - external clock source for the PIC32MX250F128B (load caps C17/C18 must be 20 pF — see Crystal Load Capacitors)
  • 2x linear potentiometers - analog controls for POT_1 and POT_2, mapped to HID Z and Rz
  • Mini USB breakout - USB connector breakout for the device port, such as the small Adafruit mini USB breakout the board is using

Hardware Notes

  • Crystal load capacitors C17/C18 must be 20 pF. A 0.1 µF value stops the 20 MHz crystal from oscillating on the PCB (the board powers up briefly, then drops off USB). It only appeared to work on the breadboard because the long jumper wires masked the oversized caps. Full explanation: Crystal Load Capacitors.

Architecture

MCP23017 Pinout

UML Class Diagram

UML Diagram

State Machine

State Diagram

Pin Assignment Table

PIC32MX250F128B Direct I/O

SignalPinPortDirectionDescription
MCLR1—InputMaster clear (active-low reset); 10k pull-up to VDD; PICkit 5 pin 1 (VPP)
PGED12RA0ProgrammingICSP data (PICkit 5 pin 4)
PGEC13RA1ProgrammingICSP clock (PICkit 5 pin 5)
GREEN_LED4RB0OutputGreen status LED
RED_LED5RB1OutputRed status LED
POT_16RB2 / AN4InputAnalog potentiometer mapped to HID Z axis
POT_27RB3 / AN5InputAnalog potentiometer mapped to HID Rz axis
VSS8—PowerGround
OSC19RA2Input20 MHz crystal input
OSC210RA3Output20 MHz crystal output
U1TX11RB4OutputUART1 transmit (debug)
U1RX12RA4InputUART1 receive (debug)
VDD13—Power5V supply
INTERRUPT_A14RB5InputMCP23017 Port A interrupt (active-low)
VBUS15—PowerUSB 5V bus voltage; connected to VCC
INTERRUPT_B16RB7InputMCP23017 Port B interrupt (active-low)
SCL117RB8OutputI2C1 clock to MCP23017
SDA118RB9BidirectionalI2C1 data to MCP23017
VSS19—PowerGround
VCAP20—PowerInternal core regulator output; 0.1µF cap to VSS
D+21—BidirectionalUSB data plus
D−22—BidirectionalUSB data minus
VUSB3V323—PowerUSB 3.3V supply; decoupling capacitors to GND
RB1324RB13NCNot connected
BUTTON_125RB14InputDirect button input 1
BUTTON_226RB15InputDirect button input 2
AVSS27—PowerAnalog ground
AVDD28—Power5V analog supply

MCP23017 I/O Expander (I2C address 0x20)

PortPinsDirectionPull-upsInterruptDescription
Port AGPA0–GPA7InputEnabledEnabled (interrupt-on-change)8 button inputs
Port BGPB0–GPB7InputEnabledEnabled (interrupt-on-change)8 button inputs

Input/Output Summary

TypeCountSourceDetails
Button inputs (direct)2PIC32 GPIORB14, RB15
Button inputs (expanded)16MCP23017 Port A & BGPA0–7, GPB0–7
Analog inputs2PIC32 ADCPOT_1 on AN4 drives HID Z, POT_2 on AN5 drives HID Rz
LED outputs2PIC32 GPIOGreen (RB0), Red (RB1)
USB HID1USB peripheral18 buttons, hat switch, X/Y centered, live Z/Rz in an 8-byte report
Debug UART1UART1 via MAX3232115200 baud debug/serial path (TX: RB4, RX: RA4)
I2C bus1I2C1MCP23017 at 0x20

Getting Started

Prerequisites

Install MPLAB for VS Code

  1. Open VS Code (or VS Code Insiders).
  2. Go to the Extensions view (Ctrl+Shift+X).
  3. Search for "MPLAB" and install the Microchip MPLAB extension pack.
  4. The extension will prompt you to install the XC32 compiler and required device packs if they are not found. Follow the prompts.
  5. Restart VS Code after installation.

Harmony Configurators

Clone and Build

bash
git clone https://github.com/jcksnvllxr80/usb-controller-32.git
cd usb-controller-32
  1. Open the folder in VS Code.
  2. The MPLAB extension should detect the project automatically via the CMake configuration in the cmake/ directory.
  3. Select the usb-controller-32 project and the default configuration from the MPLAB project view.
  4. Click Build (or press Ctrl+Shift+B).

Program the Device

  1. Connect the PICkit 5 to the ICSP header on your board (ensure correct pin 1 orientation).
  2. In the MPLAB extension, select PICkit 5 as the hardware tool.
  3. Set the programming speed to Low if you encounter connection issues.
  4. Click Program to flash the .hex file to the PIC32MX250F128B.

Warning: Use a native USB 2.0 port when connecting this controller to the PC. On some machines, USB 3.x ports/controllers can fail enumeration or produce a Windows Code 10 error with this hardware. If your machine does not have a USB 2.0 port, connect the controller through a USB 2.0 hub.

Verify Operation

  1. After programming, the device should enumerate as a USB HID gamepad on the host PC.
  2. Open Set up USB game controllers (Windows) or a gamepad tester to confirm button presses and Z / Rz potentiometer movement are registered.
  3. Connect a serial terminal (115200 baud, 8N1) to UART1 to view debug logs, potentiometer change logs, and issue commands.

UART Diagnostics

Helper scripts:

  • powershell -ExecutionPolicy Bypass -File .\tools\uart_query.ps1
  • powershell -ExecutionPolicy Bypass -File .\tools\uart_cmd.ps1 -cmd "status"

Useful commands:

  • status - GPIO, USB, and LED summary
  • usb - USB device state and register dump
  • enum - enumeration counters and last setup request
  • hid - HID readiness, send counters, and current report bytes
  • usblog - recent USB transaction log
  • usbdbg - toggle live USB debug logging
  • usbreset - soft detach/reattach to force re-enumeration

Automatic serial logs:

  • Potentiometer changes are logged automatically as [POT] POT_1 axis=... and/or [POT] POT_2 axis=...
  • Logs are only emitted when the scaled axis value changes
  • Pot logs are rate-limited to 5 lines per second total

Firmware Notes

  • GPIO and MCP23017 interrupts only latch state. HID reports are built and sent from APP_Tasks().
  • POT_1 and POT_2 are polled in APP_Tasks(), scaled from 10-bit ADC samples to 8-bit HID axis values, and mapped to HID Z and Rz.
  • Potentiometer state is cached, so a new HID report is only queued when a button changes or when the last-sent Z / Rz byte changes.
  • Potentiometer serial logs identify which input changed (POT_1, POT_2, or both), skip repeated values, and are rate-limited to 5 lines per second.
  • HID reports are only queued when button or axis state changes, which keeps traffic and debug noise down.

Project Structure

text
usb-controller-32/
├── cmake/                      # CMake build configurations
├── docs/                       # Datasheets, block diagram, images
├── tools/                      # Flash and UART helper scripts
├── usb-controller-32/
│   ├── mcc/                    # MPLAB Code Configurator files
│   └── src/
│       ├── main.cpp            # Entry point (SYS_Initialize + SYS_Tasks)
│       ├── app.cpp / app.h     # App task, GPIO/MCP state, USB HID send path
│       ├── command_handler.cpp / .h # UART command parser and diagnostics
│       ├── gamepad.cpp / .h    # USB HID gamepad driver
│       ├── mcp23017.cpp / .h   # MCP23017 I2C I/O expander driver
│       ├── logger.cpp / .h     # UART debug logger (singleton)
│       ├── usb_debug.c / .h    # USB debug logging helpers
│       ├── config/             # Harmony-generated peripheral config
│       └── third_party/rtos/   # FreeRTOS source
└── README.md

Sponsor

PCB prototyping for this project is sponsored by PCBWay.

PCBWay makes it easy to go from design files to manufactured boards. Upload your Gerber files, pick your board specs (layers, thickness, surface finish, color, etc.), and get an instant quote. Orders typically ship within a few days. Their online ordering process is straightforward — just create an account, upload your files, review the specs, and check out.

License

See Microchip's license terms in the source file headers.

Parts

93
QtyValueFootprintReferences
3212kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR1, R2, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23 +16
250.1µFCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P2.50mmC1, C2, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C24, C25 +9
18SW_Push_DualButton_Switch_THT:SW_TH_Tactile_Omron_B3F-100xSW1, SW2, SW3, SW4, SW5, SW6, SW7, SW10, SW11, SW12, SW13, SW14, SW15, SW16, SW17, SW18 +2
20.01µFCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P2.50mmC22, C23
24.7kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR36, R37
2R_PotentiometerPotentiometer_THT:Potentiometer_Bourns_3386P_VerticalRV1, RV2
11.2kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR34
110kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR35
115kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR38
120MHzCrystal:Crystal_HC49-4H_VerticalY1
18.2kResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR33
1Conn_01x03_PinConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ3
1Conn_01x08_PinConnector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_VerticalJ2
1LED_Dual_AKALED_THT:LED_D3.0mm-3D2
1MAX3232Package_DIP:DIP-16_W7.62mmU2
1MCP23017x-x-SPPackage_DIP:DIP-28_W7.62mmU3
1PIC32MX250F128BPackage_DIP:DIP-28_W7.62mmU1
1USB_MiniB_Adafruit_Breakoutextra:USB_MiniB_Adafruit_BreakoutJ1

Similar boards

  • 2 layers111.8 × 161.8 mmTrac, the printed circuit board in 3D

    Trac

    tractiming/trac-pcb

    kicad project for rfid communication board

    103 parts1MIT
  • 2 layers64.1 × 33.4 mm32mx2xx, the printed circuit board in 3D

    32mx2xx

    PinguinoIDE/pinguino-cad

    Open Hardware Pinguino boards (and extensions) CAD files (Kicad)

    41 parts11GPL-2.0
  • 2 layers191.5 × 97.6 mmOpen Apple 1 SBC, the printed circuit board in 3D

    Open Apple 1 SBC

    davischris/OpenAC1

    This work is largely based on the work of Tor-Eirik Bakke Lunde (https://github.com/tebl/RC6502-Apple-1-Replica).

    72 parts4GPL-3.0
  • 2 layers92 × 76 mmILV2-7-5 Clock, the printed circuit board in 3D

    ILV2-7-5 Clock

    biomurph/ILV2-7-5_VFD_Display

    KiCAD circuit for a VFD Clock using the Popular ILV2-7/5 flat tube segmented nixie

    50 parts3GPL-3.0
  • 4 layers61.4 × 61.3 mmCyton wired, the printed circuit board in 3D

    Cyton wired

    BostonUniversitySeniorDesign/brain-4ce

    Where thoughts become motion. Designed by BU ECE 2023 Senior Design Capstone Team 4 From left to right: Brendan Shortall, Mitchell Gilmore, Dayanna De La Torres, Jonathan Mikalov, Alexander Johnson

    100 parts3
  • 2 layers45 × 39 mmHeartBone, the printed circuit board in 3D

    HeartBone

    biomurph/HeartBone_Hardware_v2

    A Place For HeartBone Hardware

    42 partsMIT
  • 2 layers125 × 113 mmVideo terminal, the printed circuit board in 3D

    Video terminal

    ibm2030/EDUC8

    EDUC-8 recreation by Gwyllym Suter

    41 parts13
  • 2 layers189.5 × 204.9 mmSmartSpin2k Panelized, the printed circuit board in 3D

    SmartSpin2k Panelized

    doudar/SmartSpin2k

    Transform your spin bike into a Smart Trainer!

    749 parts292GPL-2.0

Questions

How big is the Usb controller-32 PCB?

It measures 194.3 × 109.2 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Usb controller-32 use?

93 parts, built around the PIC32MX250F128B-I/SS and MAX3232ID. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Usb controller-32 KiCad files?

From the jcksnvllxr80/usb-controller-32 repository on GitHub, at the commit this page was made from: the board is pcb/usb-controller-32/usb-controller-32.kicad_pcb and its schematic pcb/usb-controller-32/usb-controller-32.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Usb controller-32 design in my own project?

Its repository states no licence, so its author keeps all rights: ask jcksnvllxr80 before reusing the design.