Arnov Sharma
Published © MIT

Pocket SNES

Miniature version of the Classic SNES Controller.

BeginnerFull instructions provided1 hour710
Pocket SNES

Things used in this project

Hardware components

RP2040
Raspberry Pi RP2040
×1
PCBWay Custom PCB
PCBWay Custom PCB
×1

Software apps and online services

Fusion
Autodesk Fusion
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

cad file

Schematics

SCH

Code

code

C/C++
#include "Adafruit_TinyUSB.h"
#include <Adafruit_NeoPixel.h>

// === WS2812 Setup ===
#define LED_PIN     16     // GPIO16
#define NUM_LEDS    1
Adafruit_NeoPixel pixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// === Gamepad Setup ===
#define NUM_BUTTONS 12
const uint8_t buttonPins[NUM_BUTTONS] = {
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};

// Gamepad HID Descriptor (12 buttons)
uint8_t const hid_report_descriptor[] = {
  0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, 0x15, 0x00,
  0x25, 0x01, 0x35, 0x00, 0x45, 0x01, 0x75, 0x01,
  0x95, 0x0C, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0C,
  0x81, 0x02, 0x75, 0x01, 0x95, 0x04, 0x81, 0x03,
  0xC0
};

Adafruit_USBD_HID usb_hid;
uint8_t report[2] = {0};

void setup() {
  for (int i = 0; i < NUM_BUTTONS; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }

  // Setup NeoPixel
  pixel.begin();
  pixel.setBrightness(50);
  pixel.show(); // Initialize to off

  // Setup USB HID
  usb_hid.setReportDescriptor(hid_report_descriptor, sizeof(hid_report_descriptor));
  usb_hid.setPollInterval(2);
  usb_hid.begin();

  while (!USBDevice.mounted()) delay(10);
}

void loop() {
  static uint32_t last = 0;
  if (millis() - last < 10) return;
  last = millis();

  // Clear report
  report[0] = 0;
  report[1] = 0;
  bool anyPressed = false;

  for (int i = 0; i < NUM_BUTTONS; i++) {
    if (digitalRead(buttonPins[i]) == LOW) {
      report[i / 8] |= (1 << (i % 8));
      anyPressed = true;
    }
  }

  // Update LED: Purple if any button is pressed
  if (anyPressed) {
    pixel.setPixelColor(0, pixel.Color(255, 0, 255)); // Purple
  } else {
    pixel.setPixelColor(0, 0); // Off
  }
  pixel.show();

  usb_hid.sendReport(0, report, sizeof(report));
}

Credits

Arnov Sharma
345 projects • 353 followers
I'm Arnov. I build, design, and experiment with tech—3D printing, PCB design, and retro consoles are my jam.

Comments