Skip to content

Instantly share code, notes, and snippets.

@fxprime
Created January 7, 2026 04:41
Show Gist options
  • Select an option

  • Save fxprime/44fa8ef10a77da021eb3b68c7d4317b7 to your computer and use it in GitHub Desktop.

Select an option

Save fxprime/44fa8ef10a77da021eb3b68c7d4317b7 to your computer and use it in GitHub Desktop.
PS2 stream test with ui https://www.modulemore.com/ps2visualize
/**
PS2 Wireless Controller Data Streaming
Modified for web visualization with structured data format
Messages prefixed with:
- DATA: Controller state data
- LOG: User information
- ERROR: Error messages
- WARN: Warning messages
**/
#include <PS2X_lib.h>
PS2X ps2x;
int error = -1;
byte type = 0;
byte vibrate = 0;
unsigned long lastUpdate = 0;
const int UPDATE_INTERVAL = 50; // Send data every 50ms
void setup() {
Serial.begin(115200);
Serial.println("LOG:PS2 Controller Visualizer Starting...");
while (error != 0) {
// Setup pins: GamePad(CLK, CMD, CS, DAT, Pressures?, Rumble?)
error = ps2x.config_gamepad(6, 4, 5, 3, false, true);
if (error == 0) {
Serial.println("LOG:Controller configured successfully");
}
else if (error == 1) {
Serial.println("ERROR:No controller found, check wiring");
}
else if (error == 2) {
Serial.println("ERROR:Controller found but not accepting commands");
}
else if (error == 3) {
Serial.println("WARN:Controller refusing to enter Pressures mode");
}
type = ps2x.readType();
switch (type) {
case 0:
Serial.println("WARN:Unknown Controller type");
break;
case 1:
Serial.println("LOG:DualShock Controller Found");
break;
case 2:
Serial.println("WARN:GuitarHero Controller Found (Not supported)");
break;
}
delay(100);
}
Serial.println("LOG:Ready to stream controller data");
}
void loop() {
if (error == 1) return; // Skip if no controller
if (type == 1) { // DualShock Controller
ps2x.read_gamepad(false, vibrate);
unsigned long currentTime = millis();
if (currentTime - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = currentTime;
sendControllerData();
}
// Handle button events for logging
handleButtonEvents();
}
delay(10);
}
void sendControllerData() {
// Format: DATA:buttons,LX,LY,RX,RY,L2,R2,UP,DOWN,LEFT,RIGHT,vibrate
// buttons is a 16-bit value with each bit representing a button state
uint16_t buttons = 0;
// Pack button states into bits
if (ps2x.Button(PSB_SELECT)) buttons |= (1 << 0);
if (ps2x.Button(PSB_L3)) buttons |= (1 << 1);
if (ps2x.Button(PSB_R3)) buttons |= (1 << 2);
if (ps2x.Button(PSB_START)) buttons |= (1 << 3);
if (ps2x.Button(PSB_PAD_UP)) buttons |= (1 << 4);
if (ps2x.Button(PSB_PAD_RIGHT)) buttons |= (1 << 5);
if (ps2x.Button(PSB_PAD_DOWN)) buttons |= (1 << 6);
if (ps2x.Button(PSB_PAD_LEFT)) buttons |= (1 << 7);
if (ps2x.Button(PSB_L2)) buttons |= (1 << 8);
if (ps2x.Button(PSB_R2)) buttons |= (1 << 9);
if (ps2x.Button(PSB_L1)) buttons |= (1 << 10);
if (ps2x.Button(PSB_R1)) buttons |= (1 << 11);
if (ps2x.Button(PSB_GREEN)) buttons |= (1 << 12); // Triangle
if (ps2x.Button(PSB_RED)) buttons |= (1 << 13); // Circle
if (ps2x.Button(PSB_BLUE)) buttons |= (1 << 14); // X
if (ps2x.Button(PSB_PINK)) buttons |= (1 << 15); // Square
// Get analog values
byte lx = ps2x.Analog(PSS_LX);
byte ly = ps2x.Analog(PSS_LY);
byte rx = ps2x.Analog(PSS_RX);
byte ry = ps2x.Analog(PSS_RY);
// Get pressure values (0-255)
byte l2_pressure = ps2x.Analog(PSAB_L2);
byte r2_pressure = ps2x.Analog(PSAB_R2);
byte up_pressure = ps2x.Analog(PSAB_PAD_UP);
byte down_pressure = ps2x.Analog(PSAB_PAD_DOWN);
byte left_pressure = ps2x.Analog(PSAB_PAD_LEFT);
byte right_pressure = ps2x.Analog(PSAB_PAD_RIGHT);
// Send structured data
Serial.print("DATA:");
Serial.print(buttons);
Serial.print(",");
Serial.print(lx);
Serial.print(",");
Serial.print(ly);
Serial.print(",");
Serial.print(rx);
Serial.print(",");
Serial.print(ry);
Serial.print(",");
Serial.print(l2_pressure);
Serial.print(",");
Serial.print(r2_pressure);
Serial.print(",");
Serial.print(up_pressure);
Serial.print(",");
Serial.print(down_pressure);
Serial.print(",");
Serial.print(left_pressure);
Serial.print(",");
Serial.print(right_pressure);
Serial.print(",");
Serial.println(vibrate);
}
void handleButtonEvents() {
// Log button press/release events
static uint16_t lastButtons = 0;
uint16_t currentButtons = 0;
if (ps2x.Button(PSB_SELECT)) currentButtons |= (1 << 0);
if (ps2x.Button(PSB_L3)) currentButtons |= (1 << 1);
if (ps2x.Button(PSB_R3)) currentButtons |= (1 << 2);
if (ps2x.Button(PSB_START)) currentButtons |= (1 << 3);
if (ps2x.Button(PSB_PAD_UP)) currentButtons |= (1 << 4);
if (ps2x.Button(PSB_PAD_RIGHT)) currentButtons |= (1 << 5);
if (ps2x.Button(PSB_PAD_DOWN)) currentButtons |= (1 << 6);
if (ps2x.Button(PSB_PAD_LEFT)) currentButtons |= (1 << 7);
if (ps2x.Button(PSB_L2)) currentButtons |= (1 << 8);
if (ps2x.Button(PSB_R2)) currentButtons |= (1 << 9);
if (ps2x.Button(PSB_L1)) currentButtons |= (1 << 10);
if (ps2x.Button(PSB_R1)) currentButtons |= (1 << 11);
if (ps2x.Button(PSB_GREEN)) currentButtons |= (1 << 12);
if (ps2x.Button(PSB_RED)) currentButtons |= (1 << 13);
if (ps2x.Button(PSB_BLUE)) currentButtons |= (1 << 14);
if (ps2x.Button(PSB_PINK)) currentButtons |= (1 << 15);
// Handle X button for vibration
if (ps2x.NewButtonState(PSB_BLUE)) {
if (ps2x.Button(PSB_BLUE)) {
vibrate = 255;
Serial.println("LOG:Vibration started (X pressed)");
} else {
vibrate = 0;
Serial.println("LOG:Vibration stopped (X released)");
}
}
lastButtons = currentButtons;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment