CIRCUITO CON JOYSTICK Y
SERVO
Manejando joysticks con Arduino
Home Circuito Con Joystick Y Servo
OBJETIVOS
o Presentando un pequeño joystick.
o Leyendo el joystick.
o Moviendo el servo mediante el stick.
o Filtrando las lecturas.
MATERIAL REQUERIDO.
Arduino Uno o similar.
Esta sesión acepta cualquier otro modelo de Arduino
Una Protoboard mas cables.
Un Joystick.
Un Servo con sus horns, esas pequeñas piezas de p
QUE ES UN JOYSTICK
Un joystick suele estar formado por dos potenciómetros a 90º que transforman el
movimiento en X e Y del mando en una señal eléctrica proporcional a su posición y que
además suele incluir un botón.
Así pues, suelen tener 5 pines: X, Y, botón y 6V más GND.
En realidad ya usamos todos estos componentes previamente y la única curiosidad del
joystick es que resulta un elemento muy cómodo para posicionar algo, aunque no sea
demasiado preciso.
Vamos a montar un circuito con un servo como en la sesión previa y usaremos uno de los
ejes del joystick para posicionar un servo, y si pulsamos el botón encendemos un LED.
(Ignoraremos el otro eje Y, aunque podríamos usarlo para posicionar un segundo servo).
El pin correspondiente al botón suele venir marcado como SW de Switch.
Aquí tenemos el diagrama eléctrico:
Y para
la protoboard:
EL PROGRAMA DE CONTROL
Vamos con el programa (Prog_17_1):
#include <Servo.h> // Incluir la librería Servo
Servo servo1; // Crear un objeto tipo Servo llamado servo1
int angulo = 0 ;
int Eje_X = A1 ;
int Eje_Y = A2 ;
int boton = 4 , LED = 12 ;
void setup()
{
servo1.attach(6) ; // Conectar servo1 al pin 6
pinMode( boton, INPUT_PULLUP) ;
}
void loop()
{
angulo = map( analogRead(A1), 0, 1024, 0, 180);
servo1.write(angulo);
if ( ! digitalRead(boton))
digitalWrite(LED, HIGH);
else
digitalWrite(LED, LOW);
delay(250) ;
}
La parte que corresponde al servo es exactamente lo mismo que en la sesión 16. Por lo
demás hemos incluido unas definiciones al principio indicando que hemos conectado el eje
X a la entrada analógica A1 y el eje Y a la entrada A2.
El pulsador está conectado al pin digital 4 y el LED al 12, de forma que si queremos
cambiar de pines, por la razón que sea, bastara con actualizar esta lista al principio del
programa.
Insistir en que hemos definido la entrada correspondiente al boto del joystick como
INPUT_PULLUP y no como INPUT, porque de este modo no necesitamos incluir una
resistencia, sino que Arduino conecta un pullup internamente
Por eso leeremos LOW al pulsarlo y entre tanto será HIGH, por ese motivo invertimos la
condición en el if. Encenderemos el botón solo cuando pulsemos.
El servo sigue la posicion del joystick y cuando soltamos vuelve al centro.
Pero hay algo de epiléptico en el movimiento del servo (y más con uno barato como éste
que estoy usando). Recibe muchas interferencias y el movimiento es muy convulso,
porque, aún si el servo tuviera una cierta precisión (lo que es una suposición entre
optimista y muy optimista) los potenciómetros y los convertidores analógicos a digital
siempre tienen un margen de ruido.
Seguro que se nos puede ocurrir una forma de mejorar ese movimiento. Pensadlo, ¿Que
podemos hacer para filtrar ese ruido?
No, en serio. Piénsalo primero antes de seguir.
Vale. En el mundo real, las cosas no son nunca blancas o negras, sino más bien en tonos
grises (o muy frecuentemente chocolates), por eso no es buena idea enviar las lecturas
directamente al control el servo, o de lo que sea que estamos moviendo.
Hay que filtrar un poco la señal. Sin entrar mucho en este tema (sobre el que hay
enciclopedias),vamos a usar una técnica muy básica, pero muy eficaz en muchas
ocasiones y que os conviene conocer.
Vamos a leer el potenciómetro para decidir si subimos o bajamos el valor del Angulo. No
para calcular Angulo directamente.
Como el potenciómetro nos da valores entre 0 y 10000, cuando está centrado o suelto,
leerá sobre 500, poco más o menos (aunque bailará). Así que le vamos a dar un margen
de tolerancia. Solo aumentaremos el Angulo, un valor dado, si la lectura del potenciómetro
sobrepasa el valor de 600 y lo disminuiremos cuando baje de 400.
De este modo pequeñas oscilaciones alrededor del punto medio, no nos afectarán. Es
decir las hemos filtrado. Esto reflejado en el programa, podría ser algo así: Prog_17_2
#include <Servo.h> // Incluir la librería Servo
Servo servo1; // Crear un objeto tipo Servo llamado servo1
int angulo = 90 ; // Empezamos en el centro
int salto = 3 ; // Controla el salto por movimiento
int Eje_X = A1 ;
int Eje_Y = A2 ;
void setup()
{
servo1.attach(6) ; // Conectar servo1 al pin 6
pinMode( boton, INPUT_PULLUP) ;
}
void loop()
{
int p = analogRead(A1);
if ( p < 400 ) // Si la lectura es menor de 400
angulo = angulo - salto ; // disminuimos el angulo
else if (p>600) // Si mayor de 600
angulo = angulo + salto ; // Aumentamos el angulo
servo1.write(angulo); // Y este es el que mueve el servo
delay (50); // Este delay regula la velocidad del
movimiento
}
Creo que comprobareis que el movimiento es más fluido y uniforme, y que prácticamente
elimina las convulsiones del servo. Además usamos este método para dejar clavado al
servo en la posición que nos interesa (Aunque soltemos el mando), algo que del otro modo
sería imposible.