• Pulsadores Arcade Efecto Hall

    SrRubio03/06/2026 at 18:51 0 comments

    Actualmente 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 triggers :

    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);
    }
    
    SensorPro Micro
    Pin 1 (VCC)5V
    Pin 2 (GND)GND
    Pin 3 (VOUT)A4 o A5

    https://vm.tiktok.com/ZNRmveXVV/

  • Array Imagen OLED Restrictor III

    SrRubio03/06/2026 at 18:37 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...
    Read more »

  • Array Imagen OLED Restrictor II

    SrRubio03/06/2026 at 18:36 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,...
    Read more »

  • Array Imagen OLED Restrictor I

    SrRubio03/04/2026 at 10:07 0 comments

    Cuando 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...
    Read more »

  • Restrictor automático + Rotary en JOY SANWA II

    SrRubio03/04/2026 at 08:00 0 comments

    En 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 

    https://www.arcadexpress.com/blog/la-guia-definitiva-para-elegir-el-mejor-joystick-arcade/?srsltid=AfmBOop-ZE0R95xaMq0i1LVbsIfr1rMUldtZAsWNV15VSzzeZIm34yBm

    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 =================...
    Read more »

  • Retrobat + restrictor

    SrRubio03/02/2026 at 15:07 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 .bat de 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 .bat que ya lanza MAME

    Esto 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 .bat ejecuta restrictor.py
    3️⃣ Python envía "4", "8" o "0" por serie
    4️⃣ El Arduino mueve el motor
    5️⃣ Luego el .bat lanza MAME
    6️⃣ El juego arranca con el restrictor ya colocado

    Pantallas siguen funcionando. Nada se rompe. Sistema estable.

    🧠 Lógica final aplicada

    Tipo de juegoPosición
    Lista 4-way4 (rombo)
    Lista lucha8 (octógono)
    Resto0 (cuadrado)

  • Restrictor automático + Rotary en JOY SANWA I

    SrRubio02/18/2026 at 12:32 0 comments

    Llevo 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

    SrRubio12/10/2025 at 12:12 0 comments

    sistema 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.

    1. 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

    2. 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:

    1. Pasos motor por rev = 200

    2. Microsteps por rev motor = 200 × 16 = 3200

    3. Pasos por 1 rev salida = 3200 × 5,18 =
      3200 × 5 = 16000
      3200 × 0,18 = 576
      suma = 16000 + 576 = 16576 pasos por 360° salida

    4. Pasos por 90° = 16576 / 4 = 4144 pasos

    Cálculo B — si ratio = 5.00:

    1. 200 × 16 = 3200

    2. 3200 × 5 = 16000 pasos por 360° salida

    3. 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).

      ...
    Read more »

  • Esbozo Giro Pantalla

    SrRubio12/10/2025 at 12:06 0 comments

  • MAME Standalone

    SrRubio11/08/2025 at 16:46 0 comments

    DOFLinx 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>