El 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.
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); }
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.
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
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:
- A partir de 10cm.
- Entre 10 y 35 cm.
- De 35 hasta fuera de rango.
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:
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).
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:
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.
SENSOR DE ULTRASONIDO
PRACTICA RÁPIDA: "DETECTOR DE OBJETOS POR ULTRASONIDOS"
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.pdfPROGRAMA 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"); }
EL SENSOR DE ULTRASONIDOS.
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.
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
(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
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:
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.
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
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.
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.
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º.