-
Pulsadores Arcade Efecto Hall
18 hours ago • 0 commentsActualmente estoy haciendo pruebas con sensores hall activados por imán. Este mismo recurso es el que quiero usar para añadir mando analógico a la palanca restrictor/rotary. Es más sencillo empezar por un pulsador y experimentar.
Patillaje del SS49E
Con la cara que no es plana del sensor mirando hacia ti
y las patillas hacia abajo:Pin 1 → VCC (alimentación)
Pin 2 → GND
Pin 3 → VOUT (salida analógica)![]()
Conexión típica al Arduino Pro Micro
Para configurar el sensor he usado el código para mandos xinput, con el que configuraremos los movimientos del joy y la función de los pulsadores.
https://github.com/dmadison/ArduinoXInput
Ya he modificado el código para configurar los tiggers :
else { // Read trigger potentiometer values int triggerLeft = analogRead(Pin_TriggerL); int triggerRight = analogRead(Pin_TriggerR); // Escalar el sensor Hall (centro → mínimo) triggerLeft = constrain(triggerLeft, 520, 780); triggerLeft = map(triggerLeft, 520, 780, 0, 1023); triggerRight = constrain(triggerRight, 580, 780); triggerRight = map(triggerRight, 580, 780, 0, 1023); // Enviar a XInput XInput.setTrigger(TRIGGER_LEFT, triggerLeft); XInput.setTrigger(TRIGGER_RIGHT, triggerRight); }Sensor Pro Micro Pin 1 (VCC) 5V Pin 2 (GND) GND Pin 3 (VOUT) A4 o A5 -
Array Imagen OLED Restrictor III
18 hours ago • 0 comments![]()
// ROMBO 128x64 const unsigned char bitmap_rombo[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x83, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xc0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0xf0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xf0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0xe0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xf0, 0x01, 0x80, 0x03, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xf0, 0x01, 0x80, 0x03, 0xf8, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8f, 0xf0, 0x1d, 0x8c, 0x03, 0xf8, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x87, 0xf0, 0x79, 0x8f, 0x03, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x80, 0xf9, 0x8e, 0x80, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xf8, 0x0e, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xff, 0x3e, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xff, 0xff, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x7f, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3f, 0xfe, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0xf8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xc0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x83, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -
Array Imagen OLED Restrictor II
18 hours ago • 0 comments![]()
// CUADRADO 128x64 const unsigned char bitmap_cuadrado[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xc0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x03, 0xf0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x03, 0xf0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x01, 0xe0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf8, 0x01, 0xe0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf8, 0x00, 0xc0, 0x07, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x03, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x01, 0x00, 0x00, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x00, 0x80, 0x01, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xe0, 0x00, 0xc0, 0x01, 0xfd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xe0, 0x0f, 0x9c, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x3d, 0x8f, 0x00, 0xf9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x5d, 0xc6, 0x80, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x5c, 0x8e, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x5f, 0xfe, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x7f, 0xff, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x3f, 0xff, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x02, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x07, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf8, 0x00, 0x00, 0x07, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf8, 0x01, 0xe0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x01, 0xe0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x01, 0xe0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x03, 0xf0, 0x03, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -
Array Imagen OLED Restrictor I
3 days ago • 0 commentsCuando subas el PNG en
https://javl.github.io/image2cpp/Selecciona exactamente:
- ✔ Monochrome
- ✔ Invert image → SOLO si el fondo te sale negro
- ✔ Horizontal byte orientation
- ✔ Arduino code
- ✔ Draw mode: Vertical (page addressing) → (si aparece opción)
Resolución debe marcar:
128 x 64
Si no, el PNG no es correcto.
![]()
// OCTOGONO 128x64 const unsigned char bitmap_octogono[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0xe0, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0f, 0xf0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0xc0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe0, 0x03, 0xc0, 0x07, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xe0, 0x01, 0x80, 0x07, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xe0, 0x00, 0x00, 0x07, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf8, 0x00, 0x00, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x00, 0x00, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x07, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x03, 0xc0, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xfc, 0x00, 0x09, 0x90, 0x00, 0x3f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xfc, 0x00, 0xb9, 0x8d, 0x00, 0x3f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x00, 0xf1, 0x8f, 0x80, 0x3e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x01, 0x71, 0x8e, 0x80, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x78, 0x1e, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0xbf, 0xfd, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xcf, 0xf3, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0x00, 0x00, 0x0f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0x00, 0x00, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xe0, 0x00, 0x00, 0x07, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xe0, 0x00, 0x00, 0x07, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xf0, 0x03, 0xc0, 0x0f, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0xc0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0f, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x07, 0xe0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x03, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -
Restrictor automático + Rotary en JOY SANWA II
3 days ago • 0 commentsEn los últimos cambios realizados. He añadido un microswitch de palanca para tener una referencia de posición. Concretamente en la figura octogonal, puesto que es la primera figura antes del avance del engranaje.
Uno de los elementos con el que más dificultad estoy teniendo, es el amarre del rotary con el eje. Hay muy poco espacio en el eje después del circlip, donde encajarlo. En estos momentos tengo dos tornillos M2 haciendo de prisionero roscador sobre los injertos de la misma métrica.
He usado injertos para asegurar el restrictor. A pesar de encajar a presión entre las 2 piezas. He preferido atornillarla.
Aquí dejo un par de enlaces de youtube, donde desmontan un SANWA. Para que veáis lo sencillo que es un joystick
https://youtu.be/wrguS8764nY?si=oV7sMrTcUV4zLuqK
Y una guía de cómo elegir un joystick de los compañeros de Arcade Express. Una tienda especializada en ARCADE muy recomendable
![]()
Para la programación del arduino, tenemos que partir de la medición en el CAD del giro del engranaje que mueve las piezas para la figura. En nuestro caso fuero 55 grados. Con estos datos y sabiendo los pasos por giro de nuestro motor. Definimos el sketch.
#include <Stepper.h> #include <Mouse.h> #include <EEPROM.h> // ================= CONFIGURACIÓN ================= #define STEPS_PER_REV 4096 #define STEPS_55_DEG 586 #define IN1 6 #define IN2 7 #define IN3 8 #define IN4 9 #define BUTTON_PIN 5 #define HOME_PIN 4 #define outputA 0 #define outputB 1 #define EEPROM_POS_ADDR 0 #define EEPROM_DIR_ADDR 1 Stepper motor(STEPS_PER_REV, IN1, IN3, IN2, IN4); int UltimoEstado = 0; // ================= ESTADOS ================= enum Posicion { POS_8, POS_0, POS_4 }; Posicion posicionActual = POS_8; bool yendoHacia4 = true; long pasosActuales = 0; // ================= EEPROM ================= void guardarEstado() { EEPROM.update(EEPROM_POS_ADDR, posicionActual); EEPROM.update(EEPROM_DIR_ADDR, yendoHacia4); } void cargarEstado() { byte pos = EEPROM.read(EEPROM_POS_ADDR); byte dir = EEPROM.read(EEPROM_DIR_ADDR); if (pos <= 2) posicionActual = (Posicion)pos; else posicionActual = POS_8; yendoHacia4 = dir; } // ================= HOMING ================= void hacerHoming() { motor.setSpeed(4); if (digitalRead(HOME_PIN) == LOW) { posicionActual = POS_8; pasosActuales = 0; yendoHacia4 = true; // asegurar coherencia return; } while (digitalRead(HOME_PIN) == HIGH) { motor.step(-5); } delay(100); motor.step(20); posicionActual = POS_8; pasosActuales = 0; yendoHacia4 = true; } // ================= MOVIMIENTO ABSOLUTO ================= void moverA(Posicion destino) { long pasosDestino = 0; if (destino == POS_8) pasosDestino = 0; if (destino == POS_0) pasosDestino = STEPS_55_DEG; if (destino == POS_4) pasosDestino = STEPS_55_DEG * 2; long diferencia = pasosDestino - pasosActuales; if (diferencia != 0) { motor.step(diferencia); } pasosActuales = pasosDestino; posicionActual = destino; guardarEstado(); } // ================= SETUP ================= void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(HOME_PIN, INPUT_PULLUP); pinMode(outputA, INPUT_PULLUP); pinMode(outputB, INPUT_PULLUP); motor.setSpeed(5); Serial.begin(115200); delay(1000); attachInterrupt(digitalPinToInterrupt(outputA), Rotary, CHANGE); attachInterrupt(digitalPinToInterrupt(outputB), Rotary, CHANGE); Mouse.begin(); // ---- REFERENCIA FÍSICA ---- hacerHoming(); // ---- CARGAR EEPROM ---- cargarEstado(); // ---- RESTAURAR POSICIÓN ---- moverA(posicionActual); // ---- ASEGURAR COHERENCIA SECUENCIAL ---- if (posicionActual == POS_8) { yendoHacia4 = true; } } // ================= LOOP ================= void loop() { // ---------- BOTÓN ---------- static bool lastButtonState = HIGH; bool buttonState = digitalRead(BUTTON_PIN); if (lastButtonState == HIGH && buttonState == LOW) { moverRestrictorSecuencial(); delay(300); } lastButtonState = buttonState; // ---------- PUERTO SERIE ---------- if (Serial.available()) { char comando = Serial.read(); if (comando == '8') moverA(POS_8); if (comando == '0') moverA(POS_0); if (comando == '4') moverA(POS_4); } } // ================= SECUENCIAL BOTÓN ================= void moverRestrictorSecuencial() { if (yendoHacia4) { if (posicionActual == POS_8) { moverA(POS_0); } else if (posicionActual == POS_0) { moverA(POS_4); yendoHacia4 = false; } } else { if (posicionActual == POS_4) { moverA(POS_0); } else if (posicionActual == POS_0) { moverA(POS_8); yendoHacia4 = true; } } } // ================= ROTARY ================= void Rotary() { int EstadoInicial = !digitalRead(outputA); if (EstadoInicial != UltimoEstado) { if (!digitalRead(outputB) != EstadoInicial) { Mouse.move(+5,0,0); } else { Mouse.move(-5,0,0); } } UltimoEstado = EstadoInicial; }🧠 1️⃣ Librerías
#include <Stepper.h>
#include <Mouse.h>
#include <EEPROM.h>
🔹 Stepper
Controla el 28BYJ-48 con la placa ULN2003.
- Modo por pasos
- Control directo de número de pasos
- Suficiente porque solo tienes 3 posiciones fijas
🔹 Mouse
Permite que el Pro Micro se comporte como dispositivo HID.
Se usa en el rotary:
Mouse.move(+5,0,0);
Esto convierte el encoder en movimiento de ratón.
🔹 EEPROM
Permite guardar:
- Última posición
- Dirección secuencial
Para que al reiniciar no pierda estado.
⚙️ 2️⃣ Definiciones de hardware
#define STEPS_PER_REV 4096
#define STEPS_55_DEG 586
- 4096 pasos = vuelta completa del 28BYJ-48
- 586 pasos = 55° reales de la rueda grande (calculados con relación 45/24 y ajuste fino)
#define IN1 6
#define IN2 7
#define IN3 8
#define IN4 9
Pines hacia ULN2003.
El orden en el constructor es:
Stepper motor(STEPS_PER_REV, IN1, IN3, IN2, IN4);
Esto es importante porque el 28BYJ necesita secuencia concreta.
#define BUTTON_PIN 5
#define HOME_PIN 4
- BUTTON_PIN → cambio secuencial manual
- HOME_PIN → switch físico en posición 8
#define outputA 0
#define outputB 1
Pines del encoder rotativo (interrupciones).
🧠 3️⃣ Modelo de estados
enum Posicion { POS_8, POS_0, POS_4
};
Muy buena decisión.
No trabajas con grados. No trabajas con pasos.
Trabajas con estados lógicos.
Esto hace el sistema más robusto.
Variables globales importantes:
Posicion posicionActual = POS_8;
bool yendoHacia4 = true;
long pasosActuales = 0;
🔹 posicionActual
Estado lógico actual.
🔹 yendoHacia4
Controla el modo secuencial del botón.
🔹 pasosActuales
Posición real en pasos respecto a HOME.
Este es el “eje absoluto” interno.
💾 4️⃣ EEPROM
Guardar:
guardarEstado();
Se guarda:
- posición
- dirección secuencial
Se usa EEPROM.update() (muy bien hecho):
Solo escribe si cambia → evita desgaste.
🏠 5️⃣ Homing
void hacerHoming()
Lógica:
- Si ya está tocando el switch → estamos en 8.
- Si no:
- Mover lentamente hacia atrás
- Hasta que se active
- Liberar 20 pasos
Después:
pasosActuales = 0;
posicionActual = POS_8;
Eso convierte HOME en referencia absoluta 0.
Esto es lo que hace que el sistema sea mecánicamente fiable.
🎯 6️⃣ Movimiento absoluto
void moverA(Posicion destino)
Aquí está la clave de la robustez.
No haces movimiento relativo. Haces movimiento absoluto.
Primero traduces estado → pasos:
if (destino == POS_8) pasosDestino = 0;
if (destino == POS_0) pasosDestino = STEPS_55_DEG;
if (destino == POS_4) pasosDestino = STEPS_55_DEG * 2;
Luego calculas diferencia:
long diferencia = pasosDestino - pasosActuales;
Y solo mueves lo necesario.
Eso evita acumulación de error.
🔁 7️⃣ Secuencial con botón
void moverRestrictorSecuencial()
Secuencia:
8 → 0 → 4 → 0 → 8
Se controla con:
yendoHacia4
Este diseño evita que tengas que usar condicionales complejos.
🔌 8️⃣ Control por serie
En loop:
if (Serial.available())
Lee un carácter:
'8'
'0'
'4'
Y llama a moverA().
Es completamente independiente del botón.
Eso permite:
- RetroBat automático
- Botón manual
- Control externo
Todo convive.
🖱 9️⃣ Rotary con interrupciones
attachInterrupt(digitalPinToInterrupt(outputA), Rotary, CHANGE);
Cada cambio en encoder:
- Detecta sentido
- Mueve ratón
No bloquea el loop. No interfiere con el motor. Bien aislado.
Falta añadir una mini pantalla para mostrar la posición en la que estamos.
-
Retrobat + restrictor
5 days ago • 0 comments🕹 PROYECTO: Restrictor automático integrado con RetroBat + MAME
🎯 Objetivo
-
Juegos 4-way → posición 4 (rombo)
-
Juegos de lucha (lista específica) → posición 8 (octógono)
-
Todo lo demás → posición 0 (cuadrado)
-
Compatible con botón manual
-
Compatible con control por serie
-
Sin romper RetroBat ni tu
.batde pantallas
🧠 Arquitectura final correcta
NO tocamos el XML para meter comandos raros.
La solución profesional fue:
👉 Mantener el
<command>original
👉 Integrar el restrictor dentro del.batque ya lanza MAMEEsto evita problemas con
&,&&y procesos de Windows.🛠 1️⃣ Instalación de Python
Descargar
Ir a:
https://www.python.org/downloads/
Muy importante
Marcar la casilla:
☑ Add Python to PATH
Luego instalar.
Verificar instalación
Abrir CMD:
python --version
Debe devolver algo como:
Python 3.x.x
🛠 2️⃣ Instalar pyserial
En CMD:
pip install pyserial
Si falla:
python -m pip install pyserial
🛠 3️⃣ Crear el plugin restrictor
Ruta:
C:\RetroBat\plugins\restrictor.py
Crear con VS Code o bloc de notas.
Contenido:
import serial import sys import time import os COM_PORT = "COM5" # ← Cambiar por tu puerto BAUDRATE = 115200 lista_4 = [ "pacman", "puckman", "galaga", "digdug", "donkeykong", "dkong", "frogger" ] lista_8 = [ "sf2", "sf2ce", "sf2hf", "ssf2", "mk", "mk2", "mk3", "umk3", "kof94", "kof95", "kof96", "kof97", "kof98", "kof99", "samsho", "samsho2" ] def enviar(valor): try: with serial.Serial(COM_PORT, BAUDRATE, timeout=1) as ser: time.sleep(1.2) ser.write(valor.encode()) except: pass if __name__ == "__main__": if len(sys.argv) < 2: sys.exit(0) rom_path = sys.argv[1] rom = os.path.splitext(os.path.basename(rom_path))[0].lower() if rom in lista_4: enviar("4") elif rom in lista_8: enviar("8") else: enviar("0")🛠 4️⃣ Probar manualmente
En:
C:\RetroBat\plugins
Ejecutar:
python restrictor.py pacman
Debe ir a 4.
python restrictor.py sf2
Debe ir a 8.
python restrictor.py metalslug
Debe ir a 0.
Si funciona → integración lista.
🛠 5️⃣ Integración correcta en RetroBat
NO modificar el XML.
Mantener:
<command>"C:\RetroBat\plugins\launch_mame_direct.bat" %ROM%</command>
Editar el archivo:
C:\RetroBat\plugins\launch_mame_direct.bat
Al principio del archivo añadir:
python "C:\RetroBat\plugins\restrictor.py" %1
Debe quedar así:
@echo off python "C:\RetroBat\plugins\restrictor.py" %1 REM --- aquí sigue tu código original --- ...
No borrar nada más.
🎮 Flujo final de funcionamiento
Cuando seleccionas un juego:
1️⃣ RetroBat ejecuta
launch_mame_direct.bat
2️⃣ El.batejecutarestrictor.py
3️⃣ Python envía "4", "8" o "0" por serie
4️⃣ El Arduino mueve el motor
5️⃣ Luego el.batlanza MAME
6️⃣ El juego arranca con el restrictor ya colocadoPantallas siguen funcionando. Nada se rompe. Sistema estable.
🧠 Lógica final aplicada
Tipo de juego Posición Lista 4-way 4 (rombo) Lista lucha 8 (octógono) Resto 0 (cuadrado) -
-
Restrictor automático + Rotary en JOY SANWA I
02/18/2026 at 12:32 • 0 commentsLlevo bastante tiempo sin subir ningún avance. Pero he estado trabajando en el diseño, fabricación y programación de un mecanismo instalado bajo el eje de un joystick SANWA JLX-TP-8YT.
Un restrictor es la pieza (normalmente una placa de plástico en la base del joystick) que limita físicamente el recorrido de la palanca.
Define:-
El ángulo máximo al que puede moverse.
-
Si el movimiento es 4, 8 o más direcciones.
-
La sensación (recorrido corto/largo, esquinas marcadas o suaves).
-
La precisión al activar los microswitches.
![]()
Además he añadido un encoder para que al girar el eje podamos actuar en juegos tipo ikari warriors.
El sistema “rotary” en juegos como Ikari Warriors no es un joystick normal.
Es un joystick doble función:-
🔹 Inclinar la palanca → mueve al personaje (X/Y digital, 8 direcciones).
-
🔹 Girar la palanca sobre su eje vertical → rota el disparo 360°.
El modelo clásico es el SNK LS-30.
La idea de recrear este modelo la vi en un video compartido por un compañero en Telegram (Antonio) en el grupo TOP LIGHT GUNNERS2 https://t.me/TopLightgunners2/1546
El mecanismo que yo he usado es muy parecido al que él implanto. Pero con algunas diferencias importantes:
- Su joystick es un Eurojoy 2 de IL, yo lo hago sobre un SANWA
- El usaba un motor eléctrico y un potenciómetro para saber la posición. Yo uso un motor paso a paso 28BYJ-48 (5 V) con Placa controladora ULN2003.
- El lo hace sobre un eurojoystick y como he comentado antes, yo uso un SANWA
- El mecanizaba el eje por debajo para ampliar y colocar el rotary. Yo he dejado todos los elementos principales intactos. He diseñado y modificado las partes de base y restrictor para imprimirlas en 3D.
- Para bloquear el rotary el usaba un mecanismo que sujetaba en la estructura de su arcade. Yo he usado la base del rotary modificado para crear un menismo similar al SNK LS-30.
Estás son las diferencias más básicas. Pero una cosa quiero dejar clara. Si no es por Antonio, yo no me hubiera planteado esta modificación.
GRACIAS Antonio. Este es su CANAL:
https://youtube.com/@antonio-fw2wl?si=jZANzQrFQBKgaeYj
Lo que más me ha costado diseñar, fue el mecanismo que crea las formas del restrictor. Octognal, libre (cuadrado) y rombo. En todos mis proyectos, nunca había realizado ningún sistemas con ejes y engranajes. Ha sido muy entretenido y he aprendido mucho.
![]()
El diseño hoy en día, sigue en evolución. Mi primera idea era modificar solo la parte del restrictor y conservar
lo máximo los elementos originales del joystick. Pero debido a la longitud de los enganches originales con el restrictor. He tenido que recrear la base también. Estos enganches obstaculizaban el giro de las piezas, si se hubieran quedado como el original, tendría que haber alargado el eje del joystick. Y es una de los elementos que no quería tocar.
Ya habré desmontado y montado el Joystick decenas de veces y puedo asegurar que la calidad del mismo es en un 99% los switches, muelle, eje y actuadores usados.
El actuador también lo he modificado, porque el diámetro del original no está diseñado para la altura en la que ha quedado el mecanismo.
Ahora miso las piezas giran sobre ejes impresos. no hay ningún problema con eso. Pero si me gustaría usar tornillos para cerrar el eje y no tapones como los tengo ahora.
Las pruebas las estoy haciendo con PLA (azul y rojo para ver las partes diferenciadas, Sentido arácnido), pero cuando este todo bien atado lo imprimiere en PETG. Que es un material más duro que el PLA.
![]()
-
-
GIRO DE PANTALLA NEMA17 +608ZZ+ TCM2209
12/10/2025 at 12:12 • 0 commentssistema que tienes: rodamiento 608ZZ + NEMA17 con caja planetaria 5:1 + hub hecho a medida + TMC2209 (UART) + 2 finales de carrera. Incluye los cálculos exactos (grados / pasos / torque), el cableado esencial, comportamiento de software y checklist de puesta en marcha.
1 — Datos físicos básicos (tu caso)
-
Masa de la pantalla: 0,53 kg.
-
Dimensiones aproximadas: 280 × 210 × 55 mm.
-
Asunción (peor caso): eje en el borde → distancia centro de masa al eje ≈ 0,14 m (media del lado largo).
-
Rodamiento elegido: 608ZZ (8 × 22 × 7 mm).
-
Motor comprado: NEMA17 + caja planetaria 5:1 (ver nota de ratio más abajo).
-
Driver: TMC2209 v1.3 en UART.
-
Microcontrolador: Arduino Pro Micro (USB-Serial para RetroBat).
-
Finales de carrera: 2 (HOME = 0°; VERT = 90°).
2 — Cálculo del par gravitatorio (número exacto)
Queremos saber el par que debe sostener el eje si la pantalla está anclada por el borde.
-
Fuerza debida a la gravedad:
-
m = 0,53 kg
-
g = 9,81 m/s²
-
F = m × g = 0,53 × 9,81 =
0,53 × 9,81 → hago el producto paso a paso:
9,81 × 0,5 = 4,905
9,81 × 0,03 = 0,2943
suma = 4,905 + 0,2943 = 5,1993 N -
F = 5,1993 N
-
-
Par = F × r = 5,1993 × 0,14 =
-
5,1993 × 0,1 = 0,51993
-
5,1993 × 0,04 = 0,207972
-
suma = 0,51993 + 0,207972 = 0,727902 N·m
-
→ Par gravitatorio ≈ 0,7279 N·m (≈ 0,73 N·m).
Regla de diseño: usa factor de seguridad ×2 → objetivo de diseño ≈ ≥ 1,5 N·m en salida del reductor.
3 — Par disponible con NEMA17 + planetaria 5:1
-
Supongamos torque nominal sin reductor del NEMA17 ≈ 0,52 N·m (modelo típico 17HS19).
-
Si la ratio nominal real es 5.18:1 (algunos PG5 son 5.18):
-
Par salida ≈ 0,52 × 5,18 =
0,52 × 5 = 2,60
0,52 × 0,18 = 0,0936
suma = 2,60 + 0,0936 = 2,6936 N·m
-
-
Si la ratio fuera exactamente 5:1:
-
Par salida ≈ 0,52 × 5 = 2,6 N·m
-
→ Resultado: con la planetaria tienes ≈ 2,6–2,69 N·m en salida, claramente por encima del objetivo 1,5 N·m. Holgura amplia.
Conclusión: la caja planetaria es sobredimensionada para seguridad y para compensar pérdidas/perfil dinámico — perfecto.
4 — Pasos por 90° (microstepping y ratio)
Necesitas saber cuántos pulsos STEP para mover 0°→90°.
Variables base:
-
Motor: 200 pasos / rev (1,8°/paso).
-
Microstepping elegido: 1/16 (configurado por UART en TMC2209).
-
Gearbox ratio: puede ser 5:1 o 5.18:1 — usa el número que indique tu caja (marca).
Cálculo A — si ratio = 5.18:
-
Pasos motor por rev = 200
-
Microsteps por rev motor = 200 × 16 = 3200
-
Pasos por 1 rev salida = 3200 × 5,18 =
3200 × 5 = 16000
3200 × 0,18 = 576
suma = 16000 + 576 = 16576 pasos por 360° salida -
Pasos por 90° = 16576 / 4 = 4144 pasos
Cálculo B — si ratio = 5.00:
-
200 × 16 = 3200
-
3200 × 5 = 16000 pasos por 360° salida
-
Pasos por 90° = 16000 / 4 = 4000 pasos
Conclusión práctica:
-
Si tu caja es 5.18:1 → usa STEPS_90 = 4144.
-
Si es 5:1 → usa STEPS_90 = 4000.
(Confirma la relación exacta serigrafiada en la caja para elegir el número correcto en firmware.)
5 — Velocidad y temporización (ejemplos)
Si quieres que el giro dure 1,5 s:
-
Para 4144 pasos → pasos/s = 4144 / 1,5 = ≈ 2762,67 pasos/s.
-
Para 4000 pasos → pasos/s = 4000 / 1,5 = ≈ 2666,67 pasos/s.
Con microstepping 1/16 y TMC2209 en StealthChop esto es razonable; empieza por 1.5–2 s y ajusta.
Recomendación: hacer rampa de aceleración (accel) en firmware para evitar pérdidas de pasos; usa AccelStepper (Arduino) o implementa rampas en tu loop.
6 — Hardware y cableado esencial (resumen)
Piezas principales
-
NEMA17 + caja planetaria 5:1 (ya comprado).
-
Rodamiento 608ZZ (ya comprado).
-
Hub/disco con asiento para 608 (impreso o comprado).
-
TMC2209 v1.3 (UART).
-
Arduino Pro Micro (USB-Serial).
-
Fuente 12 V (2 A recomendada).
-
2 finales de carrera (micro-switch) para 0° y 90°.
-
Cables, tornillería, acoplamiento eje → hub.
Wiring básico (propuesto):
-
VMOT (TMC) → +12V
-
GND (TMC) ↔ GND (Fuente) ↔ GND (Pro Micro)
-
VIO (TMC) → VCC (Pro Micro 5 V) ó 3.3V si usas lógica 3.3V (ajustar)
-
STEP (TMC) → pin STEP (Pro Micro)
-
DIR (TMC) → pin DIR (Pro Micro)
-
EN (TMC) → pin EN (Pro Micro) opcional
-
PDN_UART (TMC TX/RX pins) ↔ Pro Micro TX/RX (con resistor 1 kΩ en la línea TX→PDN_UART si recomienda el módulo)
-
ENDSTOP_HOME → pin input pullup (ej. D7)
-
ENDSTOP_90 → pin input pullup (ej. D6)
(Ajusta pines concretos según sketch que cargues.)
7 — Software: comportamiento y lógica clave
Comandos USB (por puerto serie):
-
ROTATE_VoVERTICAL→ mover a 90° -
ROTATE_HoHORIZONTAL→ mover a 0° -
HOME→ hacer homing
Algoritmo recomendado en MCU:
-
Al encender → ejecutar homing: moverse lentamente hacia HOME hasta pulsar switch; hacer back-off y volver despacio para homing desde la misma dirección (compensar backlash). Fijar
pos_actual = 0. -
Al recibir
ROTATE_V:-
Si
pos_actual == 1→ no hacer nada. -
Si
pos_actual == 0→ realizar movimiento aSTEPS_90con rampa y reduce velocidad al final; parar si se activa final 90. Actualizarpos_actual = 1.
-
-
Al recibir
ROTATE_H: análogo hacia 0. -
Si se detecta final de carrera inesperado durante movimiento → detener de inmediato y re-homing si hace falta.
-
Opcional: guardar posición en EEPROM al cambiar (por si reinicio).
Ajustes TMC2209 (por UART):
-
microsteps(16) + interpolate(true) (interpolación a 256)
-
en_spreadCycle(false) para StealthChop quieto si quieres silencio
-
corriente RMS inicial: empieza por ~70–80% del nominal del motor (ver nota Vref/calibración si no usas UART para corriente).
8 — Homing & backlash (práctica)
-
Homing desde misma dirección reduce efecto backlash de la planetaria.
-
Procedimiento: moverse a velocidad baja hasta detectar HOME; retroceder 20–40 micropasos; acercarse de nuevo a baja velocidad hasta contacto. Marcar 0.
-
Para la posición 90°, usar final de carrera para confirmar. No confiar sólo en conteo de pasos (la final añade robustez).
9 — Seguridad y recomendaciones prácticas
-
Rodamiento 608 debe quedar fijo en el soporte (su pista exterior atornillada a la estructura). El eje gira dentro de la pista interior.
-
Usa hub metálico o impreso en PETG/ASA reforzado; si imprimes en PLA refuerza con tornillos y epoxy.
-
Añade amortiguador de goma en toques a finales para evitar impacto.
-
Comprueba temperatura del driver y motor tras 1–2 minutos de uso; si están calientes reduce corriente.
-
Poner un interruptor maestro que corte 12 V para mantenimiento.
-
Si quieres que la pantalla no pueda caer con pérdida de energía, añade freno mecánico o usa worm gear (no imprescindible con planetaria, pero si quieres seguridad absoluta).
10 — Ejemplo rápido de parámetros concretos a poner en firmware
-
MICROSTEP = 16(por UART) -
GEAR_RATIO = 5.18(confirma en tu caja) -
STEPS_90 = int(200 * MICROSTEP * GEAR_RATIO / 4)→ si GEAR=5.18 →STEPS_90 = 4144 -
STEP_DELAYajustable para velocidad: empieza condelayMicroseconds(900)(≈1100 pasos/s por pulsos; ajustar) — mejor usar librería AccelStepper y fijarsetMaxSpeed(3000)ysetAcceleration(2500). -
Curriente TMC2209:
rms_current≈ 0.8 A (ajusta según motor). Con TMCStepper en Arduino:driver.rms_current(800);
11 — Checklist de puesta en marcha (orden práctico)
-
Monta hub + rodamiento 608 en el soporte y fija la pantalla provisionalmente (prueba con cinta).
-
Monta NEMA17+PG5 al chasis; acopla eje con hub; aprieta grub screw.
-
Conecta TMC2209 y Pro Micro (GND común). No pongas la pantalla aún.
-
Ajusta corriente inicial baja en el driver por UART o Vref seguro.
-
Prueba homing sin carga (solo placa trasera). Ajusta dirección de endstop si es necesario.
-
Prueba movimiento 90° a baja velocidad (2–3 s). Observa vibraciones/pérdida de pasos.
-
Monta la pantalla definitivamente con epoxi estructural (Araldite) o con tornillos si la carcasa lo permite. Deja curar.
-
Prueba con la pantalla montada: 10 ciclos 0°↔90°. Verifica temperatura motor/driver.
-
Integra con RetroBat: script llama
rotate.bat ROTATE_Vantes de lanzar, yrotate.bat ROTATE_Hal salir. -
Opcional: registrar eventos y fallback (si final no detectado en X segundos → stop + rehome).
-
-
Esbozo Giro Pantalla
12/10/2025 at 12:06 • 0 comments -
MAME Standalone
11/08/2025 at 16:46 • 0 commentsDOFLinx solo funciona con mame por separado, sin cores de retroarch.
He instalado la última versión de mame:
https://www.insertmorecoins.es/mame-0-282-64-bits-no-nag-including-mess/
Y he descargado todo el romset de esa versión
https://pleasuredome.github.io/pleasuredome/mame/
El romset entero es enorme, no instaléis todo. Yo he partido de una selección que ya tenía.
Para sustituir las roms que tenía por las del romset he usado freefilesync.
https://freefilesync.org/download.php
A la izq ponemos la carpeta del romset y a la derecha donde tenemos las roms C:\Retrobat\roms\mame
Para el set, tenemos que personalizar la sincronización como aparece en la imagen
![]()
He descargado la versión non merged que agrupa todo lo necesario en un solo archivo zip. La pega es que debe ser de la misma versión que el mame instalado.
Pero para retrobat, creo que es mejor.
![]()
Para añadir los flyers he usado la última versión de Bezel Project para windows.
https://github.com/thebezelproject/BezelProject-Windows
Se instala fácilmente. Primero hay que elegir la carpeta de mame.
Para cargar las roms desde mame stand alone, he creado un .bat en la carpeta plugins:
![]()
@echo off REM Lanza directamente MAME con la ROM que le pasa RetroBat cd /d "C:\RetroBat\emulators\mame" mame.exe %1![]()
Luego tenemos que editar es_systems.cfg y sustituir el command de mame por uno nuevo que apunte al .bat creado
![]()
<command>"C:\RetroBat\plugins\launch_mame_direct.bat" %ROM%</command>![]()
SrRubio












