#include "Adafruit_TinyUSB.h"
/* USB HID */
hid_gamepad_report_t report;
Adafruit_USBD_HID usb_hid;
//GPIO Pins
/* Controller Buttons */
//const int topBtnPin = 38;
const int bottomBtnPin = 42;
const int joyYpin = 35; // Analog
const int joyXpin = 34; // Analog
const int joySEL = 33; // Analog
/* LED */
//const int powerled = 3;
/* Joystick Deadzone */
int joyCenterX;
int joyCenterY;
/* Gamepad report Structure */
// typedef struct {
// int16_t x;
// int16_t y;
// uint8_t buttons;
// } GamepadReport;
//GamepadReport report;
// Handle Deadzone
int applyDeadzone(int val, int center, int deadzone = 150) {
if (abs(val - center) < deadzone) {
return center;
}
return val;
}
// Normalize to -32768 - 32767 (standard for gamepads)
int16_t normalizeAxis(int raw, int center) {
int val = raw - center; // shift center to 0
// clamp to avoid overflow
if (val > 2048) val = 2048;
if (val < -2048) val = -2048;
float scaled = (float)val / 2048.0; // normalize to -1.0 to +1.0
return (int16_t)(scaled * 32767);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial && millis() < 5000); // Wait up to 5 seconds for Serial Monitor
Serial.println("Staring Controller...\n");
//pinMode(topBtnPin, INPUT_PULLUP);
pinMode(joySEL, INPUT_PULLUP);
pinMode(bottomBtnPin, INPUT_PULLUP);
//pinMode(powerled, OUTPUT);
//Idle LED ON
//digitalWrite(powerled, HIGH);
// Calibrate center (don't touch joystick)
delay(500);
joyCenterY = analogRead(joyYpin);
joyCenterX = analogRead(joyXpin);
// Setup HID as generic gamepad
static const uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_GAMEPAD()
};
TinyUSBDevice.setManufacturerDescriptor("");
TinyUSBDevice.setProductDescriptor("USB Atari 2600 Dual controller");
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.begin();
}
void loop() {
Serial.println("Controller code entered loop\n");
// Buttons (LOW = pressed because of pullup)
//if (!usb_hid.ready()) return;
// Reset report
memset(&report, 0, sizeof(report));
//bool topPressed = !digitalRead(topBtnPin);
bool joyPressed = !digitalRead(joySEL);
bool bottomPressed = !digitalRead(bottomBtnPin);
int rawX = applyDeadzone(analogRead(joyXpin), joyCenterX);
int rawY = applyDeadzone(analogRead(joyYpin), joyCenterY);
report.x = normalizeAxis(rawX, joyCenterX);
report.y = normalizeAxis(rawY, joyCenterY);
report.buttons = 0;
if (joyPressed) {
Serial.println("joystick pressed");
report.buttons |= 0x01;
}
if (bottomPressed) {
Serial.println("bottom button pressed");
report.buttons |= 0x02;
}
usb_hid.sendReport(0, &report, sizeof(report));
delay(10); // this speeds up the simulation
}