Sie sind auf Seite 1von 11

CONTROL DE SERVO CON JOYSTICK

Un joystick suele estar formado por dos potenciómetros a 90º que transforman el movimiento, 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 cinco pines: X, Y, botón y 5V y GND.

Vamos a montar un circuito con un servo como ya hicimos y usaremos uno de los ejes del joystick
para posicionarlo, 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:


#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) ;
}
Hemos definido la entrada correspondiente al boton del joystick como INPUT_PULLUP y no como
INPUT, porque de este modo no necesitamos incluir una resistencia, sino que Arduino realiza un
pullup internamente. Por eso leeremos LOW al pulsarlo y HIGH si no está pulsado, por ese motivo
invertimos la condición en el if. Encenderemos el botón solo cuando pulsemos.
Al ponerlo en funcionamiento veremos que no es un resultado muy bueno ya que tiene un movimiento
convulsivo y además no queda en la posición deseada sino que regresa siempre a la posición inicial.
Ello se debe a que los potenciómetros y los convertidores analógicos a digital siempre tienen un
margen de ruido.
Por eso no es buena idea enviar las lecturas del joystick directamente al control del servo. Hay que
filtrar un poco la señal.
Vamos a leer el potenciómetro y a partir de esa lectura decidir si subimos o bajamos el valor del
Angulo.
Como el potenciómetro nos da valores entre 0 y 1000, cuando está centrado leerá sobre 500, poco
más o menos (aunque bailará). Así que le vamos a dar un margen de tolerancia. Solo cambiaremos el
angulo, un valor dado, si la lectura del potenciómetro sobrepasa el valor de 600 o cuando baje de
400.
De este modo a pequeñas oscilaciones alrededor del punto medio no le haremos caso. Es decir las
hemos filtrado. Veamos el SKETCH mejorado.

#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 cambio mínimo de ángulo que haremos
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 ángulo
}
else if (p>600) { // Si mayor de 600
angulo = angulo + salto ; // Aumentamos el ángulo
}
servo1.write(angulo); // Y este es el que mueve el servo
delay (50); // Este delay regula la velocidad del movimiento
}
Al probarlo veremos 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.

Control de brazo robótico con dos servos


Veamos como podemos controlar la posición de un brazo robótico muy simple que se controla con
dos servos (dos grados de libertad).

El programa será igual que el anterior pero aplicado a dos servos:

#include <Servo.h> // Incluir la librería Servo


Servo servo1; // Crear un objeto tipo Servo llamado servo1
Servo servo2; // Crear un objeto tipo Servo llamado servo2
int anguloX =90 ; // Empezamos en el centro
int anguloY =90 ;
int salto = 3 ; // Controla el salto mínimo de ángulo
void setup()
{
servo1.attach(5) ; // Conectar servo1 al pin 5
servo2.attach(6) ; // Conectar servo2 al pin 6
}
void loop(){
//EJE X
int p = analogRead(A0);
if ( p < 400 ) { // Si la lectura del joystick es menor de 400
anguloX = anguloX - salto ; // disminuimos el angulo
if (anguloX<=30) anguloX=30; //ajustar límite del brazo para no forzarlo
}
else if (p > 600) { // Si mayor de 600 en el joystick
anguloX = anguloX + salto ; // Aumentamos el angulo
if (anguloX>=140) anguloX=140; // ajustar a nuestro brazo para no forzarlo
}
servo1.write(anguloX); // mueve el servo 1
delay (25); // regula la velocidad del movimiento

//EJE Y
int q = analogRead(A1);
if ( q < 400 ){ // Si la lectura es menor de 400
anguloY = anguloY - salto ; // Disminuimos el angulo
if (anguloY<=20) anguloY=20; //ajustar a nuestro brazo para no forzarlo
}else if (q > 600){ // Si mayor de 600
anguloY = anguloY + salto ; // Aumentamos el angulo
if (anguloY>=150) anguloY=150; //ajustar a nuestro brazo para no forzarlo
}
servo2.write(anguloY); // Mueve el servo 2
delay (25); // regula la velocidad del movimiento
}
Arduino y el puerto serie
Prácticamente todas las placas Arduino disponen al menos de una unidad UART. Nuestras placas
Arduino UNO operan a nivel TTL 0V / 5V, por lo que son directamente compatibles con la conexión
USB.
Los puertos serie están físicamente unidos a distintos pines de la placa Arduino. Lógicamente,
mientras usamos los puertos serie no podemos usar como entradas o salidas digitales los pines
asociados con el puerto serie en uso. En Arduino UNO los pines empleados son 0 (RX) y 1 (TX).
No debemos acostumbrarnos a usar el puerto serie si realmente no necesitamos comunicar con el
ordenador. Las librerías empleadas para el uso de puerto serie ocupan un tamaño considerable, y
sólo debemos emplearlas si realmente las necesitamos. Además, supone inhabilitar de forma
innecesaria los pines digitales asociados.

Conexión del Arduino con un ordenador

Para realizar la conexión mediante puerto serie únicamente es necesario conectar nuestra placa
Arduino empleando el mismo puerto que empleamos para programarlo. A continuación abrimos el
IDE Standard de Arduino y hacemos click en el “Monitor Serial” como se indica en la imagen.

El monitor de puerto serie es una pequeña utilidad integrada dentro de IDE Standard que nos permite
enviar y recibir fácilmente información a través del puerto serie. Su uso es muy sencillo, y dispone de
dos zonas, una que muestra los datos recibidos, y otra para enviarlos. Estas zonas se muestran en la
siguiente imagen.

Recibir información desde el Arduino


En este primer código vamos a recibir el valor de un contador enviado desde la placa Arduino. Este
valor se incrementa cada segundo. Podemos observar como se reciben los valores desde del monitor
serial.
int cont=0;
void setup()
{
Serial.begin(9600); //iniciamos el puerto serie
}

void loop()
{
Serial.print("Contador: "); //Imprimimos el valor del contador
Serial.println(cont);
//incrementamos el contador y esperamos un segundo
cont++;
delay(1000);
}

Enviar información al Arduino


En este ejemplo empleamos el puerto serie para encender o apagar el LED integrado en la placa
Arduino. Para ello enviamos un carácter a la placa Arduino, empleando el monitor serial. En caso de
enviar ‘a’ la placa Arduino apaga el LED, y en caso de enviar ‘b’ lo enciende.

int orden;
int led = 13;
void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()
{ //si existe datos disponibles los leemos
if (Serial.available()>0)
{
orden=Serial.read(); //leemos la orden enviada
if(orden=='a') {
digitalWrite(led, LOW);
Serial.println("He apagado el LED");
}
if(orden=='b')
{
digitalWrite(led, HIGH);
Serial.println("He encendido el LED");
}
}
}

Enviar valores numéricos


Por último, en este ejemplo enviamos un número a través del monitor serial, y la placa Arduino hace
parpadear el LED integrado el número de veces indicado. El código es similar al anterior, pero se
hace notar que al enviarse los datos como caracteres ASCII, debemos convertir a entero para saber
el nº de parpadeos que queremos.
Además es importante saber que la lectura del puerto se hace de dígito en dígito, por lo tanto, si el nº
enviado es de varios dígitos tendremos que ir guardando cifra a cifra en una variable tipo String. Una
vez recibidos el número completo realizamos la conversión de código ASCII a Integer.

char digito; //variable que almacena el código ASCII de un dígito único


String numerototal=""; //variable que almacena los códigos ASCII de varios dígitos
int led = 5;
int veces_parpadeo; //variable para el nº de parpadeos que queremos como entero
void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()
{

numerototal=""; //borramos el número al comienzo de cada ciclo para recibir otro


while(Serial.available()> 0) //leemos caracter a caracter hasta recibir todo el número
{
digito =Serial.read(); //leemos una cifra (código ASCII)
numerototal +=digito; //añadiendo dígitos recibidos para formar el nº completo
delay(5); //damos un poco de tiempo para seguir recibiendo
}

veces_parpadeo= numerototal.toInt(); //convertimos los caracteres ASCII a un nº entero

if(0< veces_parpadeo && veces_parpadeo<=20)


{ //límite de parpadeos en 20 por ejemplo
for(int i=0;i<veces_parpadeo;i++)
{
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(500);
}
}
}

Hacer gráficas fácilmente en Arduino IDE con Serial Plotter

El IDE de Arduino permite mostrar en una gráfica en tiempo real los valores recibidos por puerto
serie.
Encontramos el nuevo “Serial Plotter” en el menú “Herramientas”, justo al lado del tradicional “Serial
Monitor”.

Veamos un ejemplo, cargamos el siguiente código en Arduino. Simplemente genera números


aleatorios entre 1 y 3 con dos decimales, y los envía por el puerto serie cada 100 ms.
void setup() {
Serial.begin(9600);
}

void loop() {
float value;
value = random(100,300)/100.0;
Serial.println(value);
delay(100);
}

El resultado que obtendréis es similar al de la siguiente imagen.

Por supuesto, en una aplicación real el valor mostrado sería una variable supervisada como, por
ejemplo, la medición realizada mediante alguno de los sensores que hemos visto. Igualmente,
deberíamos ajustar el tiempo entre envíos a la frecuencia de medición que deseemos.
Los mandos de infrarrojos
Nos parece normal que los equipos electrónicos, televisores respondan a nuestras instrucciones sin
levantarnos del sofá. Estos mandos funcionan por ondas de infrarrojos.
Las ondas electromagnéticas se caracterizan, principalmente, por su frecuencia.
En el espectro electromagnético, a medida que la frecuencia aumenta, nos encontramos con las
ondas de radio y luego con las microondas. Después como veis en este gráfico viene el infrarrojo, el
espectro de luz visible con los colores (Que solo son una forma en que nuestro cerebro percibe las
frecuencias de luz) y luego el ultravioleta.
Más arriba en la escala encontramos los rayos X y por último los rayos gamma o cósmicos.

La capacidad energética de la radiación crece rápidamente con la frecuencia y por eso los rayos X y
los gamma son muy dañinos para los seres vivos.
Una manera de describir los infrarrojos, seria como una luz con un color diferente, que no vemos.
Una curiosidad es que seguramente la cámara de tu teléfono móvil, o tableta es capaz de ver, y
mostrarte, la radiación IR de tus mandos a distancia.
La luz infrarroja es adecuada para hacer mandos a distancia porque:

- Utilizan luz en una frecuencia que no tienen consecuencias en los tejidos vivos.
- Tiene relativamente poco alcance, pero no solemos ver la tele o tener la cadena de música
más allá de 3 o 4 metros.

Así que es práctico, sencillo y barato, aunque tienen también inconvenientes. El principal es que
cualquier cosa con una cierta temperatura, incluidos nosotros, emitimos radiación infrarroja. Es por
eso que las cámaras IR pueden mostrar nítidamente en plena oscuridad a una persona o animal.
Y esto podría interferir con el mando a distancia IR, lo mismo que cosas como la calefacción, el sol y
demás cosas calientes. Así que la solución para evitarlo es modular la señal con una portadora.
La idea básica es mandar un tren de ondas estable (La portadora) y mezclarlo con la información que
queremos enviar (La señal). Este mismo principio se usa con la radio y casi con cualquier señal
radioeléctrica que se envié por el aire.

El emisor es un sencillo transistor que gobiernan un LED infrarrojo muy similar a los LEDs normales
que hemos usado hasta ahora, solo que diseñados para emitir luz en un color que no vemos.
Un pequeño procesador en el mando gobierna, la generación de la señal y la mezcla con la
portadora, para garantizar que nuestra tele no recibe órdenes espurias.

El proceso de mezclar una señal con la portadora se le llama modular.


El inverso, extraer la señal de una onda RF y obtener la señal limpia se llama demodular.
El receptor tiene un poco más de complejidad porque, para mandos a distancia, poco menos que
cada fabricante presento su propia norma.
Al final la industria acabo diseñando unos receptores capaces de recibir y demodular casi cualquier
cosa, y como se venden mucho, valen muy poco.
Un receptor IR típico actual, incluye el receptor, amplificador demodulador y lo que se te ocurra
encapsulado y listo para usarse.

Aplicación: Detector de Movimiento con infrarrojos (PIR)


Con bastante frecuencia necesitamos algún sistema de detectar la presencia de personas o animales
en movimiento en un área dada. Es la base de cualquier sistema de detección de intrusos pero
también se usan mucho en las escaleras comunitarias o aseos públicos para encender la luz en
cuanto detecta el movimiento.
Todos los seres vivos desprenden calor y lo mismo ocurre con los automóviles y cualquier otra
maquinaria, y ese calor se emite en forma de radiación infrarroja que podemos detectar con los
dispositivos adecuados, como los sensores PIR.

Los PIR más frecuentes son sensores de movimiento, y para ello están divididos en dos mitades de
forma que detecten el cambio de radiación IR que reciben uno y otro lado, disparando la alarma
cuando perciben ese cambio.

Habitualmente se adquiere con un pequeño circuito de estabilización y control, que nos permita usarlo
como un sensor digital directo.
Lo normal además es que estos sensores se recubran con pequeñas lentes de plástico que mejoren
su angulo de detección

La imagen muestra el sensor HC-SR501 con la lente puesta y quitada para que veáis el sensor
montado.
Debéis saber que estos sensores PIR pueden disparar directamente una alarma con una señal de
3.3V y son capaces de excitar pequeños relés, de modo que no necesitáis microcontroladores, si lo
único que se necesita es encender una luz o dispara una alarma.

Por eso vamos a hacer, en primer lugar, un pequeño circuito de prueba, de modo que nos sirva para
probar el sensor, y veais que se puede usar directamente.
Vamos a montar un circuito sencillo de detección de movimiento que encienda una LED cuando
perciba algo:

Fijaros que hay 3 pines en el lateral, que usaremos para pinchar el sensor PIR HC-SR501 a nuestra
protoboard, y aquí debajo os pongo el esquema de conexiones:

Como podéis ver enseguida, hay un par de potenciómetros que podemos usar para ajustarlo además
de un jumper para elegir modo. Vamos con ello.

Ajustando el sensor

Empezad por colocar el sensor en la misma posición que la imagen de arriba porque mi modelo no
trae rotulado ningún nombre.
He visto en Internet que recomiendan poner el jumper en la posición H para las primeras pruebas que
arriba está rotulado como Auto Reset, pero en mi caso me ha resultado más fiable sacar el jumper y
dejarlo al aire.
Fijaros que el modelo de la imagen este jumper no existe, pero la mayor parte de los modelos que
encontréis por ahí podréis seleccionar H o L, conectando el jumper entre el pin central y la selección
deseada o bien dejarlo sin conectar.

Cuando colocamos el sensor en la posición L, al detectar algo el LED se encenderá, y al poco se


apagará y hará una cadencia tipo blinking LED dependiendo de lo que detecte. A este modo se le
llama no retriggering y no suele demasiado interesante.
Si lo ponemos en H, cuando detecte movimiento se encenderá y mantendrá así durante un tiempo
(Llamado retrigger mode) y suele ser más conveniente en buena parte de los circuitos prácticos.

Para ajustar la sensibilidad podemos usar uno de los potenciómetros que incluye el sensor (Girando a
favor del reloj aumentamos la sensibilidad).

El segundo potenciómetro ajusta el tiempo que estará activa la señal de detección después de que
esta haya desaparecido. Pero parece que también afecta al retraso con que inicia la alarma, así que
es cuestión de que vayáis jugando para encontrar un punto adecuado para vuestra alarma.

Programa de control con Arduino


Para usar estos sensores con Arduino basta con tomar la señal del sensor y leerla directamente en
los pines digitales de Arduino.

La señal que os entrega el sensor HC-SR501 es digital todo o nada en cuanto detecta movimiento de
una fuente de calor. Se puede leer el sensor con un programa similar a este:

const int led = 6 ;


const int sensor = 7 ;

void setup()
{ pinMode( led , OUTPUT) ;
pinMode (sensor , INPUT);
}

void loop()
{ if (digitalRead( sensor))
digitalWrite( led , HIGH);
else
digitalWrite( led , LOW);
}

Das könnte Ihnen auch gefallen