Joysticks en Arduino

0
2491
Los “joysticks” o palancas de mando, son dispositivos de entrada  que indican la posición o el ángulo al dispositivo que controla. Los mismos pueden ser digitales (solo indican estados de encendido y apagado) o análogos (indican posicion mediante potenciómetros). Hoy aprenderemos a usar Joysticks en Arduino.

 

Antes de empezar recomiendo leer los post acerca de lecturas análogas y la funcion map().

Como se mencionó anteriormente, Arduino ofrece la posibilidad de obtener lecturas de dispositivos análogos dando la posibilidad de conocer el estado o posición en la que se encuentra. Esta característica es aprovechable mediante la implementación de dispositivos de control como son los joysticks análogos.

Los joysticks análogos son dispositivos que, por lo general, constan de dos ejes los cuales controlan dos (2) potenciómetros que indicaran al dispositivo que maneja, la dirección que el usuario desea.

En esta experiencia trataremos de entender como utilizar joysticks en arduino y cómo aprovechar la información que brindan.

Para esta experiencia necesitaremos:

 

Lista de Materiales
Lista de Materiales

Antes de empezar a utilizar nuestro joystick debemos entender ciertos conceptos sobre su funcionamiento. Debemos entender como variaran las mediciones de acuerdo a la configuración que se utilice. Como ejemplo utilizaremos al potenciómetro vinculado al eje Y.

 

  • Caso 1:
Caso 1
Caso 1

Donde:

  • Y+: Pin superior del potenciómetro
  • Y-: Pin inferior del potenciómetro
  • Pin Análogo (A1): Punto de medición conectado a Pin Análogo 1

Los joysticks usan, por lo general, potenciómetros tipo B de 10kΩ , en los cuales el valor del voltaje es directamente proporcional al ángulo de giro con respecto al pin conectado a tierra (GND) , es decir entre mayor sea el ángulo con respecto a el pin conectado a tierra, mayor el voltaje en el punto de medición. Esto se debe a lo siguiente:

Esquema equivalente a Caso 1
Esquema equivalente a Caso 1

Donde:

  • Vin: Voltaje de entrada (5v)
  • Vout: Voltaje de salida en el punto de medición
  • R1: Resistencia de positivo al punto de medición
  • R2: Resistencia del punto de medición a GND

 

En este caso el valor de la resistencia R2 es equivalente al 5% de la resistencia total, por lo tanto la R1 equivale al 95% de la resistividad total, por lo que si tenemos una resistencia de 10 kΩ, R2 equivale a 500 ΩR1 a 9,5 kΩ. Teniendo estos datos en cuenta y utilizando un divisor de voltaje podremos obtener el voltaje en el punto de medición:

Divisor de Voltaje

Por lo que el voltaje en el punto de medición con las condiciones mencionadas equivale a 0.25 V que es igual al 5% de 5V (Vin).

A modo de prueba para relacionarnos con este dispositivo cargaremos el siguiente código a nuestra placa mediante ArduinoIDE:

 

El código leerá los pines A0 y A1 , mapeara los datos de -1 a 1, para reconocer la dirección e imprimirá los datos de x y luego  los datos   y, cada 5 segundos (5000 ms).

El siguiente esquema presenta la configuración a utilizar:

 

Configuración Caso 1
Configuración Caso 1

 

Prestar atención a las mediciones del joystick en estado de reposo ya que no todos los joysticks, en su estado de reposo, se mantienen en un punto medio por motivos de desgaste, fabricación o lo más común, ensamblaje; por lo que necesitaremos de estas medidas para ajustar los rangos de la función map para obtener los resultados deseados.

  •  Caso 2:
Caso 2
Caso 2

En este caso:

  • Pin superior conectado a tierra (GND)
  • Pin inferior conectado a Vin

Con esta configuración, los valores más bajos se esperan en Y+, ya que es en esta dirección que el ángulo de giro con respecto a tierra se hace menor. Aplicaremos los mismos conceptos utilizados en el caso 1, con el uso del siguiente diagrama:

 

Esquema para caso 2
Esquema para caso 2

Donde:

  • Vin: Voltaje de entrada (5V para Arduino)
  • Vout: Voltaje en  el punto de medición
  • R2: Valor resistivo desde Vout a GND
  • R1: Valor resistivo de Vin a Vout

En este caso R1 equivale al 5% de la resistencia total por lo que R2 equivale al 95%, es decir, el valor R1 es de 500 Ω y el valor de R2 es de 9,5 kΩ. Recurriendo nuevamente a la fórmula de divisor de voltaje:

 

Divisor de Voltaje

Para las condiciones dadas Vout equivale a 4,75 V, es decir el 95% de 5V

A modo de prueba cargaremos el siguiente código en nuestra placa mediante ArduinoIDE:

 

El código leerá los pines A0 y A1 , mapeara los datos de -1 a 1, para reconocer la dirección e imprimirá los datos de x y luego  los datos   y, cada 5 segundos (5000 ms).

El siguiente esquema presenta la configuración a utilizar:

Configuración para Caso 2
Configuración para Caso 2

Como se mencionó anteriormente, debemos tener en cuenta que valores se obtienen del joystick en reposo (3 primeras impresiones en mi caso), ya que no todos los joysticks en un estado de reposo están en un punto medio y como se habrán percatado la configuración también afecta a esto. Para corregir esto debemos modificar los valores en map, de la siguiente manera:

  • Si el valor en reposo es menor a 512

mapDonde x es el valor de lectura en reposo

  • Si el valor en reposo es mayor o igual a 512

map2Donde:

map2inMin

Ya tocado estos puntos pasaremos a la utilización de los datos que obtenemos de los joysticks. En esta ocasión lo utilizaremos para controlar una matriz casera de LED de 3×3.

Una matriz de LED, es una configuración donde los ánodos y cátodos de todos los LEDs dentro del arreglo están conectados entre si , es decir los ánodos están conectados unos a otros en filas o columnas y los cátodos en filas o columnas. En nuestro caso armaremos una matriz de LED de 3×3 siguiendo el siguiente esquema:

diagramamatrizy lo conectaremos a nuestra placa de la siguiente manera:

joystick_bb
Configuracion con Arduino

y cargaremos el siguiente código en nuestra placa:

Si se ha configurado todo correctamente deberíamos obtener un resultado como el mostrado a continuación:

joystickmatriz

La pregunta aquí es, ¿Cómo esto funciona?

Para responder a esto debemos recordar que es un LED. Las siglas LED, significan Light-Emitting Diode  (Diodo emisor de luz), y como todo diodo un LED solo permite el paso de corriente de ánodo a cátodo y solo bajo esta condición emitirán luz, ya que estarán en polarización directa permitiendo a los electrones recombinarse en los huecos del diodo y emitir energía en forma de fotones.

Podremos resumir el comportamiento de un LED con la siguiente tabla:

ledbehavior

Ahora traduciendo esto a nuestra matriz, significaría que para encender un LED en la posición (x,y), debemos enviar una señal ALTA (HIGH o 1) en la fila “y” y una señal BAJA (LOW o 0) en la columna “x”, ya que un pin configurado como salida (OUTPUT) con una señal LOW permite la entrada de corriente actuando como tierra . Esto permite que la corriente viaje del ánodo del led al cátodo del led.

Asumiendo que en nuestro arreglo, el LED de la esquina superior izquierda tiene la posición (0,0) y el LED de la esquina inferior derecha tiene la posición (2,2), podríamos resumir el comportamiento de la matriz en la siguiente tabla:

Comportamiento de la Matriz
Comportamiento de la Matriz

La siguiente animación muestra lo explicado, encendiendo los LED en diagonal, posiciones (0,0), (1,1), (2,2). Dale clic a la imagen para ver la animación.

Matriz en acción
Matriz en acción

En este caso se aplicó una técnica para ahorrar espacio, si bien no es necesaria en este proyecto quizás conocerla sea de ayuda en futuros proyectos. Esta técnica es el uso de un número en sistema decimal  que representa una secuencia binaria(0 y 1), que pueden representar los estados en que deben estar una serie de pines. Para entender como hacer esta conversión recomiendo leer el artículo: BitMath del Aruduino playground donde se explica algunos pasos importantes de las operaciones con bits.

Si observamos a la función Mcontrol(x,y), la cual maneja el control de la matriz se podrá observar que utiliza dos arrays del tipo byte llamadas statec y state

Estas dos matrices contienen los estados correspondientes a cada posición (3 posiciones) tanto para fila (statef), como para columnas (statec), mediante un número decimal que representa la serie de 0 y 1 para cada posición. Para obtener ese número podremos usar la siguiente técnica. Usaremos como ejemplo la posición (0,0) cuyos valores son statef[0] y statec[0].

Una variable del tipo byte van de 0 a 255, es decir una secuencia ocho (8) ceros(0) o unos(1). Para la fila 1, según la tabla la secuencia a seguir es {1, 0,0}, si metemos esta secuencia para trabajarla como bits la ubicaremos en una tabla con 8 posiciones de derecha a izquierda, es decir el último valor de la secuencia a la primera casilla de derecha a izquierda y rellenando los espacios restante con ceros:

 

f1

El valor de esta secuencia en decimal equivale a la suma del producto del número (0 o 1) por la potencia de dos (2) correspondiente a la posición en que se encuentre, es decir:

bittodeci

Ahora analicemos como esto es aplicado  a la función mcontrol.

 La función utiliza las mediciones del joystick correspondiente al eje x y eje y, y los mapea de 2 a 0, para ser utilizados como índices en las matrices de estado. Además se puede observar una función llamada bitRead(), de la cual podemos leer más acerca de ella aquí. Esta función tiene la siguiente sintaxis:

biteread

Donde:

  • X: el número de donde leer
  • n: la posición a leer (0 para el valor más a la derecha)

Esta función devuelve el número (0 o 1) de la posición especificada. Como el valor más a la derecha es el último y nuestra matriz es de 3 x 3, solo utilizaremos 3 posiciones por lo que la función empieza a leer desde la casilla 2 hasta 0 y asignándolo a la fila y columna que corresponda, creando la secuencia necesaria para obtener un movimiento correspondiente al movimiento del joystick

Joysticks en ArduinoEsto ha sido todo por hoy, esperemos que toda la información brindada sea de gran utilidad. Por favor cualquier duda, comentario, sugerencia o corrección no duden en expresarla.

Saludos.