Robot A3
Seguidor de Línea Guía de usuario
Introducción
A3 es un robot autónomo de morfología móvil, diseñado para competiciones de seguimiento de línea. Se trata de un robot ro bot de tipo diferencial, su tracción basa en dos motores de corriente directa, alimentado alimentado por una batería de 9 Voltios. A3 utiliza un microcontrolador de la marca Atmel modelo Atmega328, con firmware de Arduino, Arduino, lo cual facilita su programación. progr amación.
Advertencias de seguridad y precauciones de uso
El robot A3 no es un juguete. Puede ser usado por niños y jóvenes bajo la supervisión y ayuda de un adulto. El uso o abuso del producto es responsabilidad del usuario final. Grupo Educare no se hace responsable por daños o lesiones que éste pueda causar durante su uso. Este producto no está diseñado para jugar, no debe usarse fuera de las condiciones de trabajo. A continuación se indican las precauciones: • •
•
• •
•
Antes de comenzar por favor lee cuidadosamente el manual. Utiliza baterías alcalinas o recargables. En el caso de las alcalinas asegúrate que sean nuevas, y si compras recargables verifica que tengan suficiente carga, de lo contrario al programar lo puedes inutilizar para siempre. Condiciones de trabajo: ◦ superficie lisa, de preferencia melamina, ◦ interiores con luz controlada. controlada. No colocar la tarjeta de circuito impreso (PCB) sobre superficies metálicas. El robot A3 esta ensamblado y soldado con piezas que contienen plomo y estaño, por lo cual es necesario lavarse las manos después de manipularlo. Los componentes del robot están expuestos, por lo que es importante no tocarlo con las manos mientras está en funcionamiento. Si tus manos están mojadas se puede causar c ausar un corto circuito y dañar uno o varios componentes.
Primeros pasos de A3
¿Qué necesitas? • Batería de 9V. Utiliza Utili za de preferencia baterías alcalinas o recargables. Si trabajará durante durante tiempos prolongados con el robot, te recomendamos usar baterías recargables de Niquel-Metal Hidruro, NiMH. No olvides comprar el cargador correspondiente. • Cable A – B, USB a Micro USB. A3 no requiere un programador externo, todo el hard hardwa ware re elect electró róni nico co ya se inclu incluye ye en el robo robot, t, pero pero para para la comu comuni nica cació ción n entr entree la computadora computadora y el e l robot se requiere dicho cable. • Computadora. Necesitas una computadora para programar el robot. Para ello se utiliza la interfaz de programación de Arduino, plataforma libre, que funciona en cualquiera de los siguientes sistemas operativos: ◦ Windows ◦ Mac ◦ Linux • Material para pruebas. Es necesario que tengas a mano papel, cartulinas, cartoncillo y cinta aislante negra o blanca, blanca, para improvisar pistas y probar el robot.
Conoce más del robot A3
Figura 1. Vista frontal de robot seguidor de línea A3 A3 es un robot de morfología móvil de tipo diferencial, es decir se desplaza por medio de dos ruedas con dos motores, uno para cada una. El cerebro de este robot es un Arduino Nano, y está encargado de procesar la información que le proveen los sensores para realizar correcciones a través de los motores, bajo el esquema básico de control. Hardware de A3
En la figura 1 se muestra el hardware del robot. Observa que se cuenta con varios componentes y dispositivos electrónicos. ¿Reconoces alguno?, a continuación se explican brevemente. • Sensores reflectivos de contraste, son los encargados de percibir la información del ambiente, en este caso el contraste, la diferencia entre lo blanco y lo negro, lo brillante y lo opaco. Este dispositivo se compone de dos partes: emisor y receptor. Tanto el primero como el segundo trabajan en el rango infrarrojo de la luz. Ésta no es perceptible por el ojo humano, pero con ayuda de una cámara digital se observa.
•
•
•
•
•
LEDs. Diodos emisores de luz por sus siglas en inglés, son dispositivos que emiten una luz al
circular una corriente por sus terminales. terminales. En A3 se usan como indicadores y son son programables por el usuario por medio del Arduino. Driver para motor. Basado en un transistor de potencia NPN, son los que proveen de potencia al motor, siendo la interfaz entre el microcontrolador y el motor. Botones. Son interruptores de encendido al contacto. El robot cuenta con 2, el primero para reiniciar el microcontrolador (arduino), y el segundo como botón de usuario para propósito general. Motorreductores. Son motores de corriente directa (CD, como el de las baterías), con una caja de engranes adaptada. Los usados en A3 tienen una reducción de 48:1, esto es, por cada 48 vueltas que gire el motor, el eje del reductor girará 1 vuelta. De este modo se incrementa el torque, fuerza, y se reduce la l a velocidad. Batería. Es la que provee de energía eléctrica a todo el robot, arduino, sensores, LEDs, motores, pulsadores. Es tipo rectangular de 9V.
Figura 2. Vista trasera de A3
Arduino Nano
Es una pequeña y completa placa basada en el mirocontrolador Atmega328 que generalmente se usa para hacer prototipos. Tiene más o menos la misma funcionalidad que el Arduino UNO, pero con una presentación más compacta. No posee conector para alimentación externa, y funciona con un cable USB Mini-B en ez del cable estándar.
Figura 3. Arduino Nano Especificaciones • Microcontrolador: Atmega328. • Tensión de operación (nivel lógico): 5 Voltios. • Tensión de entrada (recomendada): 7-12 Voltios. • Tensión de entrada (límites): 6-20 Voltios. • Pines E/S digitales: 14 (de los cuales 6 proveen de salida PWM). • Entradas Analógicas: 8 • Corriente máxima por cada PIN de Entrada/Salida: Entrada/Salida: 40mA • Memoria Flash: 32KB. • SRAM: 2KB • EEPROM: 1KB. • Dimensiones: 18.5 mm x 23.2 mm.
Alimentación Alimentación
El Arduino Nano puede ser alimentado usando el cable USB Mini-B , con una fuente externa no regulada de 6-20V (pin 30), o con una fuente externa regulada de 5V (pin 27). La fuente de alimentación es seleccionada automáticamente a aquella con mayor tensión. El chip FTDI FT232RL que posee el Nano solo es alimentado si la placa esta siendo alimentada usando el cable USB. como resultado, cuando se utiliza una fuente externa (no USB), la salida de 3.3V (la cual es proporcionada por el chip FTDI) no está disponible y los pines 1 y 0 parpadearán si los pines digitales 0 o 1 están a nivel alto. Memoria
El ATmega168 posee 16KB de memoria flash para almacenar el codigo (de los cuales 2KB son usados por el bootloader); el ATmega 328 posee 32KB, (también con 2 KB usados por el bootloader). El Atmega168 posee 1KB de SRAM y 512 bytes de EEPROM (la cual puede ser leida y escrita con la librería EEPROM); el ATmega328 posee 2 KB de SRAM y 1KB de EEPROM. Entrada y Salida
Cada uno de los 14 pines digitales del Nano puede ser usado como entrada o salida, usando las funciones pinMode(), digitalWrite(), y digitalRead(). Operan a 5 voltios. Cada pin puede proveer o recibir un máximo de 40mA y poseen una una resistencia de pull-up (desconectada (desconectada por defecto) de 20 a 50 kOhms. Además algunos pines poseen funciones especializadas: especializadas: Serial: 0 (RX) y 1 (TX). (RX) usado para recibir y (TX)usado para transmitir datos TTL vía serie. Estos pines están conectados a los pines correspondientes del chip USB-a-TTL de FTDI. • Interrupciones Externas: pines 2 y 3. Estos pines pueden ser configurados para activar una interrupción por paso a nivel bajo, por flanco de bajada o flanco de subida, o por un cambio de valor. Mira la función attachInterrupt() para más detalles. • PWM: pines 3, 5, 6, 9, 10, y 11. Proveen de una salida PWM de 8-bits cuando se usa la función analogWrite(). • SPI: pines 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Estos pines soportan la comunicación SPI, la cual, a pesar de poseer el hardware, hardware, no está actualmente actualmente soportada en el lenguaje Arduino. • LED: Pin 13. Existe un LED conectado al pin digital 13. Cuando el pin se encuentra en nivel alto, el LED está encendido, cuando el pin está a nivel bajo, el LED estará apagado. El Nano posee 8 entradas analógicas, cada unas de ellas provee de 10 bits de resolución (1024 valores diferentes). Por defecto miden entre 5 voltios y masa, sin embargo es posible cambiar el rango superior usando la función analogReference(). También, algunos de estos pines poseen funciones especiales: • I2C: I2C: Pine Piness 4 (SDA (SDA)) y 5 (SCL (SCL). ). Sopo Soport rtaa comu comuni nica cació ción n I2C I2C (TWI) (TWI) usan usando do la libre librerí ríaa Wire Wire (documentación en la web Wiring). Hay algunos otros pines en la l a placa: • AREF. AREF. Tensión ensión de refer referenc encia ia por las entra entrada dass analóg analógica icas. s. Se config configur uraa con la función función analogReference(). • Reset. Pon esta linea a nivel bajo para resetear el microcontrolador. Normalmente se usa para añadir un botón de reset que mantiene a nivel alto el pin reset mientras no es pulsado. •
Diagrama Pictórico
Figura 4. Diagrama pictórico de circuito de A3
Programando en Arduino
Para programa el robot seguidor de línea es necesa rio contar con el entorno de programación de Arduino. Si aún no lo tiene lo puede descargar en: www.arduino.cc www.arduino.cc en en la sección de descargas. Es recomendable que la versión de arduino que descarque sea igual i gual o posterior a las 1.0.
Figura 5. Captura de pantalla de entorno de programación Arduino versión 1.0.1 Componentes de Arduino IDE
•
•
Figura 6. Icono “Verificar” Verificar. inspecciona el código generado, marca errores y posibles soluciones.
Figura 7. Ícono: “Cargar” Cargar: Cuando se presiona este botón se compila y ensambla el código contenido en la ventana y se descarga a la tarjeta electrónica de Arduino. Este proceso puede tardar algunos segundos o tal vez un para de minutos.
•
Figura 8. Ícono: “Nuevo”. Nuevo: crea un nuevo “sketch” en blanco.
•
Figura 9. Ícono: “Abrir”. Abrir: abre un “sketch”, código, ya existente.
•
Figura 10. Ícono: “Guardar”. Guardar: salva las modificaciones realizadas en el código.
•
Figura 11. Ícono: “Monitor Serial”. Monito Monitorr Serial Serial:: abre abre la aplica aplicació ción n de monito monitorr serial serial,, que que puede puede servir servir para para difere diferent ntes es propósitos.
Referencias Referencias del lenguaje Los programas hechos con Arduino se dividen en tres partes principales: Estructura, valores (variables y constantes), funciones. El lenguaje de programación Arduino se basa en C/C++. •
•
•
Estructuras Las dos estructuras principales son las siguientes: setup(), es la estructura donde se configura las entradas, salidas y los módulos. Es llamado también como “inicialización”. “inicialización”. Lo contenido en esta estructura se ejecuta sólamente una vez al inicio del programa. programa. loop(), es la estructura donde se escribe el código, y se repetirá infintas veces. •
•
Valores Constantes HIGH, alto, LOW, bajo, INPUT, entrada, OUTPUT, salida, • True, verdadero, • false, falso, •
•
•
•
Variables: • boolean, booleando, • char, carácter, • byte, 8 bits • int, entero, • unsigned int, entero sin signo, • long, entero de 32 bits, • unsigned long, entero 32 bits sin si n signo, • float, punto flotante. Funciones • pinMode(), configura si el pin digital será salida o entrada, • digitalWrite(), si el pin ha sido configurado como salida digital, su voltaje de salida será 0 o 5V. • digitalRead(), digitalRead(), lectura del valor digital del pin especificado, • analogRead(), analogRead(), lectura del valor analógico del pin especificado, • analogWrite(), analogWrite(), configura la modulación por anchura de pulso de un pin (PWM), • delay(), pausa en milisegundos. • Serial, librería incluida para el uso y configuración del módulo serial. Revisa la referencia del lenguaje de arduino para aprender más acerca de las estructuras, variables y funciones de Arduino.
El primer programa en Arduino para A3
Un sencillo programa de demostración está disponible en los ejemplos de Arduino, “Archivo/Ejemplos/01.Basics/Blink”.
Figura 12. El primer programa programa en Arduino Este sencillo programa prende y apaga un LED, colocado en la patilla, pin 13. /* Blink Turns on an LED on for one second, then off for one second, repeatedly. */ // Pin 13 has an LED connected on most Arduino boards. int led = 13; // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. pinMode(led, OUTPUT); }
// the loop routine runs over and over again forever: void loop() { digitalWrite(led, digitalWrite(led, HIGH); // turn the LED on (HIGH is the the voltage voltage level) delay(1000); // wait for a second digitalWrite(led, digitalWrite( led, LOW); // turn the LED off by making the voltage LOW LOW delay(1000); // wait for a second } Abierto el programa de ejemplo es necesario seleccionar la tarjeta correspondiente, en el caso del robot robot seguidor seguidor de línea, línea, se trat trataa de un Ardui Arduino no Nano Nano Atmeg Atmega32 a328, 8, para para ello diríjase diríjase al menú menú Herramientas/Tarjeta/Arduino Nano w/Atmega328.
Figura 13. Selección de tarjeta Arduino Nano w/ATmega328 Ahora se verificará que el código escrito sea correcto, presione el ícono verificar:
Lo que hará esta función será “traducir” todo lo codificado a un “idioma” que entienda el microcont contro rola lado dorr. Obse Observ rvee los los avis avisos os y erro errore ress de sali salida da most mostra rado dos. s. Si el prog progra rama ma se comp compililaa correctamente, correctamente, el mensaje de salida deberá ser como se muestra en la figura:
Figura14. Mensajes de salida Una vez compilado y verificado el programa, y en vista que no existen errores o advertencias, se procede a cargar el programa a la tarjeta de Arduino. Para ello antes es importante seleccionar el puerto de comunicación serial “COM” correcto. Para ello se puede hacer lo siguiente: • Abra el administrador administrador de dispositivos, • En la pestaña “Puertos (COM y LPT)”, verifique el puerto en el cual está ubicado el Arduino. Generalmente tiene el nombre de “USB Serail Port”.
Figura 15. Verificación del del puerto COM del del Arduino
Una vez identificado, identificado, se selecciona en el IDE, Herramientas/Puerto Herramientas/Puerto serial/COMx serial/COMx
Figura 16. Selección del Puerto Serial Cargue el programa a la tarjeta de Arduino presionando el ícono de cargar. Esta acción puede tardar algunos segundos.
Figura 17. Carga de programa a tarjeta de Arduino Si la carga fue exitosa se desplegará el siguiente mensaje:
Figura 18. Carga Exitosa
Ejemplos y proyectos Ahora que sabe como compilar y cargar un prorama a la tarjeta de Arduino es tiempo de aprender a diseñar y codificar programas más complicados. Comenzará con los más sencillos. Ejemplo 1: Luces estilo el “auto increible”
Figura 16. Tarjeta de A3 La tarjeta del robot seguidor de línea incluye 5 indicadores LED's para el propósito General. Éstos se encuentran en los pines digitales 11, 9, 8, 7, 6, marcados como B0, B1, B2, B3, B4 en ese preciso orden. La secuencia que se quiere lograr es la siguiente:
Movimiento 1
Movimiento 2
Movimiento 3
Movimiento 4
Movimiento 5
Movimiento 6
Movimiento
Movimiento !
Figura 17. Luces del auto increíble. El código de este programa se encuentra disponible en la página Web: http://www.grupoeducare.com/dct/index.php/rec/robotopia int runled = 13; //Alias para pin 13 int led0 = 11; int led1 = 6; int led2 = 7; int led3 = 8; int led4 = 9; void setup() { //Configuración de entradas y salidas pinMode(runled, OUTPUT); OUTPUT); //Salida digital en runled runled = pin 13 pinMode(led0, OUTPUT); OUTPUT); //Salida digital digital en led0 = pin 11 pinMode(led1, OUTPUT); OUTPUT); //Salida digital digital en led1 = pin 6
pinMode(led2, OUTPUT); OUTPUT); //Salida digital digital en led2 = pin 7 pinMode(led3, OUTPUT); OUTPUT); //Salida digital digital en led3 = pin 8 pinMode(led4, OUTPUT); OUTPUT); //Salida digital digital en led4 = pin 9 //Configuración de módulos } void loop() { //Código que se repetirá infititamente infititamente //Corrimiento de LEDs del B0 al B4 digitalWrite(led0, HIGH); //Puesta en alto de led0, prende digitalWrite(led1, LOW); LOW); //Puesta en bajo de led1, apaga delay(250); digitalWrite(led1, HIGH); //Puesta en alto de led1, prende digitalWrite(led0, LOW); LOW); //Puesta en bajo de led0, apaga delay(250); digitalWrite(led2, HIGH); //Puesta en alto de led2, prende digitalWrite(led1, LOW); LOW); //Puesta en bajo de led1, apaga delay(250); digitalWrite(led3, HIGH); //Puesta en alto de led3, prende digitalWrite(led2, LOW); LOW); //Puesta en bajo de led2, apaga delay(250); digitalWrite(led4, HIGH); //Puesta en alto de led4, prende digitalWrite(led3, LOW); LOW); //Puesta en bajo de led3, apaga delay(250); //Corrimiento de LEDs del B4 al b0 digitalWrite(led3, HIGH); //Puesta en alto de led0, prende digitalWrite(led4, LOW); LOW); //Puesta en bajo de led4, apaga delay(250); digitalWrite(led2, HIGH); //Puesta en alto de led0, prende digitalWrite(led3, LOW); LOW); //Puesta en bajo de led4, apaga delay(250); digitalWrite(led1, HIGH); //Puesta en alto de led0, prende digitalWrite(led2, LOW); LOW); //Puesta en bajo de led4, apaga delay(250); } Es un ejemplo sencillo pero ayuda a comprender el manejo de los pines digitales como salidas.
Ejemplo 2 Encendido de un LE! con un interruptor sin contacto" La tarjeta del robot A3 cuenta con c on 5 sensores del tipo reflectivo infrarrojo. Este E ste tipo está compuesto de dos componentes un emisor y un receptor. El primero es un LED infrarrojo, luz que no podemos ver los ojos; el segundo es un fototransistor fototransistor con filtro de luz de día. El funcionamiento es el siguiente:
Figura 18. Sensor Reflectivo sobre superficie reflejante. Cuando el LED infrarrojo se encuentre emitiendo luz, si la superfice es reflejante, por ejemplo blanca, se refleja una cantidad de luz que es percebida por el fototransistor fototransistor,, que convierte la señal luminosa en voltaje, permite un flujo de corriente entre sus terminales y por la configuración de carga de emisor se obtiene un valor.
Figura19. Sensor Reflectivo sobre superficie opaca Por lo contrario si el la superficie es opaca, por ejemplo negra, se refleja poca luz, la cual es percibida por el fototransisto, pero se genera poca corriente en sus terminales y por consiguiente poco voltaje. Este sensor no puede servir como un interruptor sin contacto, y se usa comúnmente en muchos procesos de la industra y cotidianos, tal es caso de las llaves automáticas de agua usadas en los baños públicos. La intensión es que cuando coloque su dedo frente al sensor este active el LED. A continuación se propone el código. /*--------------------------------Inicio del código--------------------------------*/ //Declaración de variables globales int sensor4; int runled = 13; //Alias para pin 13
int led0 = 11; void setup() { //Configuración de entradas y salidas pinMode(led0, OUTPUT); OUTPUT); //Salida digital digital en led0 = pin 11 //Configuración de módulos } void loop() { //Código que se repetirá infititamente infititamente sensor4 = analogRead(A4); analogRead(A4); //Lectura del sensor Izquierdo if (sensor4 > 512) //Si la superficie es blanca entonces entonces prende LED { digitalWrite(led0, HIGH); } else //Sino, es decir, es negro, entonces apaga LED { digitalWrite(led0, digitalWrite(led0, LOW); } delay(50); } /*--------------------------------Fin del código--------------------------------*/ El funcionamiento de este será el siguiente, cuando coloque su dedo cerca del sensor marcado como “A4” en el PCB del robot el indicador LED marcado como B0 se encenderá, sino se mantendrá apagado, como se muestra en la siguiente figura.
Figura 20. Funcionamiento del programa
Ejercicio # Desarrolle un programa que cumpla con las siguientes condiciones:
Si el sens sensor or 4, A4, A4, det detecta ecta,, está está sobr sobree una una Si el sens sensor or 3, A3, A3, det detecta ecta,, está está sobr sobree una una superf superficie icie refle reflejan jante, te, entonc entonces es prend prendee el LED superf superficie icie refle reflejan jante, te, enton entonces ces prend prendee el LED marcado como B0. marcado como B1.
Si el sens sensor or 2, A2, A2, det detecta ecta,, está está sobr sobree una una Si el sens sensor or 1, A1, A1, det detecta ecta,, está está sobr sobree una una superf superficie icie refle reflejan jante, te, entonc entonces es prend prendee el LED superf superficie icie refle reflejan jante, te, enton entonces ces prend prendee el LED marcado como B2. marcado como B3.
Si el sens sensor or 0, A0, A0, det detecta ecta,, está está sobr sobree una una Cada Cada uno uno de los los sens sensor ores es debe debe accio acciona narr de superf superficie icie refle reflejan jante, te, entonc entonces es prend prendee el LED manera independiente, pudiendo estar varios en marcado como B4. superficie reflejante reflejante y tener funcionamiento. funcionamiento.
Ejemplo 3 Accionar de motores" Para probar los motores tenemos que conectarlos en los terminales (verdes con tornillos), marcados como “Motor A” y “Motor B”. En la siguiente figura se muestra a manera de ejemplo la conexión.
Figura 21. Conexión de motores También es necesario conectar la batería con interruptor. Sea cuidadoso al conectar la batería, conecte el cable rojo del broche de la batería (positivo) en el tornillo del terminal verde marcado con “+V”, y el negro (común, tierra) conéctelo al otro lado del terminal, marcado con “GND”. Puede guiarse de la siguiente figura para conectarlo. Corte la alimentación con el interruptor.
Figura 22. Conexión de batería
Copie y pegue el siguiente código en la ventana del IDE de Arduino. /*--------------------------------Inicio del código--------------------------------*/ //Declaración de variables globales int sensor0, sensor1, sensor2, sensor3, sensor4; int MotorA = 3; int MotorB = 5; int led1 = 6; int led2 = 7; int led3 = 8;
void setup() { //Configuración de entradas y salidas pinMode(MotorA, OUTPUT); OUTPUT); //Salida digital en MotorA MotorA = pin 5 pinMode(MotorB, pinMode(MotorB, OUTPUT); //Salida digital en MotorA MotorA = pin 3 pinMode(led1, OUTPUT); OUTPUT); //Salida digital digital en led1 = pin 6 pinMode(led2, OUTPUT); OUTPUT); //Salida digital digital en led2 = pin 7 pinMode(led3, OUTPUT); OUTPUT); //Salida digital digital en led3 = pin 8 //Configuración de módulos } void loop() { //Código que se repetirá infititamente infititamente //Adelante digitalWrite(MotorA, HIGH); digitalWrite(MotorB, digitalWrite(MotorB, HIGH); digitalWrite(led1, digitalWrite(led1, LOW); digitalWrite(led2, HIGH); digitalWrite(led3, digitalWrite(led3, LOW); delay(1000); //Derecha digitalWrite(MotorA, HIGH); digitalWrite(MotorB, LOW); digitalWrite(led1, HIGH); digitalWrite(led2, digitalWrite(led2, LOW); digitalWrite(led3, digitalWrite(led3, LOW); delay(1000); //Izquierda
digitalWrite(MotorA, LOW); digitalWrite(MotorB, digitalWrite(MotorB, HIGH); digitalWrite(led1, digitalWrite(led1, LOW); digitalWrite(led2, digitalWrite(led2, LOW); digitalWrite(led3, HIGH); delay(1000); } /*--------------------------------Fin del código--------------------------------*/ Funcionamiento
El robot deberá ir hacia adelante, después a la derecha y por último a la izquierda. Se repetirá infinitamente. Verifique que la secuencia descrita corresponda con el movimiento del robot. Si alguno de los motores gira en sentido contrario contrario invierta los cables en los terminales de tornillo (verdes).
Ejemplo $ %isuali&ación del valor de los sensores en monitor serial" Una de las grandes ventajas de las tarjetas de Arduino es su simplicidad para establecer conexión con una computadora. Esto se realiza gracias al convertivor USB a serial incluido en la tarjeta. A demás el entorno de programación cuenta con una aplicación, monitor serial, que sirve para visualizar, visualizar, recibir y enviar informa i nformación. ción. El siguiente programa obtiene el valor de los sensores reflectivos analógico, los cuantifica y los despliega. La cuantificación es el proceso por el cual se le asigna un valor en bits a una señal. Los convertidores convertidores CAD, Analógico a Decimal, cuantifican las señales, es decir entregan un valor en número dependiendo de la resolución que posean. En el caso del microcontrolador que se usa, Atmega328, la resolució resolución n es de 10 bits, es decir 1024 divisione divisioness en la escala del 0 al 5V. 5V. Una buen analogía analogía es la siguiente: Suponga que tiene una escalera de 5 metros con 1024 escalones, cada escalón le hará subir 0.0048 metros. Si otra persona le indica que tiene que pintar una linea a 2.5 metros del piso, ¿Cuántos escalones tendrá que subir?, esto puede resolverse por una simple regla de tres: Dato=
2.5metros∗1024escalones 5metros
=512escalones
A grosso modo eso es lo que hace un convertidor Analógico a Digital, convierte un voltaje en un dato que pueda manipular. Para realizar la calibración los sensores o para obtener información de ellos se puede realizar un programa que muestre los datos en el monitor serial. A continuación se propone el código para realizar esta tarea. /*--------------------------------Inicio del código--------------------------------*/ //Declaración de variables globales int sensor0, sensor1, sensor2, sensor3, sensor4; void setup() { //Configuración de entradas y salidas //Configuración de módulos Serial.begin(9600); } void loop() { //Código que se repetirá infititamente infititamente sensor0 = analogRead(A0); analogRead(A0); //Lectura del sensor Derecho sensor1 = analogRead(A1); analogRead(A1); //Lectura del sensor Centro Derecho sensor2 = analogRead(A2); analogRead(A2); //Lectura del sensor Centro sensor3 = analogRead(A3); analogRead(A3); //Lectura del sensor Centro Izquierdo Izquierdo sensor4 = analogRead(A4); analogRead(A4); //Lectura del sensor Izquierdo
Serial.print("Sensor Derecho = "); Serial.println(sensor0); Serial.println(sensor0); Serial.print("Sensor Centro Derecho = "); Serial.println(sensor1); Serial.println(sensor1); Serial.print("Sensor Centro = "); Serial.println(sensor2); Serial.println(sensor2); Serial.print("Sensor Centro Izquierdo = "); Serial.println(sensor3); Serial.println(sensor3); Serial.print("Sensor Serial.print("Sensor Izquierdo = "); Serial.println(sensor4); Serial.println(sensor4); delay(500); } /*--------------------------------Fin del código--------------------------------*/ Funcionamiento
Una vez compilado y descargado el código se deberá abrir el monitor serial dentro del IDE de Arduino para ver los datos.
Figura 23. Recepción de datos por el monitor Serial En la figura se puede observar los valores obtenidos sobre una superficie reflejante, en la parte superi superior or,, y en la poste posterio riorr sobre sobre una superf superficie icie opaca. opaca. Estos Estos dato datoss son impor importa tant ntes es para para la determinación del umbral para el seguidor de línea. l ínea. Ejercicio 2
Desarrolle el código para un programa que muestre por el monitor serial el valor de los sensores en Voltaje.
Ejemplo ' Seguidor de línea ( )ásico El seguimiento de una línea l ínea es una buena introducción en la programación de robots. ¿Por qué un seguidor de líneas? Es fácil entender el funcionamiento y la lógica de programación para el seguimiento de una línea. Optimizar el programa para hacer que el robot se deslice sobre una línea a la velocidad más rápida es un reto que puse llevarle a algunos conceptor avanzados de programación. E"p#icaci$n de# concurso
El concurso de velocidad consiste en una carrera de persecución entre dos robots en una pista cerrada, comenzando en puntos opuestos y avanzando avanzando en el mismo sentido. El objeto, por tanto, tanto, será la consecución de altas velocidades de marca en un recorrido perfectamente perfectamente establecido.
Figura 24. Competición seguidor de línea, lí nea, persecución %onstru&a una pista para prue'as
Es importante tener una pista o construir una con los siguientes materiales. • Cartulina blanca, • cinta de aislar negra, • tijeras. Para hacer pruebas dibuje con la cita de aislar una pista sencilla, tal vez sea suficiente con un rectángulo con las esquinas redondeadas o una elipse. No se recomienda vueltas con ángulos rectos, 90 grados.
Se propone el siguiente código, copie y pegue en el área de código del IDE de Arduino. /*--------------------------------Inicio del código--------------------------------*/ //Declaración de variables globales int sensor0, sensor1, sensor2, sensor3, sensor4; int runled = 13; //Alias para pin 13 int led0 = 11; int led1 = 6; int led2 = 7; int led3 = 8; int led4 = 9; int umbral = 750; int velocidad = 100; void setup() { //Configuración de entradas y salidas pinMode(runled, OUTPUT); OUTPUT); //Salida digital en runled runled = pin 13 pinMode(led0, OUTPUT); OUTPUT); //Salida digital digital en led0 = pin 11 pinMode(led1, OUTPUT); OUTPUT); //Salida digital digital en led1 = pin 6 pinMode(led2, OUTPUT); OUTPUT); //Salida digital digital en led2 = pin 7 pinMode(led3, OUTPUT); OUTPUT); //Salida digital digital en led3 = pin 8 pinMode(led4, OUTPUT); OUTPUT); //Salida digital digital en led4 = pin 9 //Configuración de módulos } void loop() { //Código que se repetirá infititamente infititamente sensor0 = analogRead(A0); analogRead(A0); sensor1 = analogRead(A1); analogRead(A1); //Lectura del sensor Centro Derecho sensor2 = analogRead(A2); analogRead(A2); //Lectura del sensor Centro sensor3 = analogRead(A3); analogRead(A3); //Lectura del sensor Centro Izquierdo Izquierdo sensor4 = analogRead(A4); analogRead(A4); if (sensor0 > umbral && sensor1 > umbral && sensor2 < umbral && sensor3 > umbral && sensor4 > umbral) //Si la superficie es blanca entonces prende LED { analogWrite(5, velocidad); analogWrite(3, velocidad); digitalWrite(led1, digitalWrite(led1, LOW);
digitalWrite(led2, HIGH); digitalWrite(led3, digitalWrite(led3, LOW); } //Centro y derecho if (sensor0 > umbral umbral && sensor1 < umbral umbral && sensor2 sensor2 > umbral umbral && sensor3 sensor3 > umbral && sensor4 > umbral) //Si la superficie es blanca entonces prende LED { analogWrite(5, 50); analogWrite(3, velocidad); digitalWrite(led1, HIGH); digitalWrite(led2, HIGH); digitalWrite(led3, digitalWrite(led3, LOW); } //derecho if (sensor0 < umbral && sensor1 > umbral && sensor2 > umbral && sensor3 > umbral && sensor4 > umbral) //Si la superficie es blanca entonces prende LED { analogWrite(5, 20); analogWrite(3, velocidad); digitalWrite(led1, HIGH); digitalWrite(led2, digitalWrite(led2, LOW); digitalWrite(led3, digitalWrite(led3, LOW); } //Centro Izquierdo if (sensor0 > umbral umbral && sensor1 > umbral umbral && sensor2 sensor2 > umbral umbral && sensor3 sensor3 < umbral && sensor4 > umbral) //Si la superficie es blanca entonces prende LED { analogWrite(5, velocidad); analogWrite(3, 50); digitalWrite(led1, digitalWrite(led1, LOW); digitalWrite(led2, HIGH); digitalWrite(led3, HIGH); } //Izquierdo if (sensor0 > umbral && sensor1 > umbral && sensor2 > umbral && sensor3 > umbral && sensor4 < umbral) //Si la superficie es blanca entonces prende LED { analogWrite(5, velocidad); analogWrite(3, analogWrite(3, 20);
digitalWrite(led1, digitalWrite(led1, LOW); digitalWrite(led2, digitalWrite(led2, LOW); digitalWrite(led3, HIGH); } } /*--------------------------------Fin del código--------------------------------*/ *uncionamiento
Son cinco las entrada entradass que se toman toman en cuenta para para hacer la corrección corrección en los motores motores y de esta esta forma seguir la línea. Si ya probó el código se dará cuenta que el robot sigue la línea de la siguiente manera.
Figura 25. Seguimiento de línea con condiciones Idealmente el programa descrito anteriormente tiene el comportamiento mostrado en la tabla. Sensor 0
Sensor 1
Sensor 2
Sensor 3
Sensor 4
Motor A (3)
Motor B (5)
1
1
1
1
0
8.00%
40.00%
1
1
1
0
1
20.00%
40.00%
1
1
0
1
1
40.00%
40.00%
1
0
1
1
1
40.00%
20.00%
0
1
1
1
1
40.00%
8.00%
En la tabla un “1” representa representa superficie blanca, y un “0” representa representa la línea negra. Para realizar ajuste en la velocidad, se debe de cambiar el valor de la variable “velocidad”. int velocidad = 100; Y las velocidades de cada motor en cada condición.
Como verá este sistema de control control no es muy eficiente, el seguidor de línea no se desliza exactamente sobre ella y se requiere trabajar a baja velocida. Ejercicio 3"
Desarrolle un código para la respuesta ante lo cinco sensores y las siguientes condiciones: Sensor 0
Sensor 1
Sensor 2
Sensor 3
Sensor 4
1
1
1
1
0
1
1
1
0
1
1
1
1
0
0
1
1
0
1
1
1
1
0
0
1
1
0
1
1
1
1
0
0
1
1
0
1
1
1
1
0
0
1
1
1
Motor A
Motor B
Ajuste y determine las acciones a tomar con respecto a la velocidad de cada uno de los motores.
Ejemplo + Seguidor de línea con Control ,I! Para seguir la línea con precisión es necesario aplicar métodos de control. La técnica usada en este ejemplo es el control PID. • Proporcional, es un valor propocional a la posición del robot sobre la línea. Si el robot está centrado sobre sobre la línea el error será 0, pero si se encuentra a la derecho o izquierda izquierda el valor del error será positivo o negativo. • Integral, es una memoria de todos los eventos anteriores. Una integral en sistemas discretos, generalmente generalmente usados por micro-controladores micro-controladores y microprocesadores, se pude expresar como la sumatoria de todos los puntos anteriores, lo que en sistemas continuos es el área debajo de la curva. • Deriva Derivativ tivo, o, es la razó razón n de cambio cambio,, la tenden tendencia cia,, el difere diferenci nciaa de los valor valores es actua actuales les y anteriores. El código propuesto /*--------------------------------Inicio código-------------------------------------*/ #include //Biblioteca para la lectura y calibración de los sensores de contraste //Declaración de constantes constantes #define NUM_SENSORS 5 // Número de sensores #define NUM_SAMPLES_PER_SENSOR NUM_SAMPLES_PER_SENSOR 4 // Número de muestras muestras por por sensor #define EMITTER_PIN 2 // Controlador de emisores LED's infrarrojos infrarrojos //Los sensores reflectivos para detectar contraste de encuentran conectados en las entradas //Analógicas A0 a A4 QTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5}, NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN); unsigned int sensorValues[NUM_SENSORS]; sensorValues[NUM_SENSORS]; //Vector //Vector para almacenar señal de sensores unsigned int sensors[5]; // Matriz para armazenar valores dos sensores int MotorA = 5; //Alias para Motor B int MotorB = 3; //Alias para Motor A //Declaración de variables int total = 0; float average = 0; int index = 0; int last_proportional; last_proportional; int integral; void setup(){
//Configuración de entradas y salidas digitales delay(500); pinMode(13, OUTPUT); //Se prende el indicador LED conectado en el pin 13, para indicar que se //inicia la calibración digitalWrite(13, HIGH); //Rotación del robot para calibración analogWrite(MotorA, 90); analogWrite(MotorB, 0); for (int i = 0; i < 200; i++) //Calibración durante durante 5 segundos segundos { qtra.calibrate(); qtra.calibrate(); // Se hace las lecturas para obtener valores de máximos y mínimos } digitalWrite(13 digitalWrite(13,, LOW); LOW); //Se apaga apaga el LED indicando que se completo la programación programación analogWrite(MotorA, 0); analogWrite(MotorB, 0); delay(1000); } void loop(){ while(1){ //Se obtiene el valor de de cada uno de los sensores sensores mediante mediante la función qtra.readline(); qtra.readline(); unsigned int position = qtra.readLine(sensorV qtra.readLine(sensorValues); alues); //Determinación del término proporcional int proportional = ((int)position) - 2000; //Determinación del término derivativo int derivative = proportional - last_proportional; last_proportional; //Determinación del término integral integral += proportional; proportional; //Se almacena el estado anterior para determinar el próxmio término derivativo last_pr l ast_proportional oportional = proportional; proportional; //Cálculo para determinar la velocidad de cada uno de los motores int power_difference = proportional/10 + integral/10000 integral/10000 + derivative*3/2;
const int max = 180; if(power_difference > max) power_difference power_difference = max; if(power_difference < -max) power_difference power_difference = -max; if(power_difference < 0) set_motors(max+power_diff set_motors(max+power_difference, erence, max); else set_motors(max, set_motors(max, max-power_difference); max-power_difference); } } // Accionamiento dos motores void set_motors(int left_speed, int right_speed){ if(right_speed >= 0 && left_speed >= 0){ analogWrite(MotorA, analogWrite(MotorA, left_speed); analogWrite(MotorB, analogWrite(MotorB, right_speed); } if(right_speed >= 0 && left_speed < 0){ left_speed = -left_speed; analogWrite(MotorA, analogWrite(MotorA, left_speed); analogWrite(MotorB, 0); } if(right_speed < 0 && left_speed >= 0){ right_speed = -right_speed; analogWrite(MotorA, 0); analogWrite(MotorB, analogWrite(MotorB, right_speed); } } /*--------------------------------Fin de código-------------------------------------*/ Para la compilación de este programa programa es necesario descargar descargar e instalar la librería “QTRSensors” “QTRSensors” para Arduino. *uncionamiento
El robot seguirá una línea blanca sobre fondo negro, deslizándose de la mejor manera posible, debido al método de contro usado, PID. Ejercicio $
Modifique el código para que el e l robot siga una línea negra con fondo blanco.