CONTROL Y ROBOTICA

TEMA: CONTROL Y ROBOTICA

robot-gameEl control de sistemas mediante ordenadores o circuitos electrónicos es hoy en día responsable de casi todas las tareas que nos rodean, desde manejar la temperatura de nuestro aire acondicionado, pasando por abrir o cerrar las puertas de un ascensor hasta controlar un brazo robótico a través de internet para operar a un paciente en un hospital lejano.
Es este capítulo analizaremos sensores y varios proyectos reales para usarlos.




EL SENSOR DE INFRARROJOS

PRÁCTICA RÁPIDA: "DETERCTOR DE OBJETOS POR INFRARROJOS"
Realizar un montaje que utilice el sensor digital de infrarrojos modelo Keyes IR. Cuando detecte un objeto que encienda el LED 13 de Arduino. También es necesario que muestre el valor binario leído del sensor por el monitor serie.
Como se puede observar en la figura el emisor y el receptor van montados en la misma placa. El emisor transmite una frecuencia de infrarrojo y cuando encuentra un objeto la señal se refleja y es captada por el receptor. La distancia de detección es de 2 a 40 cm (bastante menor que el rango del sensor de ultrasonidos). Tiene un jumper que deshabilita el sensor si se quita y dos potenciómetros. Con uno de ellos (el 202) regulamos la distancia a la que se detecta el objeto.
La radiación infrarroja no se ve directamente, pero si enfocamos mediante la cámara del móvil como si fuéramos a hacer una foto veremos por el visor del móvil una luz violeta.

ESQUEMA:

Pin Sensor IRPin Arduino
Vcc5V
GNDGND
OutD3
ENSin conectar

esquemaIR

PROGRAMA:

#define LED 13 
#define BUTTONPIN 3
boolean val;

void setup (){
  pinMode (LED, OUTPUT);
  pinMode (BUTTONPIN, INPUT);
  Serial.begin(9600);
}
void loop (){
val = digitalRead(BUTTONPIN);// digital interface will be assigned a value of 3 to read val
if (val == HIGH) digitalWrite (LED, HIGH);
else digitalWrite(LED, LOW);
Serial.println(val);
}

Actividad

Comprueba que la señal de infrarrojos NO rebota sobre una superficie negra. Prueba con cinta aislante negra. Este sería el principio de funcionamiento de un robot siguelíneas. ¿Cómo se podría diseñar con sensores IR para seguir una línea negra? Razona la lógica de funcionamiento.
SENSOR DE INFRARROJO CNY-70


Sensor
Uno de los sensores más utilizados en robótica, o infinidad de aplicaciones industriales es el CNY-70.
Su nombre técnico es optoacoplador. Se basa en la acción conjunta de un diodo que emite una luz infrarroja (que no vemos) y un fototransistor que detecta el rebote de esta cuando incide sobre algún objeto. 
Inicialmente es un sensor analógico y nos da un valor de voltaje proporcional a la luz rebotada, pero podemos utilizarlo también de manera digital utilizando un disparador (Schmitt).





La utilización de un sensor de infrarrojos puede ser de gran utilidad en proyectos en los que haya que hacer distinción entre superficies de color blanco y negro. Como ejemplos podemos mencionar de un encoder, un robot sigue líneas o un selector de bolas blancas-negras entre otras muchas aplicaciones. 
El sensor CNY 70 que ves en la figura, permite distinguir dos umbrales de color bien definidos como son el blanco y negro mediante una pareja de diodos, un emisor de radiación infrarroja o otro receptor.
El sensor se sitúa a unos milímetros de la superficie a detectar, mientras tanto el diodo interno emite una señal de infrarrojos que absorberá la superficie en el caso de que sea negra o bien rebotará en el caso en el que la superficie sea blanca. Si la señal de infrarrojos rebota, activará la base del fototransistor en entrará en conducción, es decir que el terminal emisor y colector del transistor se conectarán eléctricamente.


Mediante un sencillo montaje indicado en la figura inferior, viendo las lentes desde arriba, con alimentación a 5V y dos resistencias podemos enviar un nivel alto (+5V) o un nivel bajo (GND) a uno de los pines digitales de Arduino configurado como pin de entrada, y poder realizar la lectura. Mediante un programa como el que indica a continuación podemos leer dichos valores y poder concluir si la superficie es blanca o negra dependiendo si lee un nivel bajo (LOW) o alto (HIGH) respectivamente. En este ejemplo se encenderá un led verde en el caso de que lea un '0' o un led amarillo en el caso de que lea un '1'. Esta parte del programa se puede cambiar para adaptarla a las necesidades del proyecto.
conexiones CNY 70

PROGRAMA:
int Valor = 0;
int Sensor = 8;
int LedVerde = 13;
int LedAmarillo = 12;
 
void setup(){
 Serial.begin(9600);
 pinMode(Sensor, INPUT);
 pinMode(LedVerde, OUTPUT);
 pinMode(LedAmarillo, OUTPUT);
}
 
void loop(){
 Valor = digitalRead(Sensor);
 Serial.println(Valor);
 delay(100);
 if (Valor == 0)
 {
  digitalWrite(LedVerde, HIGH);
  digitalWrite(LedAmarillo, LOW);
 }
 else
 {
  digitalWrite(LedVerde, LOW);
  digitalWrite(LedAmarillo, HIGH);
 }
}

Pregunta Verdadero-Falso

La radiación infrarroja rebota en cualquier objeto excepto en los de color negro que la absorben.
 

El sensor CNY 70 lo podemos utilizar tanto con lecturas digitales como analógicas.
 

El sensor de IR lo podemos utilizar en un robot siguelineas, trazando con cinta aislante negra la ruta a seguir por el robot. 
 

La lectura que toma Arduino del sensor CNY 70 nos da directamente los centímetros a los que está alejado el objeto detectado.
 


SENSOR DE INFRARROJO SHARP GP2D12
El sensor IR utilizado tiene un emisor y receptor de infrarrojos. El receptor, dependiendo de la distancia ofrece una salida de voltaje inversa (a mayor voltaje, menor distancia).
Para calcular la distancia en centímetros a un objeto, podemos usar un ajuste de mínimos cuadrados. La relación entre distancia - voltaje no es lineal, sino que se comporta como una hipérbola según se observa en la figura:
curva-IR
Se definen 3 zonas de medida, según la distancia:  curva2-IR
  • A partir de 10cm.
  • Entre 10 y 35 cm.
  • De 35 hasta fuera de rango.
Así tenemos 3 funciones diferentes según la zona de medida : alto, medio bajo, para ajustar la medida en centímetros.




En nuestro caso vamos a simplificar la ecuación de modo que podemos ajustarla mediante la fórmula:
cm = (6787 / (valor - 3)) - 4
Nos convierte el voltaje de entrada (que a su vez en convertido por Arduino a un valor entre 0-1024) a centímetros. En la variable del tipo entero, cm almacenaremos la medida en centímetros, mientras valor será el dato que recogemos del sensor Sharp.
La conexión de este dispositivo es realmente sencilla, consta de 3 cables, 2 para la alimentación (+5V, GND) y el otro para transmitir los datos.
CONEXIONES:
Vamos a construir un sistema que calcule la distancia de un objeto y nos avise mediante un LED cuando esté a menos de 20 cm.
A continuación observa cómo lo puedes conectar mediante una protoboard o usando EduBásica:
conexionesconexion-edu

La conexión de datos la podemos hacer en cualquiera de los pin analógicos del A2-A5. En nuestro ejemplo conectamos el sensor al pin A2. El led de señalización que usaremos será el verde (salida digital D3).
El programa se basa, por un lado en ir continuamente haciendo medidas de distancia desde el sensor Sharp, después hay que hacer la conversión que antes hemos visto para pasar la entrada analógica a centímetros, y por último hacemos la comparación con el valor que se nos ha pedido (20 cm) para encender o no el led del pin 5.
int alto = 515, bajo = 90; //valores de tensión del sharp
int cm = 0;                //Para almacenar el valor obtenido en cm valor=0 
int sharp = A2;            //Entrada analógica del sensor.
int led = 3;
int valor;

void setup(){

  pinMode(led, OUTPUT);
  Serial.begin(9600);

}

void loop(){

  valor = analogRead(sharp);
  if (valor > alto || valor < bajo) Serial.println("OUT"); //fuera de rango
  else{    
    cm = (6787 / (valor - 3)) - 4;      //calculo
    Serial.println(cm); //cm detectados por el monitor
    //Si el objeto esta a menos de 20cm
    if(cm < 20) digitalWrite(led,HIGH);
    delay(600);
    digitalWrite(led,LOW);
  }
}


Pregunta Verdadero-Falso

Contesta a las siguientes preguntas referidas al programa anterior.

El pin analógico 2 se asigna a la variable sharp.
 

La instrucción if(cm < 20) digitalWrite(led,HIGH); enciende un led si la distancia es MAYOR que 20 cm.
 

La variable valor almacena un valor '1' o '0' ya que recoge el valor leído en el pin digital 2.
 


SENSOR DE ULTRASONIDO
PRACTICA RÁPIDA: "DETECTOR DE OBJETOS POR ULTRASONIDOS"
HC-SR04
Esta práctica consiste en montar un sistema con Arduino capaz de medir la distancia (cm) a la que se encuentra un objeto y mostrarla por el monitor serie. Para ello usaremos el sensor de ultrasonidos HC-SR04. Este sensor dispone de un emisor y receptor de ondas de ultrasonidos. El emisor "dispara" una onda ultrasónica que se propaga a 340 m/s y se inicia un temporizador. Si encuentra un objeto, la onda rebota. Esta onda reflejada o eco es capturada por el módulo receptor y el temporizador interno se para. De esta manera midiendo el tiempo que la onda tarda en ir y reflejarse, junto con la velocidad de propagación, el sensor calcula la distancia a la que se encuetra el objeto.
El sensor dispone de 4 pines: Alimentación (+5V), Tierra (GND), Trigger y Echo. El pin Trigger se encarga de "disparar" la señal de ultrasonidos por el transmisor. Se hace enviado un nivel alto desde Arduino al pin digital donde esté conectado el pin Trigger. El pin Echo se encarga de enviar a Arduino un pulso (nivel alto) con duración proporcional a la distancia a la que se encuentra el objeto detectado, más exactamente distancia (cm) = microsegundos del pulso / 29. Mediante la instrucción PulseIn de Arduino podemos leer la duración de ese pulso.
El sensor tiene un rango de 2 cm a 400 cm. Para más información consultar la hoja de especificaciones del sensor:http://www.micropik.com/PDF/HCSR04.pdf

ESQUEMA:

Pin Sensor USPin Arduino
Vcc5V
TriggerD8
EchoD9
GNDGND

Ultrasonic

PROGRAMA 1:

int trigPin = 8;
int echoPin = 9;
long duration; //tiempo de ida/vuelta
int cm = 0; //Para almacenar el valor obtenido en cm valor=0
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}

void loop()
{
//ponemos al trigger a low para activarlo después
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
//Activar el módulo con un pulso de 10microsec.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//Esperamos la llegada de un pulso HIGH
duration = pulseIn(echoPin, HIGH); // valor del pulso alto en microsegundos
//tiempo de ida y vuelta, dividimos por 2
duration=duration/2;
//La velocidad del sonido es de 340 m/s
//El pin echo entrega un pulso alto 
//de una duración de 29 microsegundos 
//por cada centímetro de distancia
//a la que esté el objeto.
cm = duration/ 29;
Serial.print("Distancia:");
Serial.println(cm);
delay(100); // Nos aseguramos de que el siguiente trigger
// y el echo actual no se mezclen (recomiendan 50 ms). 
}

OTRO MÉTODO USANDO UNA LIBRERÍA EXTERNA:
En este caso tenemos que descargar previamente el archivo comprimido (.zip) de la librería NewPing e instalarla desde la opción del IDE de Arduino Programa -> Incluir librería -> Add Library y seleccionar NewPing.zip (normalmente estará descargado en la carpeta de Descargas).

#include <NewPing.h>
 
#define TRIGGER_PIN  8
#define ECHO_PIN     9
#define MAX_DISTANCE 200
   
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
     
void setup() {
 Serial.begin(9600);
}
     
void loop() {
  delay(50);
  int uS = sonar.ping();
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM);
  Serial.println("cm");
}



Actividad

Diseña un circuito y realiza un programa que haga sonar un zumbador cuando un objeto se encuentre a menos de 5 cm del sensor.

EL SENSOR DE ULTRASONIDOS.
portada-us

Este tipo de sensores también nos permite conocer la distancia a un objeto. Es más preciso que el de infrarrojos visto en la sección anterior y su rango de funcionamiento también es mayor. Funciona desde los 2cm hasta los 3 metros. 
US
El sensor tiene 2 partes como puedes ver en la figura. Una se encarga de enviar un sonido (a una frecuencia alta que no podemos escuchar), y la otra parte detecta cuando ese sonido vuelve.
Este sensor es muy útil en robots móviles para diversas acciones como no chocar o mantenerse a cierta distancia de una pared.
Podemos usar un sensor de ultrasonidos para obtener la distancia a un objeto. Este sensor se basa en el envío de una señal acústica y la recepción del eco de dicha señal. Lo que haremos después, al igual que hace un radar , un aparato de ecografías o un murciélago es calcular la distancia en función del tiempo que ha tardado el rebotar el sonido y la velocidad del sonido. Podemos encontrar las especificaciones en la página del fabricante. Uno de los modelos más comunes es el HC-SR04:
http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
El sensor que usamos en estos ejemplos tiene 4 pines que corresponden (de izquierda a derecha):
  • GND , Vcc (a +5V)
  • Trig: es el que emite el ultrasonido
  • Echo: Es el que recibe el rebote
conexiones(Algunos modelos solo tienen 3 pines -HCSR05- indicándonos por el tercer pin ya directamente un valor proporcional con la distancia.)

El funcionamiento se basa en la función pulseIn(pin,valor). Ella se encargará de medir el tiempo que tarda el pulso de sonido en ir-rebotar-volver. En nuestro caso enviaremos el pulso con un simple digitalWrite sobre el pin trigger y le diremos a pulseIn que vigile el pin echo hasta que llegue el pulso. La función nos devolverá el tiempo en microsegundos.
int trigPin = 8;
int echoPin = 9;
long duration; //tiempo de ida/vuelta
int cm=0; //Para almacenar el valor obtenido en cm valor=0

void setup() {

  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

}

void loop()

{

//ponemos al trigger a low para activarlo después 

   digitalWrite(trigPin, LOW);
   delayMicroseconds(2);

//Activar el módulo con un pulso de 10microsec.

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

//Esperamos la llegada de un pulso HIGH

duration = pulseIn(echoPin, HIGH);

 //tiempo de ida y vuelta, dividimos por 2

duration=duration/2;

//La velocidad del sonido es de 340 m/s
//es decir, 29 microsegundos por centímetro

cm = duration/ 29;
Serial.print("Distancia:");
Serial.println(cm);
delay(100);

}

Pregunta Verdadero-Falso

El sensor de ultrasonidos únicamente permite detectar si hay un objeto delante o no, pero no es capaz de medir la distancia a la que se encuentra. 
 

El sensor de US emite una onda de ultrasonidos y la recibe cuando rebota en un objeto. De esta manera, midiendo el tiempo de ida y vuelta, y conociendo la velocidad de propagación de la onda, puede calcular la distancia a la que se encuentra un objeto.
 

Cuando utiliza el sensor de US, la placa Arduino queda inhabilitada para realizar otras tareas.
 


SERVOMOTORES

PRÁCTICA RÁPIDA: "SERVOMOTOR"
Realizar un montaje que active un servomotor y modifique la posición de su eje cíclicamente desde 0, 90 y 180 grados con una parada en cada posición de 0,5 segundos .
Un servo es un tipo especial de motor que puede posicionar su eje en un ángulo determinado entre 0 a 180 grados. Para ello dispone de una lógica electrónica interna que permite un control mucho más preciso que un motor de corriente continua (motor DC). Asimismo tiene un tope mecánico que hace que no pueda avanzar más de 180 grados. Para accionarlos con Arduino utilizamos los pines digitales marcados con PWM (~).
PWM significa Modulación por ancho de impulsos (Pulse Width Modulation). Se trata de obtener una onda cuadrada donde, cuanto más tiempo esté el pulso en alto, más se asemejará a una señal analógica de 5V. Se usa el comando analogWrite(pin, valor) Donde valor está entre 0 y 255 según el ciclo de trabajo de la gráfica:
cicloPWM

ESQUEMA:

ARDUINOSERVO
5V+ (ROJO)
GND- (MARRÓN)
D9 (Para este ejemplo)SEÑAL (AMARILLO)

PROGRAMA:

#include <Servo.h>
Servo myservo; // crea un objeto tipo servo para controlar el servo

void setup(){
myservo.attach(9); //conecta al pin 9
}

void loop()
{

myservo.write(0); 
delay(500); 

myservo.write(90);
delay(500);

myservo.write(180);
delay(500);
}


PRÁCTICA RÁPIDA: "SERVOMOTOR DE ROTACIÓN CONTIUA"
Realizar una práctica que haga girar un motor de rotación continua una vez con la siguiente secuencia: giro durante 2 segundos, parada durante 2 segundos y giro en sentido contrario durante 2 segundos.
Un servomotor de rotación se programa de forma muy similar a los servomotores vistos anteriormente. La diferencia respecto a estos es que el servo de rotación continua puede girar (como su nombre indica) los 360 grados de forma continua. Hay que recordar que un servomotor sólo podía girar de 0 a 180 grados. Los servos de rotación continua llevan una reductora y proporcionan un buen par motor. Incluyen un circuito interno de control y las conexiones se realizan a través de 3 cables: Alimentación (+Vcc), Tierra (GND) y señal de control.

ESQUEMA:

esquema-servocont

PROGRAMA:

#include <Servo.h>
Servo servoRotCont; // crea los objetos para controlar los servomotores

void setup() {

  servoRotCont.attach(9); 
  servoRotCont.write(0);//clockwise
  delay(2000);
  servoRotCont.write(90); //stop (el valor 90 depende del motor.
  //Es conveniente probar valores por encima o por debajo
  //de 90 hasta comprobar que se para el servomotor.
  delay(2000);
  servoRotCont.write(180);//counter-clockwise
  delay(2000);
  servoRotCont.write(90); //stop

}
void loop() {

 
}


TEORÍA DEL SERVOMOTOR
portada-servo
Una de las aplicaciones más utilizadas de los sistemas de control por ordenador y en la robótica están asociados con los motores, que permiten accionar o mover otros componentes, como puertas, barreras, válvulas, ruedas, etc. Uno de los tipos que vamos a ver en este capítulo es el servomotor que posee la capacidad de posicionar su eje en un ángulo determinado entre 0 y 180 grados en función de una determinada señal.

Conocimiento previo

  • Programación básica de Arduino.
  • Uso de librerías internas de Arduino (Servo.h).
  • Bucles for.

Los servos son un tipo especial de motor en el que se añade una circuito lógico electrónico que permite un control mucho más preciso que a un motor normal de corriente continua. Los servomotores se utilizan para posicionar el eje en un ángulo determinado.
El hardware interno se compone de un potenciómetro y un circuito integrado que controlan en todo momento los grados que gira el motor. De este modo, en nuestro caso, desde Arduino, usando las salidas digitales PWM podremos controlar fácilmente un servo.
conexiones-servo

La conexión se realiza mediante 3 cables: 2 de alimentación (+5V/GND) y un tercero, conectado por ejemplo el 6 marcado como PWM según se observa en el esquema de conexiones, donde indicaremos los grados que queremos que gire a través de un programa en Arduino.
En Edubásica tenemos una forma muy sencilla de conectar un servo a la tarjeta. Lo puedes hacer mediante las clavijas identificadas con JP3.
De arriba abajo las conexiones son:
  • Señal (pin7)
  • +5V
  • GND
Recuerda que siempre puedes utilizar los pines analógicos como E/S digitales, del pin 14 al 19.
Por ejemplo, puedes conectar el servo al pin analógico 5, pero declarado como digital en el 19.

Arduino incluye una librería con funciones para mover de una manera sencilla un servo, lo primero es introducir un include con la librería al principio, luego creamos el objeto (que será el nombre que usaremos en todo el programa para cada servo que queramos controlar) .
Por último, asociamos el servo al pin al que lo hemos conectado (7).
Una vez declarado, para usarlo, dentro de loop simplemente usamos la función servo.write(posicion)
Moverá el servo los grados que le indiquemos mediante la variable entera: posicion.
A continuación verás un sencillo ejemplo que coloca el servo totalmente a la izquierda, en el centro y a la derecha de su recorrido, dejamos un pequeño delay , para permitir que el servo alcance la posición antes de darle la siguiente orden:
#include <Servo.h> 
 
Servo myservo;        // crea un objeto tipo servo para controlar el servo 
int pos = 0;          // variable para almacenar la posición del servo
 
void setup(){ 
  myservo.attach(7);  // En EduBasica el servo se conecta al pin 7 
}

void loop() 
{ 
  pos=0;       //A la derecha
  myservo.write(pos); //damos la orden con los grados
  delay(50);       // esperamos que el servo llegue a la posición
  pos=90;       //Centrado
  myservo.write(pos); //damos la orden con los grados
  delay(50); 
  pos=180;       //A la izquierda
  myservo.write(pos); //damos la orden con los grados
  delay(50); 
} 

Si queremos mejorar un poco el código anterior, podemos utilizar un for, que nos permite realizar una secuencia de acciones varias veces.
Utilizamos una variable como contador, en este caso es la misma posición (pos) , que se irá incrementando en 90 grados en cada iteración del bucle. En nuestro ejemplo se ejecuta 3 veces:
for (pos=0; pos<=180; pos+=90) { 
  myservo.write(pos); //orden con los grados en cada iteración


Actividad

Podemos probar una aplicación muy importante que está basada en mover el servo según una determinada entrada analógica. Este nos puede ser  muy útil si queremos controlar servos por medio de joysticks por ejemplo o cualquier dispositivo que cuente con potenciómetros para realizar un movimiento.
Para este ejemplo símplemente carga el ejemplo que viene incluido en la IDE de de Arduino (Knob) que encontrarás en:
 Archivo->Ejemplos->Servo 
Para que funcione en Edubásica sólo tienes que cambiar el número de pin de la conexión del servo:myservo.attach(7);  
Lo que hace este programa es variar la posición del servo enfunción de la posición del potenciómetro que leemos de manera analógica.
Sólo nos queda mapear la lectura para que se mueva de 0 a 180º.