El proyecto
Tengo un joystick que compré allá por el año 1997 o 1998. Un precioso Thrustmaster Top Gun. Para la época actual ya es una reliquia. Y, con los simuladores de aviones actuales, es poco práctico. ¿Por qué? Pues porque no tiene throttle, solo tiene 4 botones y, lo más importante, no es USB.
Pero como me gusta mucho, me propuse actualizarlo. La idea inicial era, simplemente, convertirlo a USB, utilizando un Arduino. Pero ya que estaba, y pensando que me sobrarían pines del Arduino, decidí ponerle algún botón más y un throttle. Este es el sujeto.
Esto es un «How do they do it» del proceso de transformación del joystick.
Hay varias cuestiones a tener en cuenta.
Espacio
Si le voy a poner un Arduino, tiene que ser uno que quepa dentro del joystick, así que tendrá que ser pequeño.
Lo primero es abrir el joystick y ver que tiene dentro, y cuanto espacio libre queda para el arduino, botones y demás. Así que lo abro.
Por dentro lo que tiene son dos potenciómetros para los ejes X e Y, y el cableado que sube hacia los botones. Además hay dos «pesos» (no están en la imagen), que simplemente son dos bloques de metal para añadir peso al conjunto y que sea más estable al ponerlo en una mesa.
Hay un bloque central con los potenciómetros eso le quita bastante espacio al interior, pero con el espacio restante parece que hay suficiente hueco, aunque tendré que utilizar el Arduino más pequeño que haya. Así que he pensado que es buen momento para probar un Promicro.
Conexiones
Este joystick se conectaba al antiguo puerto de juegos que tenían las tarjetas de sonido.
Este puerto permitía 4 ejes y 4 botones. El joystick tiene dos ejes (X e Y), 4 botones y una «seta». La seta lleva 4 pequeños botones para funcionar, pero, eso suman 8 botones, entonces, ¿cómo hace el joystick para poder detectar las pulsaciones? Pues con un método muy curioso. Resulta que los 4 botones de la seta están conectados entre ellos y a través de 4 resistencias, formando un circuito al que solo llegan dos cables.
Estos cables iban a una entrada de un «eje» del puerto, como si fuese un eje más aparte de los ejes X e Y. Estas entradas lo que detectan son los cambios de resistencia que hay (como en los ejes X e Y). Pues bien, al aplicar tensión a ese «circuito» y pulsar los botones, la corriente pasaba a través de una u otra resistencia, devolviendo un valor de resistencia distinto dependiendo del botón que se pulsara.
Lo importante de esto es que, para cada botón, había un valor definido de resistencia, que siempre era el mismo, y que era distinto para cada botón. Por lo tanto, leyendo ese valor, se podía saber qué botón se había pulsado. Además, el diseño de la seta impide que se puedan pulsar dos botones al mismo tiempo, así que no hay problema de que se genere algún valor de resistencia que no esté contemplado.
Sabiendo esto, yo voy a utilizar el mismo método para detectar las pulsaciones de la seta. Es decir, voy a conectar esto a un pin analógico y, leyendo ese pin, en función de la resistencia presentada, sabré qué botón se ha pulsado. Lo explicaré mejor más adelante.
Por lo tanto este proyecto tiene dos partes. Por un lado, añadir más botones y un throttle, y, por otro, convertirlo a USB.
Diseño exterior
Pasé varios días pensando en cuantos botones le podía añadir al joystick, dónde ponerlos, de qué tipo serían, si podría añadir algún switch (interruptor) en vez de solo botones…..Consejo importante: cuando te pones con estas cosas, algo muy importante es vencer la tentación de querer poner todo; botones, switches, palancas, ruedas…. Hay que ir a poner algo que funcione para lo que queremos, que sea simple y que quede bien con el resto del joystick. Nada de sobrecargar el joystick con demasiados elementos.
Lo primero que hice fue desmontar el joystick para ver como era por dentro y cuanto espacio tenía. Una vez desmontado, hice unos planos para poder estudiarlo mejor.
Encontré unos botones que combinan muy bien en cuanto a forma y color, y que tienen una pulsación agradable. Hice muchas pruebas y muchos planos para decidir donde y como ponerlos. Viendo el hueco que había para ponerlos, me decidí a poner 4 en la parte delantera. No es la mejor posición para acceder a ellos, pero es el mejor hueco que hay. Bueno, en realidad podía utilizar la parte de atrás, que hay más hueco, pero entonces tendría que taladrar la pegatina de adorno que tiene el joystick, y no quería eso, porque queda muy bien. Por eso me decidí a ponerlos delante.
En la parte de atrás pondré el Promicro. Lo que más me ha costado ha sido decidir el throttle. He barajado muchas opciones, y al final me he decidido a utilizar un potenciómetro rotatorio, que lo voy a situar en un lateral en la parte de atrás. Y, para utilizarlo, voy a diseñar una pieza en 3d que pueda engancharla en el potenciómetro y que haga de mando. Una especie de disco grande.
He hecho varios planos para asegurarme de que cabe todo bien y he probado también con el joystick desmontado para ver que todo parecía que cabría bien.
Otro consejo: haced planos, tomad medidas y haced pruebas con el joystick desmontado todas las veces que haga falta hasta que estéis seguros; una vez que taladráis un agujero, ya no hay vuelta atrás. Mide dos veces, taladra una.
Diseño del cableado
¿Cómo es el cableado existente? ¿Se puede reutilizar algo?
En el joystick hay 4 botones (de momento no cuento la seta) y dos potenciómetros para los ejes. Evidentemente esos hay que reutilizarlos, ya que este proyecto se trata precisamente de darle nueva vida al joystick. Los botones tienen un cable común que pasa por una patilla de cada uno de ellos (ground). Y luego, cada uno tiene un cable que va a otra patilla. Es justo lo que necesitamos para conectarlos a un Arduino, así que estos cables se quedan como están.
Los potenciómetros del joystick solo tienen dos cables, uno de entrada y otro de salida. El antiguo puerto de comunicaciones era capaz de leer la resistencia que ofrecía el
potenciómetro en la salida. Sin embargo, Arduino necesita un cable más por el que lee el voltaje que cae al variar la resistencia y convierte ese voltaje a un valor numérico gracias a un ADC (Conversor Analógico Digital). Así que hay que añadir un cable más a cada potenciómetro, soldándolo a la tercera patilla que tienen. El ADC convertirá el valor del voltaje (entre 0 y 5v) a un valor numérico entre 0 y 1023. De esta forma, luego habrá que conectar los tres cables de cada potenciómetro, uno al positivo de 5v, otro a tierra y otro a una patilla de lectura analógica del Arduino. Tal y como se ve en la siguiente imagen. Cable rojo a 5v, cable negro a tierra y cable amarillo a una entrada analógica (A0 en este caso).
La seta. Ya hemos hablado de como funcionaba la seta. Como ya he comentado, la seta se conectaba a una patilla del puerto de comunicaciones que era para leer uno de los 4 posibles ejes que permitía dicho puerto. Así que solo había dos cables, el de entrada y el de salida. Voy a reutilizar este circuito, pero voy a tener que añadirle un cable más, claro, como si fuese otro potenciómetro. De esta forma, para leer el botón pulsado lo que haremos será conectar uno de los cables a la entrada de 5v. Luego, a la salida, añadiremos una resistencia y un cable (antes de la resistencia). Ese nuevo cable irá a una patilla analógica del Arduino. Y el cable de después de la resistencia, a tierra.
Además de esto, tenemos que cablear los nuevos 4 botones. Estos llevarán un cableado como los 4 que ya existen, es decir, un cable común de tierra (ground) y un cable para cada botón que irá a una patilla de Arduino. Todas estas patillas hay que ponerlas con la resistencia interna (INPUT_PULLUP).
También hay que añadir el potenciómetro nuevo, el del throttle, y cablearlo igual que los otros: una patilla a 5v, otra a tierra y la tercera al Arduino para medir el valor.
Una vez que está todo claro, ya solo hay que ponerse a trabajar de verdad. Hay que taladrar los agujeros de los botones, colocarlos en su sitio, y empezar a soldar los cables. Lo que he ido haciendo es soldar los cables que van al Promicro a unos cables con terminaciones Dupont, así es más fácil conectarlos y desconectarlos. Los cables de los botones del mando ya estaban soldados a dichos botones, así que ahí no he hecho nada, pero para los nuevos botones he hecho un cable con conexiones «de espada» (seguro que tienen otro nombre pero no me lo sé) que hacen que sea muy fácil conectarlos y desconectarlos de los botones. Me compré una crimpadora para hacerlos. Creo que le sacaré partido.
No tengo muchas fotos del proceso, pero aquí van las pocas que hay.
He reaprovechado el enganche de goma que une el cable a la caja del joystick. Así la fijación del cable queda mejor y más segura, ya que se evitan rozamientos contra el plástico de la caja.
Como decía más arriba, he soldado cables del joystick a cables con terminaciones Dupont para conectarlos mejor al Promicro. Los switches que se ven en la foto no tienen nada que ver con el Joystick. Ya que me ponía con el soldador, quería quitarles los cables.
Nótese el tamaño del Promicro. También se puede apreciar en las imágenes que aun no había hecho los agujeros para los nuevos botones.
Programación
La programación del Promicro en este proyecto es bastante sencilla. Dejaré el código en Github, pero básicamente son tres cosas. Para los botones:
int btnState_1 = 0;
int lastBtnState_1 = 0;
// Botón 1
btnState_1 = digitalRead(PIN_BTN_1);
// Se comprueba si ha cambiado de estado con respecto al que tenía
if (btnState_1 != lastBtnState_1){
if(btnState_1 == LOW){ // interruptor cerrado
Joystick.pressButton(BTN_1);
}else{
Joystick.releaseButton(BTN_1);
}
lastBtnState_1=btnState_1;
}
Es decir, se comprueba si el botón está pulsado y si ha cambiado su estado respecto al ciclo anterior. En ese caso, se envía el evento «pressButton(botón)» del botón pulsado. Cuando se suelta el botón se envía el evento «releaseButton(botón)». Y, en ambos casos, se guarda el nuevo estado. Así solo se enviará alguno de los dos eventos si ha cambiado el estado. Si no, se estarían enviando continuamente.
Para los ejes es más simple todavía; se lee el valor del pin y se llama al evento «setXAxis(eje)». Hay un evento para cada eje.
int eje_x = analogRead(PIN_EJE_X);
Joystick.setXAxis(eje_x);
Y, para la seta, se lee el valor del pin y, en función del valor que nos devuelva, no hacemos nada (seta en el centro) o enviamos el evento «setHatSwitch(0, ángulo)».
valorSeta = analogRead(PIN_SETA);
if (valorSeta > 900){
// No hay botones pulsados
Joystick.setHatSwitch(0, -1);
} else if ((valorSeta < 890) && (valorSeta > 865)){
// Botón izquierdo cruceta
Joystick.setHatSwitch(0, 270);
} else if ((valorSeta < 840) && (valorSeta > 815)){
// Botón abajo cruceta
Joystick.setHatSwitch(0, 180);
}else if ((valorSeta < 698) && (valorSeta > 685)){
// Botón derecho cruceta
Joystick.setHatSwitch(0, 90);
}else if (valorSeta < 25){
// Botón arriba cruceta
Joystick.setHatSwitch(0, 0);
}
Resultado
Y, finalmente, aquí está el resultado. Para mi gusto ha quedado bastante aparente.
En estas imágenes ya se ve la rueda del throttle y el cable USB. No he puesto video ni imágenes, pero funciona muy bien. De momento solo lo he probado con mi querido IL-2 Sturmovik 1946. Hay que programar los botones en el juego para que hagan lo que queramos, claro, pero funciona sin problema.
Si has llegado leyendo hasta aquí, ¡muchas gracias!. Espero que hayas disfrutado y que me sigas en más proyectos como este.