PROYECTO: “seguidor_línea” nOmbRE dEl PROgRama En aRduinO: “SEGUIDOR_LINEA_Joaquin_Berrocal_PirisVerano-17.ino”
(Realizado en Arduino 1.6.4)
Vídeo Construcción + Programa + Información variada
Autor: Joaquín Berrocal Piris Fecha: Verano 2017
Joaquín Berrocal Piris
1
CONSTRUCCIÓN (Verano 2017)
Joaquín Berrocal Piris
2
JoaquĂn Berrocal Piris
3
JoaquĂn Berrocal Piris
4
UTILIZO UNA PLACA ARDUINO UNO R3 Y UN DRIVER MOTOR CON L298N CONEXIONADO
Pines de la placa driver con arduino #define AIN1 3 #define AIN2 4 #define PWMA 5 #define PWMB 6 #define BIN1 8 #define BIN2 7 La placa de sensores que utilizo, no es la pololu QTR8A, es otra china parecida que vale unos 4€ respecto a los 17€ de la pololu. Sí utilizo la misma librería. Tan sólo utilizo 6 de los 8 sensores que dispone la placa. Conexiones: placa sensores --- arduino GND --- a GND IR ----- al pin 11(pwm) ¿en pololu serÍa seguramente el pin LEDON? D1 ----- NC No conexionado D2 ----- A0 D3 ----- A1 D4 ----- A2 D5 ----- A3 D6 ----- A4 D7 ----- A5 D8 ----- NC No conexionado + ----- a +5v
#define NUM_SENSORS 6 #define NUM_SAMPLES_PER_SENSOR 4 #define EMITTER_PIN 11 //en la placa pololu – QTR-8A: se conecta al pin LEDON . //“Yo lo conectao con el pin IR de mi módulo sensor” #define LED 13 //para activar led de la placa arduino durante la calibración de los sensores
NOTA : Con la librería “qtr-sensors-arduino-3.0.0 ”de pololu para los sensores infrarrojos Hay unos ejemplos explicativos para su uso. Y también hay un ejemplo llamado “QTRAExample_calibrar_QTRSensor.ino” que nos sirve para comprobar la placa de los sensores y ver si actúan ok viendo sus valores por el puerto serie. Al comienzo de cada carrera, hay que girar durante unos segundos (hasta que se apague el led de la placa arduino) de un extremo a otro sobre la cinta, para poder adaptar la sensibilidad de los sensores de infrarrojo a la luz de la cinta y sus alrededores.
Joaquín Berrocal Piris
5
---------------------------------------------------- PINES DE PLACAS ARDUINO ------------------------------------------Muestro la estructura de algunas placas Arduino, que se pueden utilizar para el control del semáforo de ruido, siendo más que suficiente con la NANO (3€) o la Uno (10€) La Arduino UNO R3
La Arduino NANO V3.1
Joaquín Berrocal Piris
6
La Arduino MEGA 2560
PROGRAMA EN ARDUINO 1.6.4 SEGUIDOR DE LINEA por Joaquín Berrocal Piris
//--------------------PROGRAMA----------------#include <QTRSensors.h>
//Mapeo de pines //#define STBY 9 //NO LO USO POR NO ESTAR EN MI PLACA DRIVER DE ACTIVACIÓN MOTOR permite un paro fijo #define AIN1 3 #define AIN2 4 #define PWMA 5 #define PWMB 6 #define BIN1 8 #define BIN2 7 #define NUM_SENSORS 6 #define NUM_SAMPLES_PER_SENSOR 4 #define EMITTER_PIN 11 //en la placa pololu – QTR-8A: se conecta al pin LEDON . //“quizás deba conectarlo con el pin IR de mi módulo sensor” #define LED 13 //para activar led de la placa arduino durante la calibración de los sensores
// Constantes para PID float KP = 0.5;//1.0; // ORIGINALES KP 0.01 KD 1.0 Ki 0.006 Va bien para Vmax >=100 float KD = 1.0; float Ki = 0.15;//0.006; // Regulación de la velocidad Máxima int Velmax = 255; //ORIGINAL ERA 80 Joaquín Berrocal Piris 7
// Data para integral int error1=0; int error2=0; int error3=0; int error4=0; int error5=0; int error6=0; // Configuración de la librería QTR-8A QTRSensorsAnalog qtra((unsigned char[]) {A0, A1, A2, A3, A4, A5} , NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN); unsigned int sensorValues[NUM_SENSORS]; //Estoy usando sólo 6 de los 8 // Función accionamiento motor izquierdo void Motoriz(int value) { if ( value >= 0 ) { digitalWrite(BIN1,LOW); //original era HIGH Y LOW digitalWrite(BIN2,HIGH); } else { digitalWrite(BIN1,HIGH); //ORIGINAL ERA LOW Y HIGH digitalWrite(BIN2,LOW); value *= -1; } analogWrite(PWMA,value); // ORIGINAL ERA PWMB } // Función accionamiento motor derecho void Motorde(int value) { if ( value >= 0 ) { digitalWrite(AIN1,LOW); // ORIGINAL ERA HIGH Y LOW digitalWrite(AIN2,HIGH); } else { digitalWrite(AIN1,HIGH); // ORIGINAL ERA LOW Y HIGH digitalWrite(AIN2,LOW); value *= -1; } analogWrite(PWMB,value); // ORIGINAL ERA PWMA } //Accionamiento de motores void Motor(int left, int righ) { //// digitalWrite(STBY,HIGH); no lo uso por no tenerlo mi placa driver de activación motores Motoriz(left); Motorde(righ); }
//función de freno void freno(boolean left, boolean righ, int value) { //// digitalWrite(STBY,HIGH); no lo uso por no tenerlo mi placa driver de activación motores Joaquín Berrocal Piris 8
if ( left ) { digitalWrite(BIN1,HIGH); digitalWrite(BIN2,HIGH); analogWrite (PWMB, value); } if ( righ ) { digitalWrite(AIN1,HIGH); digitalWrite(AIN2,HIGH); analogWrite (PWMA, value); } }
void setup() { // Declaramos como salida los pines utilizados pinMode(LED ,OUTPUT); pinMode(BIN2 ,OUTPUT); /////// pinMode(STBY ,OUTPUT); //NO LO USO POR NO ESTAR EN MI PLACA DRIVER DE ACTIVACIÓN MOTOR permite un paro fijo pinMode(BIN1 ,OUTPUT); pinMode(PWMB ,OUTPUT); pinMode(AIN1 ,OUTPUT); pinMode(AIN2 ,OUTPUT); pinMode(PWMA ,OUTPUT);
// Calibramos con la función qtra.calibrate();, y dejamos parpadeando el led, mientras se produce la calibración. for ( int i=0; i<70; i++) { digitalWrite(LED, HIGH); delay(20); qtra.calibrate(); digitalWrite(LED, LOW); delay(20); } delay(3000); }
unsigned int position = 0; //variables para utilizar PID int proporcional = 0; // Proporcional int integral = 0; //Intrgral int derivativo = 0; // Derivativo int diferencial = 0; // Diferencia aplicada a los motores int last_prop; // Última valor del proporcional (utilizado para calcular la derivada del error) int Target = 2500; // Setpoint (Como utilizamos 6 sensores, la línea debe estar entre 0 y 5000, //por lo que el ideal es que esté en 2500) void loop() { position = qtra.readLine(sensorValues, true, true); proporcional = ((int)position) - 2500; if ( proporcional <= -Target ) { Motorde(0); freno(true,false,255); Joaquín Berrocal Piris 9
} else if ( proporcional >= Target ) { Motoriz(0); freno(false,true,255); } derivativo = proporcional - last_prop; integral = error1+error2+error3+error4+error5+error6; last_prop = proporcional; error6=error5; error5=error4; error4=error3; error3=error2; error2=error1; error1=proporcional; int diferencial = ( proporcional * KP ) + ( derivativo * KD )+ (integral*Ki) ; if ( diferencial > Velmax ) diferencial = Velmax; else if ( diferencial < -Velmax ) diferencial = -Velmax; ( diferencial < 0 ) ? Motor(Velmax+diferencial, Velmax) : Motor(Velmax, Velmax-diferencial); } //-----FIN DEL PROGRAMA -------------
PROGRAMA EN ARDUINO 1.6.4 SEGUIDOR DE LINEA por Joaquín Berrocal Piris Ahora el mismo programa en color, con recortes fotográficos desde el mismo programa
Joaquín Berrocal Piris 10
JoaquĂn Berrocal Piris 11
JoaquĂn Berrocal Piris 12
DOCUMENTACIÓN VARIADA Componentes, drivers posibles En el video de youtube dice que utiliza micromotores de pololu 5:1 que son los más rápidos. Yo, para un peso de 385 a 507 grs, el que uso es el de 30/1 1000 rpm, con ruedas finas de 34 mm y va con fuerza Dirección global del youtube: https://www.youtube.com/watch?v=0Qww0lm0MQk Lamborghini competencia final dic 2016 https://www.youtube.com/watch?v=0G4La3PPuWA Lamborghino abril 2017 explicación sensores https://www.youtube.com/watch?v=eWIZBDN1os
Lamborghino: El Seguidor de Linea más Rápido de América Publicado el 6 abr. 2017 ¿De que está hecho el robot seguidor de línea más rápido de America? Lamborghino el único representante latino en la All Japan Micromouse Contest
◌ Código y Diagramas: http://lamborghino.cl/diy/ http://www.lamborghino.cl/ ◌ Tienda Zambeca: http://www.zambeca.cl ◌ Lista de Componentes: - Motores: https://goo.gl/J7W5sc - Sensor: https://goo.gl/NAUfkD https://www.pololu.com/docs/0J19/all - Ruedas: https://goo.gl/B2eZRO - Driver Puente H: https://goo.gl/RFr9Cb - Arduino: https://goo.gl/uphmMM ◌ Agradecimientos especiales a: Leonfindel por facilitarnos el material de la competencia en Japón. https://goo.gl/41DWuH
Código http://lamborghino.cl/codigo/ Antes de mostrar el código, es necesario entender el funcionamiento de Lamborghino. El modo de operar de lamborghino es la siguiente: •
Primero utilizamos las lecturas del sensor de luz infrarroja, para saber “qué tan alejado está el robot, respecto de la línea”. A esa “distancia de alejamiento”, le llamaremos “El Error”. • Luego tomaremos “la cuantificación de ese error”, y a través de un algoritmo matemático que ya describiremos, haremos funcionar a los motores con distintas velocidades, para que siempre se acomode para ir alineado con el camino. Entonces lo primero que debemos hacer es obtener la posición del robot, a partir de a lectura de los sensores de luz infrarroja: Como ya habíamos visto antes en la parte electrónica, podemos observar que el modo de funcionamiento de los sensores QTR-8A. Si las conexiones están bien hechas, y hacemos la lectura analógica de cada uno de los sensores del QTR-8A, podemos observar que obtenemos una lectura de 1023 cuando la superficie es absolutamente blanca, y obtenemos 0, cuando la superficie es absolutamente negra.
Joaquín Berrocal Piris 13
Ahora imaginemos que estamos utilizando los 8 sensores de luz infrarroja disponibles en la matriz, y que cada una de las salidas de los sensores, las tenemos conectadas desde el pin analógico 0 hasta el pin analógico 7, y nos arrojará lecturas como las que vemos a continuación:
Como podemos observar, las mediciones sobre el blanco nos dan 1023, y las que están “en el umbral entre el blanco y el negro”, nos dan un valor entre 0 y 1023, dependiendo del nivel de reflectancia. Luego, si graficamos estos valores, podremos observar lo siguiente:
Joaquín Berrocal Piris 14
Con esto, podemos intuir que la línea negra está entre el sensor 4 y el sensor 5, pero debemos obtener el valor exacto de la posición de la línea, y para eso, haremos una transformación a los datos, para obtener lo que buscamos. A los valores obtenidos, les cambiaremos el rango, de 0 a 1023, a 0 a 1000; Y además, le cambiaremos los daremos vuelta. Es decir, lo que antes era 1000, ahora será 0, y lo que antes era 0, ahora será 1000, y obtendremos el siguiente gráfico.
Ahora, podemos observar gráficamente en qué sensores se concentra mayormente la línea negra. Joaquín Berrocal Piris 15
Pero nosotros necesitamos el dato exacto, y para poder obtener ese dato, podemos utilizar 2 métodos: • •
Estimación de la posición a través de interpolación cuadrática Estimación de la posición a través del promedio ponderado Luego de probar con ambas, nos dimos cuenta que el resultado es idéntico. No hay diferencia ni velocidad ni en la precisión. Así que enseñaremos el más sencillo: El promedio ponderado: El promedio ponderado se calcula así:
Probando esta fórmula con el ejemplo anterior, no da lo siguiente:
Esta fórmula nos devuelve un valor entre 0 y 7000, donde 0 significa que el sensor está en el extremo izquierdo, y 7000 significa que está en el extremo derecho. Pero en este ejemplo nos dice que está en la posición 3587.
Joaquín Berrocal Piris 16
Bien, ahora que ya encontramos nuestra posición actual (que es x = 3587) debemos aplicar el algoritmo matemático que nos ayudará a controlar los motores, a partir del error respecto a la posición ideal.
Si la posición del sensor respecto a la línea debe estar entre 0 y 7000, obviamente, la posición ideal será de 3500, a esa posición ideal, le llamaremos Setpoint. (Setpoint = 3500), y como habíamos dicho antes, le llamaremos “Error”, a la distancia entre la lectura actual, y la posición ideal del robot. (Posición Actual = 3587). Error = Posición Actual – Setpoint Error = 3587 – 3500 Error = 87
Ahora que sabemos qué tan alejado estamos de la posición ideal, aplicaremos un algoritmo matemático para energizar a los motores para éstos siempre se acomoden a la posición ideal. Este algoritmo se llama “Proporcional, Integral, Derivativo” (más conocido como PID). ( No se asusten con el nombre, la verdad es que es muy sencillo. No es necesario ser un experto matemático para aplicarlo.) Copiamos el código, para que lo apliques, lo mejores y lo comentes!
#include <QTRSensors.h> //Mapeo de pines #define STBY 9 #define AIN1 3 #define AIN2 4 #define PWMB 5 #define PWMA 6 Joaquín Berrocal Piris 17
#define BIN1 8 #define BIN2 7 #define NUM_SENSORS
6
#define NUM_SAMPLES_PER_SENSOR 4 #define EMITTER_PIN #define LED
11
13
// Constantes para PID float KP = 0.01; float KD = 1.0; float Ki = 0.006; // Regulación de la velocidad Máxima int Velmax = 80;
// Data para integral int error1=0; int error2=0; int error3=0; int error4=0; int error5=0; int error6=0;
// Configuración de la librería QTR-8A QTRSensorsAnalog qtra((unsigned char[]) {A0, A1, A2, A3, A4, A5} , NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN); unsigned int sensorValues[NUM_SENSORS];
// Función accionamiento motor izquierdo Joaquín Berrocal Piris 18
void Motoriz(int value) { if ( value >= 0 ) { digitalWrite(BIN1,HIGH); digitalWrite(BIN2,LOW); } else { digitalWrite(BIN1,LOW); digitalWrite(BIN2,HIGH); value *= -1; (PWMB,value);
// Lo positiviza para evitar error en el próximo: analogWrite
} analogWrite(PWMB,value); } // Función accionamiento motor derecho void Motorde(int value) { if ( value >= 0 ) { digitalWrite(AIN1,HIGH); digitalWrite(AIN2,LOW); } else { digitalWrite(AIN1,LOW); digitalWrite(AIN2,HIGH);
Joaquín Berrocal Piris 19
value *= -1; (PWMB,value);
// Lo positiviza para evitar error en el próximo: analogWrite
} analogWrite(PWMA,value); } //Accionamiento de motores void Motor(int left, int righ) { digitalWrite(STBY,HIGH); Motoriz(left); Motorde(righ); } //función de freno void freno(boolean left, boolean righ, int value) { digitalWrite(STBY,HIGH); if ( left ) { digitalWrite(BIN1,HIGH); digitalWrite(BIN2,HIGH); analogWrite (PWMB, value); } if ( righ ) { digitalWrite(AIN1,HIGH); digitalWrite(AIN2,HIGH); analogWrite (PWMA, value); } } Joaquín Berrocal Piris 20
void setup() { // Declaramos como salida los pines utilizados pinMode(LED ,OUTPUT); pinMode(BIN2 ,OUTPUT); pinMode(STBY ,OUTPUT); pinMode(BIN1 ,OUTPUT); pinMode(PWMB ,OUTPUT); pinMode(AIN1 ,OUTPUT); pinMode(AIN2 ,OUTPUT); pinMode(PWMA ,OUTPUT); // Calibramos con la función qtra.calibrate();, y dejamos parpadeando el led, mientras se produce la calibración. for ( int i=0; i<70; i++) { digitalWrite(LED, HIGH); delay(20); qtra.calibrate(); digitalWrite(LED, LOW); delay(20); } delay(3000); } unsigned int position = 0; //declaraos variables para utilizar PID int proporcional = 0; int integral = 0; int derivativo = 0;
// Proporcional //Integral // Derivativo
int diferencial = 0; // Diferencia aplicada a los motores int last_prop; del error)
// Última valor del proporcional (utilizado para calcular la derivada
Joaquín Berrocal Piris 21
int Target = 2500; // Setpoint (Como utilizamos 6 sensores, la lĂnea debe estar entre 0 y 5000, por lo que el ideal es que estĂŠ en 2500) void loop() { position = qtra.readLine(sensorValues, true, true); proporcional = ((int)position) - 2500; if ( proporcional <= -Target ) { Motorde(0); freno(true,false,255); } else if ( proporcional >= Target ) { Motoriz(0); freno(false,true,255); } derivativo = proporcional - last_prop; integral = error1+error2+error3+error4+error5+error6; last_prop = proporcional; error6=error5; error5=error4; error4=error3; error3=error2; error2=error1; error1=proporcional; int diferencial = ( proporcional * KP ) + ( derivativo * KD )+ (integral*Ki) ; if ( diferencial > Velmax ) diferencial = Velmax; else if ( diferencial < -Velmax ) diferencial = -Velmax; ( diferencial < 0 ) ? JoaquĂn Berrocal Piris 22
Motor(Velmax+diferencial, Velmax) : Motor(Velmax, Velmax-diferencial); }
Mecánica http://lamborghino.cl/mecanica/ El secreto de lamborghino, es que está diseñado por ingenieros mecánicos. Si bien es cierto que la electrónica es fundamental el desarrollo de los seguidores de línea, una vez “solucionado” el tema electrónico, la velocidad y la precisión de nuestro seguidor de líneas dependerá casi exclusivamente de la mecánica. Cuando diseñamos el robot, nos planteamos 2 principios de diseño: 1. El robot debe pesar lo menos posible. 2. Debemos disminuir la inercia. Cuando comenzamos a seleccionar las piezas que utilizaríamos para armar nuestro seguidor de líneas, optamos por las ruedas vendidas por Pololu, Solarbotics RW2 Wheel. Nuestra primera impresión fue que eran perfectas para nuestro seguidor de línea. El ancho de las ruedas, el agarre aparente y todo se veía perfecto. Además estas ruedas las vendían de a una… eso nos hablaba de la calidad de las ruedas. además la descripción de las ruedas era así: The Solarbotics RW2 rubber wheel has a black, anodized aluminum hub with a generously thick rubber tire for maximum traction (great for minisumo robots or fast line-following robots that need traction when rounding corners). Así que decidimos comprarlas.
Aprovechando la compra en el extranjero, compramos una ruedas mucho menos sofisticadas, con nombre Wheel 32×7mm Pair. La verdad es que estas ruedas las compramos como una alternativa poco probable, ya que según nuestra apuesta, las solarbotics deberían ser infinitamente mejores. Pero como somos ingenieros, hicimos las pruebas para saber cuáles eran las mejores ruedas para nuestro seguidor de línea. Así que construimos una pista de aproximadamente 16 metros lineales. (con curvas y todo). Primero probamos con las ruedas solarbotics, y el robot se demoró aproximadamente 20 segundos en promedio, en dar una vuelta completa. Luego probamos con las ruedas estándar de 32×7 mm, y el robot se demoró 12 segundos. Así que
Tamaño de la pista [m]
15,9
Diámetro
Peso [gr]
tiempo/vuelta [s]
V prom [m/s]
Solarbotics
31,2
12,2
20,1
0,79
Ruedas 32×7
32
3,2
11,58
1,37
Joaquín Berrocal Piris 23
haciendo una pequeña tabla podemos observar lo siguiente: La conclusión inmediata que se nos viene a la mente, es que con las rudas de 32×7 mm casi duplicamos la velocidad promedio que con las ruedas “súper sofisticadas solarbotics”. ¿Pero por qué?, la respuesta es “EL PESO”. Como ya habíamos dicho en un principio, el peso de nuestros robots es una de las variables que más influyen en la velocidad de este; y haciendo una observación de cómo afecta esta variable, podemos ver que tan solo la disminución de 9 gramos en cada rueda, hizo que el robot casi duplicara su velocidad promedio. En conclusión, el peso es la variable más importante. A las velocidades y los pesos a los que frecuenta nuestro robor, la variable del “agarre”, no es tan influyente como la variable del peso. Cuando nuestro robot supera los 3 metros por segundo, y está sometido a aceleraciones “muy bruscas”, ahí recién, la variable del agarre de las ruedas, pasa a a ser una variable de igual importancia que el peso. Luego de comprender la importancia del peso en nuestro seguidor de líneas, rediseñamos todo, pensando en disminuir el peso a su mínima expresión. Así que nos hicimos un chasis de cartón Foam, con una figura “velocista”. En realidad la forma del robot puede ser cualquiera, pero tienen que cumplirse la siguiente característica. •
La separación entre las ruedas debe ser de aproximadamente 14 centímetros • La separación entre el eje de las ruedas y los sensores, debe ser de aproximadamente 12 centímetros Es decir, debe quedar como en este diagrama:
Otra variable importante al momento de construir nuestro seguidor de líneas, es la Inercia. Mientras más alejado del centro de giro se encuentre el peso, mayor dificultad tendrá nuestro robot para girar, por lo tanto, debemos procurar que la mayor parte del peso, se encuentre en el centro de giro, es decir, entremedio de los dos motores. Por lo tanto, la batería y los componentes electrónicos más pesados, deberán ir lo más centrados respecto al eje de giro. El pivote: Ya que nuestro robot posee solo dos ruedas, deberemos agregarle un tercer punto de apoyo para que los sensores no toquen el piso, y se mantengan siempre a la misma altura. Para eso tenemos 2 soluciones, igual de prácticas y con resultados muy similares. La primera, es comprar una bola rodante, que vende Pololu. Joaquín Berrocal Piris 24
Es muy cómodo, pero con el tiempo se ensucia y pierde movilidad. además, tendremos que perforar nuestro robot para poder utilizarlo. La otra opción, la vimos en internet, que es utilizar luces led de 3mm… Sí… tal como de escucha… Utilizar un led de 3mm como pivote. Si nos preguntan cuál es el mejor lugar para ubicar el pivote, les decimos que deben probarlo ustedes. no obstante, deben considerar que mientras más alejado del centro de giro, provocará una mayor inercia. Por otro lado, mientras más cerca esté el pivote del centro de giro, la estabilidad de los sensores va a empeorar.
Electrónica http://lamborghino.cl/electronica/ Lamborghino es básicamente un vehículo eléctrico autónomo, y como todo vehículo, éste debe generar su movimiento a través de actuadores electromecánicos, en este caso, serán motores eléctricos. Así que primero que todo, deberemos definir el microcontrolador que utilizaremos. Como Lamborghino es un proyecto “Mecatrónico”, al momento de fabricarlo, procuramos no abusar de los límites entre las áreas de la electrónica y la mecánica, de tal manera que decidimos trabajar con un procesador que fuese capaz de programarlo cualquier integrante del grupo, y no solo el ingeniero electrónico. Por esta razón, decidimos trabajar con la plataforma de Arduino. En este caso, utilizamos un Arduino Nano (ATmega 328, 16Mhz.)
Con Arduino Nano Posee: • •
8 Entradas Analógicas 14 Entradas y salidas digitales (6 con PWM)
Suficiente para hacer nuestro seguidor de líneas.
Joaquín Berrocal Piris 25
Además nuestro robot deberá ser capas de seguir el camino trazado, (que será una línea blanca sobre una superficie negra, o una linea negra sobre una superficie blanca)por lo que necesitaremos utilizar entonces, un “sensor de línea”. Tenemos una buena y una mala noticia respecto a esto. La mala es que los sensores de línea no existen…, la buena es que podemos hacernos uno utilizando sensores y emisores de luz infrarroja. ¿Por qué?, lo veremos con el siguiente diagrama.
Como podemos ver en la imagen, si emitimos luz infrarroja sobre una superficie blanca, entonces la luz revotará y la recibirá el sensor. Ahora bien, si emitimos luz infrarroja sobre una superficie negra, la luz no rebotará. De esta forma podremos saber si nuestros sensores están sobre el camino, o si no. Dentro de una amplia gama de sensores de luz infrarroja, los más utilizados son los siguientes: Emisor y receptor de Luz infrarroja, formato led 3mm.
Joaquín Berrocal Piris 26
Pack de emisor y receptor de montaje de orificio pasante. (Por ejemplo CNY70)
Pack de emisor y receptor de montaje superficial. (Por ejemplo QRE1113GR)
En nuestra experiencia, la forma más fácil y eficiente para hacer un seguidor de líneas velocista es utilizando las matrices de sensores, prefabricadas, como el módulo QTR8A de pololu.
Joaquín Berrocal Piris 27
Su implementación es muy sencilla, gracias a la facilidad de conexión. (en nuestra opinión, utilizar este módulo es un ahorro de tiempo y de dinero). Nota: Existen dos tipos de QTR8, Están los Análogos (QTR-8A) y los digitales (QTR-(8RC), Pueden ver la diferencia en la página del fabricante, pero en nuestro caso, por comodidad, preferimos utilizar los QTR-8A. Como podemos observar, esta matriz posee 8 sensores, pero luego de varias pruebas, hemos llegado a la conclusión de que con una buena programación del algoritmo, podemos trabajar perfectamente con 6 sensores. Disminuyendo así, a solo 9 las conexiones necesarias. 1. 2. 3. 4. 5. 6. 7. 8. 9.
Salida sensor 1 Salida sensor 2 Salida sensor 3 Salida sensor 4 Salida sensor 5 Salida sensor 6 LEDON VCC GND
El pin LEDON sirve como un STANDBY de los emisores de luz infrarroja, por lo tanto, si el LEDON recibe un “HIGH”, entonces prende los emisores de luz infrarroja, y si recibe un “LOW”, los apaga. Esto sirve para ajustar la luminosidad que queremos utilizar (usando PWM), o para ahorrar energía, utilizando los emisores, sólo cuando sea necesario. Las salidas de los sensores, las conectaremos a las entradas analógicas del microcontrolador, el pin LEDON lo conectaremos a una salida digital, y la alimentación VCC y GND la suministraremos de la que nos puede dar Arduino. OJO: Muchos nos dirán que esto último no se debe hacer, y tienen razón, ya que arduino solo puede suministrar hasta un máximo de 40mA, y el QTR-8A necesita aproximadamente 100 mA… Pero bueno, nuestro robot funciona así, y nunca ha fallado, ni quemado, ni nada. Si no confían, pueden utilizar un regulador de voltaje (LM7805, pero a nosotros nos da pereza hacer esa conexión jajajaja). Otro de los dispositivos fundamentales para nuestro seguidor de líneas, será el Driver, para energizar y controlar nuestros motores. Para los que no sean “Electrónicos”, explicaré por qué el driver cumple una función primordial para poder controlar los motores. Como sabemos, Los motores de corriente continua poseen 2 cables, y estos exigen un cierto voltaje y una cierta Joaquín Berrocal Piris 28
corriente. La mayoría de las veces, tanto el voltaje como la corriente que necesitan, sobrepasa la que puede suministrarle el Arduino. Entonces, con el driver podremos energizar externamente nuestros motores y controlarlos con Arduino…. Para eso sirve el driver. Luego de probar un sin fin de Drivers, hemos llegado a la conclusión de que la mejor opción es utilizar el Toshiba TB6612FNG, Como dato anecdótico, podemos contar que este Driver viene incorporado en los discos duros SATA de marca TOSHIBA, por lo tanto su fidelidad es tremenda.
Luego de probar un sin fin de Drivers, hemos llegado a la conclusión de que la mejor opción es utilizar el Toshiba TB6612FNG, Como dato anecdótico, podemos contar que este Driver viene incorporado en los discos duros SATA de marca TOSHIBA, por lo tanto su fidelidad es tremenda
Además, este driver puede aguantarnos corrientes permanentes de 1.2 A por canal y un peak de 3.2 amperes por canal, además con este driver lo podemos utilizar para generar un freno en los motores por inducción electromagnética.
en julio 2017 en aliexpress 10uds = 9€ Los pines de este driver son los siguientes:
1. PWMA –> Entrada de señal PWM para motor A 2. AIN2 –> Control de dirección para motor A (Horario o Anti-horario) 3. AIN1 –> Control de dirección para motor A (Horario o Anti-horario) 4. STBY –> Standby motores, ( si recibe un LOW, los motores se desconectan) 5. BIN1 –> Control de dirección para motor B (Horario o Anti-horario) 6. BIN2 –> Control de dirección para motor B (Horario o Anti-horario) 7. PWMB –>Entrada de señal PWM para motor B 8. GND –> Tierra 9. GND –> Tierra 10. B01 –> Salida para motor B 11. B02 –> Salida para motor B 12. A02 –> Salida para motor A 13. A01 –> Salida para motor A 14. GND –> Tierra 15. Vcc –> Alimentación del driver (2,7 – 5,5V) 16. Vin –> Alimentación de los motores (15V máx.)
Joaquín Berrocal Piris 29
Por ejemplo, si tiramos un LOW al AIN1 y un LOW al AIN2, y un HIGH al PWMA y al STANDBY, provocaremos una frenada brusca en los motores.
Bueno, finalmente, pero no menos importante, hablaremos sobre la alimentación del robot. Queremos ser tajantes desde un principio, LAS PILAS AA o AAAo todas esas que se
utilizan en las radios NO SIRVEN!!. En primer lugar, no sirven porque son una aberración mecánica. Cada una de estas pilas, pesa lo mismo que nuestro robot, y lo que no queremos hacer, es aumentarle el peso. Además, tenemos que pensar que necesitamos suministrar más de 4 amperes en el peak al robot. Esto ocurre porque cada motor consume en el peak, 1.6 amperes, más un factor de seguridad, necesitaríamos por lo menos una fuente de energía que pueda aguantarnos 4 amperes. Para eso utilizaremos baterías de litio… PERO NO CUALQUIER BATERÍA DE LITIO!!. dentro de las baterías de litio más comunes, podemos encontrar las baterías de Litio – Ion (que son las que utilizan los smartphones o tablets) y las baterías de Litio – Polímero (Li-po). que son las que utilizan en aeromodelismo o cosas así. También queremos ser categóricos en esto… LAS BATERÍAS DE LITIO – ION NO SIRVEN!! SÓLO SIRVEN LAS BATERÍAS DE LITIO – POLÍMERO! Ahora que ya sabemos qué batería son las que nos sirven, aprenderemos a cómo elegirlas: Las baterías de litio – polímero tienen siglas para entender sus especificaciones. Ejemplo:
Joaquín Berrocal Piris 30
Esta batería dice que es 2S, significa que posee 2 celdas en serie. Si dijera 6s, significaría que posee 6 celdas en serie. Cada celda genera 3,7 V, por lo tanto, si tiene 2 celdas en serie, generaría 7,4 volts. Para saber cuánto es lo máximo que puede suministrarnos una batería de litio polímero, debemos fijarnos en la letra “C”. La letra C, nos indica la tasa de descarga de nuestra batería. Es decir, si la batería es de 200 mAh y 30C, Entonces nos podrá suministrar hasta 30*200mAh, es decir hasta 6 amperes!. En fin, las baterías son todo un mundo, y si quieren saber más acerca de las baterías, pueden ver este link. Ahora que ya sabemos todas las partes electrónicas que necesitamos, procederemos a describir las conexiones entre los elementos. Mostraremos las conexiones por separado, para que sea más fácil el entendimiento: La conexión entre la batería, el driver y arduino es la siguiente: • • • • • • • • • • • • • • • • • • • • • • •
D0 (Reservado para puerto serial) D1 (Reservado para puerto serial) D2 – Libre disposición D3 – Driver: AIN1 D4 – Driver: AIN2 D5 – Driver: PWM A D6 – Driver: PWM B D7 – Driver: BIN2 D8 – Driver: BIN1 D9 – Driver: STANDBY D10 – Libre disposición D11 – QTR-8A: LEDON “quizás deba conectarlo con el pin IR de mi módulo sensor” D12 – Libre disposición D13 – Reservado para utilizar led incorporado en arduino A0 – QTR-8A: 1 A1 – QTR-8A: 2 A2 – QTR-8A: 3 A3 – QTR-8A: 4 A4 – QTR-8A: 5 A5 – QTR-8A: 6 GND – Driver: GND, QTR-8A GND, Batería: GND VIN – Batería: 7,4V 5V – Driver: Vcc, QTR-8A: VCC
Joaquín Berrocal Piris 31
OJO: El pin VM del Driver debe ir conectado a la batería: 7,4 Volt.
La conexión entre arduino y el módulo QRT-8A será la siguiente:
---------------------------------------------------- 0 ----------------------------------
+ Más sobre el sensor QTRSensor y hay mas datos con otros archivos informativos: Joaquín Berrocal Piris 32
Materiales resumen: Micro Metal Gearmotor (motores con reductora de la casa Pololu)
He aquí el dilema , Que tipo de motor utilizar?. Pues si tienes un robot que te va a salir un poco pesado, es decir que este por 200 a 400 gramos, que es mucho para un robot velocista de competencia, pues puedes utilizar los motores 30:1. Pero en cambio si tienes un robot liviano de unos 100 gramos, pues puedes utilizar uno de reducción 10:1. NOTA: el mío (Joaquín) pesa 385grs com 6 pilas de 1.5V y cierto es que va bien con 30:1 con rueda de 32mmx7mm Lo anterior fue una parte de lo que debemos tener en cuenta para el motor del robot, Ahora está el consumo de los motores. Pololu, empresa de venta de articulos para robotica, posee 3 tipos de motores, están los de consumo: High Power o HP, Medium Power MP y los Low Power LP.
Los HP tienen consumos de corriente de 120mA libre a 1600 mA en paro obteniendo mayores revoluciones por minuto 10:1 -> 3000 rpm, 30:1 -> 1000 rpm. Los MP tienen consumos de 40mA libre a 700mA en paro obteniendo revoluciones relativamente altas 10:1 -> 2200 rpm, 30:1 -> 730 rpm Los LP tienen consumos de 40mA libre a 360mA en paro obteniendo revoluciones bajas pero a menor consumo 10:1 -> 1300 rpm, 30:1 -> 440 rpm En el caso de mi robot , utilizo motores 10:1 MP 2200 rpm , elegí estos tienen revoluciones altas y el consumo del motor no es tan alto por lo que no tengo problemas con el agotamiento de baterías.
-> Driver de motor Hasta la fecha no existe un microcontrolador que sea capas de entregar mas de 100mA, por lo que el driver de motor seguirá siendo una opción obligatoria. Los driver que se pueden utilizar son los siguientes: Joaquín Berrocal Piris 33
TB6612FNG. Este driver posee 2 canales (para dos motores) es capaz de entregar 1 amperio continuo de corriente y 3 A pico por canal. soporta hasta los 13 Voltios y va bien con los motores HP. En embajadores Madrid dice : 1.2A y picos de 3.2A
DRV8833. Este driver es de 2 canales y entrega una corriente de 1.2 A continuos y 2 A pico por cada canal soporta hasta 10.8 Voltios y es el que yo utilizo:3, este driver es simple de utilizar, cuenta con los pines necesarios para el control de cada motor, a un pin lo puedes usar para dar para el sentido de giro al motor y al otro para el pwm, cumple su proposito muy bien, lo utilizo para motores MP.
La recomendación que puedo dar aquí es que para tener un mejor control de los motores, es mejor utilizar una configuración inversa de pwm para el control del motor ....... investiguen :D
->Baterias
Joaquín Berrocal Piris 34
Las baterias de lipo son siempre la mejor opción, lo recomendable es que sean de 7.4 voltios, ya que nuestros micromotores funcionan a ese voltaje. Un aspecto importante también es la capacidad A/h (amperios hora que es capas de entregar la bateria antes de agotarse), Yo me tome la molestia de medir la corriente que consume en funcionamiento el circuito de control del robot (arduino, sensores, leds, etc) y estos consumen alrededor de 100 mA- 150 mA y los motores con carga consumes 200 mA- 400 mA ( es decir si promediamos el consumo del robot en funcionamiento normal, este estaría cosumiendo algo mas de 400 mA, por lo que lo ideal sería contar con una batería que suministre al menos una hora de funcionamiento. Este seria el caso de una bateria de 500mAh. Como nuestro robot consume alrededor de 400 mAh, esta batería nos brindara un poco mas de una hora de funcionamiento antes de que este completamente descargada. Pero por supuesto siempre está la opción de comprar una batería que tenga mayor capacidad como los de 1000mA y los de 1500mAh, pero sabemos que a mayor capacidad, mayor tamaño y peso, produciendo un mayor consumo de los motores, por lo tanto siempre hay q buscar un equilibrio + Condensadores en los motores: Una las soluciones mas baratas que hay es simplemente poner un capacitores de "tantalio" de codigo 104 (0,1uF) y 103 (0.01 uF) en paralelo con la alimentación, http://aprendiendofacilelectronica.blogspot.com.es/2014/12/robot-velocista-decompetencia.html http://aprendiendofacilelectronica.blogspot.com.es/2016/11/robot-velocista-qtr8a-parte-ii.html Continuación http://aprendiendofacilelectronica.blogspot.com.es/2016/11/robot-velocista-qtr8aparte-iii.html
-------------------------------- 0 ----------------------
Joaquín Berrocal Piris 35
Zinc– carbono
Alcalina
Li-FeS2
NiCd
NiMH
Designación IEC
R6
LR6
FR6
KR6
HR6
Designación ANSI/NEDA
15D
15A
15LF
1.2K2
1.2H2
Capacidad típica
1100 mAh
2700– 2900 mAh
3000 mAh
500– 1100 mAh
1500– 2900 mAh
Tensión nominal
1,5 V
1,5 V
1,55 V
1,25 V
1,25 V
+ Las pilas de 1.5V alcalinas pesan 25.6grs (Pila cilíndrica alcalina LR6 / AA - 1,5V) + 6 pilas x 25.6grs= 153,6grs . la capacitad total > 16200mah + Las batería LIPO de 7.4V (2S o 2 celdas) + La que he comprado yo : 7.4V 30C 4200mah pesa 260grs + Batería Lipo de 7.4V Capacidad: 2000 mAh Celdas: 2S 25C Peso neto: 100 gr + Batería Lipo de 7.4V Capacidad: 1200 mAh Celdas: 2S 25C Peso neto: 70 gr + Batería Lipo de 7.4V Capacidad: 900 mAh Celdas: 2S 25C Peso neto: 45 gr + Una de 11,1V (3S -15C -5200maH) pesa 365grs + Mi power Bank (PowerAdd) es de Li-ion de 5V / 5000mAh 18.5W output 5V/2.1A y pesa 122grs
++++ BATERIAS LIPO CARACTERISTICAS INTERESANTES+++ http://blogturbohobby.blogspot.com.es/2013/05/bateriaslipo.html las baterías de Lipo están formadas por elementos de 3.7v. Para saber el voltaje de una batería solo tenemos que multiplicar el número de elementos por el voltaje de este, ya que se conectan en serie (2S por ejemplo). Es decir que una batería de 2 elementos tendría el voltaje de 7.4v (3.7v x 2 elementos = 7.4v) las letras KW. Si multiplicas el número por el voltaje de tu batería el resultado son las vueltas por minuto de tu motor. Por ejemplo, si tu coche rc lleva un motor brushless que saca 3500KV y le has montado una batería de 7.4v las revoluciones totales por minuto serán, 25.900RPM. Ahora bien, si en este mismo coche resulta que tu variador admite un voltaje de hasta 14v. por ejemplo y le montas una batería de 11.1v tendrías la friolera de 38.850RPM (una pasada!!!) y sin aumentar apenas el peso de la batería... Por otro lado las Lipos a parte de la especificación de los miliamperios de la batería, también se detalla una referencia de descarga máxima que viene expresada con un número seguido de una ‘C’ (25C), donde C es el amperaje de la batería. Para saber que amperaje descarga nuestra batería tenemos que multiplicar los miliamperios de esta por el número delante de la C. Por ejemplo, si tenemos una batería de 4.000Mha y 30C, la descarga máxima a la que podemos someter esta batería sería 120.000Mha (120A). Es decir que la podemos montar en un modelo RC que consuma como máximo 100 o 110A ya que siempre es necesario dejar un margen por si se produce algo que no tengamos controlado. En algunas batería de Lipo, aparecen una referencia de descarga indicada por dos valores 20C-30C, esto nos indica que el fabricante está diciendo que la batería se puede descargar a 20C de manera continuada y que la batería podría darnos hasta 30C por un tiempo limitado, unos segundos Mantenimiento de la Batería 1 Compruebe la tensión (voltaje) por celda tras la primera carga, conforme a la siguiente tabla: nota cada celda da 3.7V si tiene 2 celdas dará 7.4V como valor nomial. Joaquín Berrocal Piris 36
1 celda 4.2V (4.15 a 4.22) 2 celdas 8.4V (8.32 a 8.44) --Nota la q yo he comprado al llegar tenía 7,8V y al cargarla 8.37V 3 celdas 12.6V (12.48 a 12.66) 4 celdas 16.8V (16.64 a 16.88) 5 celdas 18.5V (18.30 a 18.60) 2. No descargue la batería por debajo de 3V por celda. Una descarga profunda, por de bajo de 3V puede deteriorar el rendimiento de la batería.
----------------tabla de características de baterías de LI-POLY ----------------Compro el 3-7-2017 la de 7,4V 4200Mah 30C peso 215grs
Joaquín Berrocal Piris 37
JoaquĂn Berrocal Piris 38
Tabla de referencia Motorcillos con engranajes metálicos N20 stall actual
Ratio reductor
DCV
velocidad sin carga rpm/min
Parámetro del ENGRANAJE-JA12 n20 velocidad de corriente par nominal par máximo carga nominal rpm/min kg. cm ma kg. cm
ma
1:00
3
750
500
0.02
80
0.3
100
10
3
250
200
0.07
80
0.56
100
30
3
150
120
0.1
80
0.8
100
50
3
75
60
0.15
80
1.2
100
100
3
50
40
0.2
60
1.6
100
150
3
37
30
0.25
60
2
100
200
3
25
20
0.5
60
4
100
298
3
19
13
0.5
60
4
100
380
6
1500
1000
0.05
160
0.3
100
10
6
500
400
0.15
160
1.2
100
30
6
300
240
0.2
160
1.6
100
50
6
150
120
0.3
160
2.4
200
100
6
100
80
0.4
160
3.2
200
150
6
74
70
0.6
120
3.2
200
200
6
50
40
1.5
120
10
200
298
6
39
40
1.5
120
10
300
380
12
3000
2000
0.08
200
0.8
300
10
12
1000
800
0.3
200
2.4
300
30
12
600
480
0.4
200
3.2
300
50
12
300
240
0.6
200
4
300
100
12
200
160
1
200
7
300
150
12
148
118
1.5
150
9
300
200
12
100
80
2
150
16
300
298
12
78
80
2
150
16
300
380
tensión
---------------- CONVERTIDORES DE TENSIÓN Step Up / Step Down---------------------Lo puedo utilizar para utilizar 4 baterías de 1.5V = 6V para alimentar a la placa arduino y los motores por ejemplo a < 6 A 12Voltios. Con lo que podré activar los motores sin problemas. Regulador de voltaje DC-DC Step Up 4V a 35V Módulo Step Up basado en el integrado XL6009E1, permite elevar el voltaje de entrada hacia una salida regulable entre 1.25 y 35 Vdc con una corriente máxima de 4A (se sugiere utilizar disipador).
Joaquín Berrocal Piris 39
El módulo incluye el circuito integrado XL6009E1 que corresponde a una tecnología de conmutación de alta frecuencia, eficiencia de un 96% y bajo rizado. La salida es ajustable mediante el potenciómetro. Características: • • • • • • • •
Voltaje de entrada: 3V a 32V (se recomienda un mínimo de 5V) Voltaje de salida: 4-35V regulable Intensidad máxima de entrada: 4A Intensidad máxima de salida: 4A Eficiencia aproximada: 96% Frecuencia de trabajo: 400KHz Temperatura trabajo: -40º a +85ºC Dimensiones: 43 x 21 x 14 (mm) Ejemplo de rendimiento para una salida deseada de 12V:
• • •
Si entrada es 3V, 1,6A (5W) se obtiene una salida de 12V, 0.4A (4.8W) Si entrada es 5V, 2A (10W) se obtiene una salida de 12V, 0.8A (9.6W) Si entrada es 7.4V, 2,53A (18,75W) se obtiene una salida de 12V, 1.5A (18W)
-------- Este otro la entrada dice que debe ser superior 1.5V a la salida------A estos se les llama Step Down necesitan 1.5V por encima de la salida Regulador de Voltaje DC-DC 1.3V a 37V LM2596 con Voltímetro Módulo que permite la regulación del voltaje de salida (según la entrada) entre 1.3 y 37 Vdc, y corriente máxima de 2 A. Mediante su display es posible visualizar el voltaje de entrada o voltaje de salida. Se debe asegurar que el voltaje de entrada sea al menos de 4 V y mínimo 1.5 V por encima de la salida deseada. Características: Resolución ± 1 V Rango tensión de entrada: 4 - 40 Vdc Tensión de salida ajustable: 1.3 - 37 Vdc Corriente de salida: 2 A Voltímetro digital con displays de 7 segmentos, rango: 0 - 40 Vdc Pulsadores para elegir visualizar voltaje de entrada o de salida Circuito integrado: LM2596
Joaquín Berrocal Piris 40
http://www.fpalzira.es/web/index.php/es-es/2015-05-21-16-45-34/61departamentos/electricidad-y-electronica/proyectos/robotica/tutorial-como-se-construye-unrobot ----------------------------------- OTROS MATERIALES ----------RUEDA ESPUMA - BANEBOTS http://www.todohobby.net/es/2798-ruedas-espuma https://www.fingertechrobotics.com/proddetail.php?prod=ft-minisumo-wheels-1125 Aquí habla de característica de las scaleauto de espuma http://bantuslot.com/blog/ruedas-con-neumatico-de-espuma-para-rallyslot-124/ Escala rueda 1:24 con diámetro inte de 3mm las hay de 17/19 y 21 mm DIRECCIÓN INTERESANTE CON PROGRAMACIÓN VELOCISTA http://aprender.tdrobotica.co/seguidor-de-lineaprofesional/ COMENTARIOS DE LOS CONSTRUCTORES DE VELOCISTAS https://www.youtube.com/watch?v=TAvCD_xx39c dirección con instrucciones y pista velocista http://www.pascualbravo.edu.co/virtual/index.php/90-expotecnologica/132-x-muestra-derobotica CATEGORÍA: SEGUIDOR DE LÍNEA VELOCISTA •
DEFINICIÓN:
La categoría Seguidor de Línea velocista, busca que los constructores diseñen robots que se adapten a las especificaciones de la prueba y que desarrollen estrategias de programación, adecuadas a la tarea El robot velocista tiene un punto específico de partida que a la vez es el de llegada. Su recorrido lo hace con el objetivo de realizar 3 vueltas. Características: Una vez iniciada la competencia el cronómetro no es detenido bajo ninguna circunstancia. • Pista: Esta se encuentra demarcada sobre una lámina plástica (PVC y poliéster) de color blanco mate de dimensiones 1.80 x 2.40 metros. El robot debe seguir la línea Joaquín Berrocal Piris 41
negra de 18 mm de ancho. Todas las medidas especificadas están sujetas a variaciones hasta ±2% debido a los cortes sobre el material. La pista estará iluminada de forma artificial o natural y las condiciones de luz pueden ser cambiantes, por lo cual no se garantiza la ausencia de sombras. Durante la competencia, existirán equipos de filmación y cámaras fotográficas que podrán generar rayos infrarrojos por sus sistemas de auto foco. Por lo tanto, los robots deben estar preparados para que las condiciones de luz cambiante no los afecten.
------------------- MÁS INFORMACIÓN alguna ya está comentada anteriormente---------------https://www.pololu.com/product/1000 https://www.youtube.com/watch?v=ee-GuCBWyH4 descripción piezas micromotor reductor y ruedas pololu https://www.pololu.com/product/1000 Rueda direccional: 0,19 + gastos envio total 2,13€
CY-15A 5/8A inteligente casters coche pequeño maverick ojo redondo bola de acero omni rueda universal rueda caster wheel 1 unids
Joaquín Berrocal Piris 42
Ruedas traseras de 34 mm diámetro: 34 MM apertura: D-3mm 10 pzs 8,56€
10 unids 3PI miniQ N20 Micro Motor Mount Set 12mm DC Gear Motor Soporte De Montaje Accesorios Del Coche de Juguete F05101 10 pzs 4,71€ altura: 11mm ancho: 25mm Material: plástico de alta calidad cantidad: 10 set/lote Nota especial: sólo para HM N20 motor de serie --------------------------------------------------------------------------------------------2 Motores 6,48€
el paquete Incluye: 1 x Motor De Engranajes(12 V 100 RPM) Tamaño Del Eje de salida: 3*10mm (Tipo D)
Módulo de Módulo de Sensor de Detección de Infrarrojos DIY Para Arduino Módulo Sensor Hunt Módulo Detector de Infrarrojos de $ Number Canales de $ number bits 3,96€
Joaquín Berrocal Piris 43
http://www.zambeca.cl/tiendaOficial/index.php?route=product%2Fproduct&product_id= 398&search=qtr-8a
Especificaciones: • Dimensiones: 74,93 mm x 12,70 mm x 3,18 mm (2,95 "x 0,5" x 0,125") (sin conectores instalados) • Voltaje de funcionamiento: 3,3 a 5,0 V • Corriente de alimentación: 100 mA, aunque el del video dice que se puede conectar sin problemas a arduino • Formato de salida: 8 voltajes análogos • Rango de voltaje de salida: desde 0 V al voltaje suministrado • Distancia óptima de detección: 3 mm (0,125") • Distancia máxima de detección recomendada: 6 mm (0,25") • Peso sin conectores: 3,09 g (0,11 oz) Incluye: • 1 tira de terminales macho 1 x 25 pines, de 2,54 mm (0,1”) • 1 resistencia 100 Ohm. Documentos • Guía del usuario para el sensor QTR-8A. • Notas de aplicaciones de los sensores Pololu QTR • Guía del usuario: Librería Pololu AVR C/C++ • Librería Arduino para los sensores de reflectancia Pololu QTR Joaquín Berrocal Piris 44
• • •
Librería de comandos de referencia Pololu AVR Construcción de seguidores de líneas y laberintos de líneas Robot Zero: un rápido seguidor de líneas para principiantes
Etiquetas: Pololu, sensor reflectancia, seguidores de línea, QTR-8A
IR
D1
D2
D3
D4
D5
D6
D7
D8
+
IR
D1
D2
D3
D4
D5
D6
D7
D8
+
GND GND
https://www.pololu.com/docs/0J19/all
Gnd-IR-D1------------D8-VCC Gnd-IR-D1----------D8-VCC Información sobre el sensor SQR 8 A DE POLOLU https://www.pololu.com/docs/0J19/all
Biblioteca de Arduino para la reflectancia Sensores de Pololu QTR
También puede ver este documento como un PDF imprimible . 1. Introducción 2. Instalación Biblioteca 3. Métodos y QTRSensors Notas de uso 1. Introducción
QTR comparación de tamaño del sensor. Las agujas del reloj desde arriba a la izquierda: QTR-3RC, QTR-1RC, QTR-L-1RC, QTR-8RC. Joaquín Berrocal Piris 45
Los sensores de reflectancia Pololu QTR llevan pares de LED y el fototransistor de infrarrojo que pueden proporcionar mediciones analógicas de reflectancia IR, lo que los hace ideal para la detección de bordes de proximidad y aplicaciones de línea siguiente. Los módulos vienen como compacto, las unidades de un solo sensor ( QTR-1A y QTR-1RC ; QTR-L-1A y QTR-L1RC ), matrices de 3-sensor ( QTR-3A y QTR-3RC ), o como 8- matrices de sensores ( QTR8A y QTR-8RC ) que pueden estar opcionalmente dividida en una matriz de 2-sensor y una matriz de 6-sensor. Los módulos están disponibles en dos formatos de salida diferentes: la QTR-xA da salida a una tensión analógica entre 0 y Vcc que puede ser medido por un convertidor de analógico a digital (ADC), y las salidas de QTR-XRC requiere una E / S digital línea capaz de conducir la línea de salida de alta y luego midiendo el tiempo para la tensión de salida a la descomposición (que proporciona una medición analógica de la reflectancia).
sensor de reflectancia QTR-L1A diagrama esquemático.
sensor de reflectancia QTR-1A diagrama esquemático.
QTR-1RC y QTR-L-1RC sensor de reflectancia diagrama esquemático.
Por favor, vea las páginas de productos para obtener más información sobre cómo funcionan estos sensores. Este documento explica cómo instalar las bibliotecas de Arduino para los sensores de reflectancia Pololu QTR, y proporcionará bocetos de muestra, así como enlaces a documentación de la biblioteca. Las bibliotecas le dará todo lo necesario para interactuar con un conjunto de sensores de reflectancia QTR-8x o múltiples sensores de reflectancia QTR-1x, incluyendo funciones avanzadas como la calibración automática y, en el caso de detección de la línea, el cálculo de la posición de la línea. 2. Instalación Biblioteca Si está utilizando la versión 1.6.2 o posterior del software de Arduino , puede utilizar el gestor de bibliotecas para instalar esta biblioteca: En el IDE de Arduino, abra el menú “Boceto”, seleccione “Incluir biblioteca”, luego “Administrar bibliotecas ...”. 1. La búsqueda por “QTRSensors”. 2. Haga clic en la entrada QTRSensors en la lista. 3. Haga clic en “Instalar”. Si esto no funciona, puede instalar manualmente la biblioteca: 1. Descargar el archivo de notas último de GitHub y descomprimirlo. 2. Cambiar el nombre de la carpeta “qtr-sensores en Arduino-xxxx” a “QTRSensors”. 3. Arrastre la carpeta “QTRSensors” en el directorio “bibliotecas” dentro de su directorio de bocetos Arduino. Puede ver su ubicación bloc de dibujo, abra el menú “Archivo” y seleccionar Joaquín Berrocal Piris 46
“Preferencias” en el IDE de Arduino. Si no hay ya una carpeta “bibliotecas” en ese lugar, usted debe hacer la carpeta sí mismo. 4. Después de instalar la biblioteca, reiniciar el IDE Arduino. Ahora debería ser capaz de utilizar estas bibliotecas en sus bocetos al seleccionar Boceto> Importar Biblioteca> QTRSensors desde el IDE de Arduino (o simplemente escriba # include <QTRSensors.h> en la parte superior de su dibujo). Tenga en cuenta que puede que tenga que reiniciar el IDE Arduino antes de ver las nuevas bibliotecas. Una vez hecho esto, se puede crear un QTRSensorsAnalog objeto para sus sensores QTRXa y un QTRSensorsRC objeto para sus sensores QTR-XRC: ? 1 2 3 4 5 6
// create an object for three QTR-xA sensors on analog inputs 0, 2, and 6 QTRSensorsAnalog qtra((unsigned char[]) {0, 2, 6}, 3); // create an object for four QTR-xRC sensors on digital pins 0 and 9, and on analog // inputs 1 and 3 (which are being used as digital inputs 15 and 17 in this case) QTRSensorsRC qtrrc((unsigned char[]) {0, 9, 15, 17}, 4);
Esta biblioteca se encarga de las diferencias entre los sensores QTR-Xa y QTR-XRC internamente, que le proporciona una interfaz común para ambos sensores. La única diferencia externa está en los constructores, como se puede ver en el ejemplo de código anterior. El primer argumento del constructor QTRSensorsAnalog es una matriz de pines de entrada analógicas (0 - 7) mientras que el primer argumento del constructor QTRSensorsRC es una matriz de pines digitales (0 - 19). Tenga en cuenta que las entradas analógicas a 0 - 5 se pueden utilizar como pines digitales 14 - 19. Para más detalles, véase la sección 3 . La única otra diferencia es que puede experimentar en el tiempo que se tarda en leer los valores de los sensores. Los sensores QTR-XRC pueden ser leídas en paralelo, pero cada uno requiere la sincronización de un impulso que podría llegar a tardar hasta 3 m (se puede especificar el tiempo que la biblioteca debe vez este pulso antes de tiempo de espera y declarando el resultado completo negro) . Los sensores QTR-Xa utilizar el convertidor de analógico a digital (ADC) y por lo tanto deben ser leídos secuencialmente. Además, los resultados analógicas son producidos internamente promediando un número de muestras para cada sensor (se puede especificar el número de muestras a la media) para reducir el efecto del ruido en los resultados. Varios bocetos de ejemplo están disponibles para ayudarle a empezar. Para ver los bocetos ejemplo, abra el IDE Arduino y vaya a: Archivo> Ejemplos> QTRSensors Como primer paso, se recomienda utilizar QTRARawValuesExample (para sensores QTRXa)
o QTRRCRawValuesExample (para
los
sensores
QTR-XRC). Estos
ejemplos
simplemente imprimir las lecturas en bruto de los sensores para el monitor de serie, utilizando 9600 baudios. Una vez que se está trabajando, es posible que desee probar uno de los ejemplos más avanzados, QTRAExample o QTRRCExample , que incorporan la calibración y también estimar la posición de una línea. 3. QTRSensors Métodos y Notas de uso QTRSensor Referencia de comandos Las versiones anteriores de esta biblioteca fueron nombrados PololuQTRSensors , pero hemos cambiado a QTRSensors para diferenciarla de la biblioteca sensor de QTR en nuestro Arduino Bibliotecas para el orangután y el robot 3pi . Aparte de la biblioteca y Joaquín Berrocal Piris 47
nombre de clase cambios, la nueva biblioteca QTRSensors es funcionalmente idéntico a las versiones anteriores. Para los sensores QTR-Xa, tendrá que crear una instancia de un QTRSensorsAnalog objeto, y
para
los
sensores
QTR-XRC
tendrá
que
crear
una
instancia
de
un QTRSensorsRC objeto. Aparte de los constructores, estos dos objetos proporcionan los mismos métodos para la lectura de los valores del sensor (ambas clases se derivan de la misma clase base abstracta). La biblioteca proporciona acceso a los valores de los sensores primas, así como para funciones de alto nivel, incluyendo la calibración y alineación de seguimiento. Esta sección de la biblioteca define un objeto para cada uno de los dos tipos de sensores QTR, con el QTRSensorsAnalog clase destinado para su uso con sensores QTR-Xa y la QTRSensorsRCclase destinado para su uso con sensores QTR-XRC. Esta biblioteca se encarga de las diferencias entre los sensores QTR-Xa y QTR-XRC internamente, que le proporciona una interfaz común para ambos sensores. La única diferencia externa está en los constructores. Esto se consigue por tener tanto de estas clases se derivan de la clase base abstracta QTRSensors . Esta clase base no se pueden crear instancias. Las clases QTRSensorsAnalog y QTRSensorsRC deben crearse instancias antes de ser utilizados. Esto permite que múltiples matrices de sensores QTR para ser controlados de forma independiente como objetos QTRSensors separadas. Para la calibración, se asigna memoria mediante el malloc () de comandos. Esto conserva la memoria RAM: si los ocho sensores se calibran con los emisores de ambos en un off, un total de 64 bytes estaría destinada a almacenar los valores de calibración. Sin embargo, para una aplicación donde sólo se utilizan tres sensores, y los emisores están siempre en durante lee, sólo se requieren 6 bytes. Internamente, esta biblioteca utiliza todas las funciones estándar de Arduino como micros () para sincronización y analogRead () o digitalRead () para obtener los valores de los sensores, por lo que debería funcionar en todos Arduino sin entrar en conflicto con otras bibliotecas. vacío de
lectura (unsigned
int
* sensorValues ,
sin
firmar
carbón readMode =
QTR_EMITTERS_ON) Lee los valores de sensor en bruto en una matriz. Hay DEBE haber espacio para tantos valores como había sensores especificados en el constructor. Los valores devueltos son una medida de la reflectancia en las unidades que dependen del tipo de sensor que se utiliza, con valores más altos de reflectancia que corresponde a inferior (una superficie de color negro o un vacío). Sensores QTR-Xa devolverá un valor en bruto entre 0 y 1023. sensores QTR-XRC devolverá un valor en bruto entre 0 y el tiempo de espera de argumento (en unidades de microsegundos) proporcionado en el constructor (que por defecto es 2000). Las funciones
que se leen los
valores
de los
sensores
de todos
toman un
argumento readMode, que especifica el tipo de lectura que se va a realizar. Se definen varias opciones: QTR_EMITTERS_OFF especifica que la lectura debe hacerse sin necesidad de encender el infrarrojo (IR) emisores, en cuyo caso la lectura representa niveles de luz ambiente cerca del sensor; QTR_EMITTERS_ON especifica que los emisores deben estar encendidos
para
la
lectura,
lo
que
resulta
en
una
medida
de
reflectancia; y QTR_EMITTERS_ON_AND_OFF especifica que una lectura debe hacerse Joaquín Berrocal Piris 48
tanto
en
los
estados
activado
y
desactivado. Los
valores
devueltos
cuando
el QTR_EMITTERS_ON_AND_OFF opción se usa están dadas por el + max - off , donde en es la lectura con los emisores en, off es la lectura con los emisores de descanso, y max es la lectura máxima del sensor. Esta opción se puede reducir la cantidad de interferencia de iluminación de ambiente desigual. Tenga en cuenta que el control del emisor sólo funcionará si especifica un alfiler emisor válido en el constructor. Ejemplo de uso: ? 1 2
unsigned int sensor_values[8]; sensors.read(sensor_values);
anulará emittersOn () A su vez los LEDs IR sucesivamente. Esto es principalmente para su uso por el método de lectura, y llamar a estas funciones antes o después de la lectura de los sensores no tendrá ningún efecto sobre las lecturas, pero puede que desee utilizar éstos para fines de prueba. Este método sólo se va a hacer algo si el pin emisor especificada en el constructor no es QTR_NO_EMITTER_PIN . anulará emittersOff () A su vez los LEDs IR off. Esto es principalmente para su uso por el método de lectura, y llamar a estas funciones antes o después de la lectura de los sensores no tendrá ningún efecto sobre las lecturas, pero puede que desee utilizar éstos para fines de prueba. void Calibrar (unsigned char readMode = QTR_EMITTERS_ON) Lee los sensores para la calibración. Los valores de los sensores no se devuelven; En cambio, los valores máximos y mínimos que se encuentran con el tiempo se almacenan internamente y se utilizan para la readCalibrated () método. Puede acceder a la calibración (es decir, max prima y lecturas del sensor min) a través de los punteros miembro públicas calibratedMinimumOn , calibratedMaximumOn , calibratedMinimumOff , y calibratedMaximumOff . Tenga en cuenta que estos indicadores señalarán a matrices de longitud numSensors , tal como se especifica en el constructor, y sólo se asignarán después de calibrar () se ha llamado. Si sólo se calibra con los emisores en, no se asignarán las matrices de calibración que mantienen los valores de corte. anulará readCalibrated (unsigned int * sensorValues , sin firmar carbón readMode = QTR_EMITTERS_ON) Lecturas de sensor vuelve calibrados a un valor entre 0 y 1000, donde 0 corresponde a una lectura que es menor o igual al valor mínimo leído por Calibrar () y 1000 corresponde a una lectura que es mayor que o igual al valor máximo. Los valores de calibración se almacenan por separado para cada sensor, de modo que las diferencias en los sensores se tienen en cuenta automáticamente. unsigned
int ReadLine (unsigned
int
* sensorValues ,
unsigned
char readMode =
QTR_EMITTERS_ON, unsigned char WhiteLine = 0) Funciona igual que leer calibrado, pero con una característica diseñada para la línea Joaquín Berrocal Piris 49
siguiente: esta función devuelve una posición estimada de la línea. La estimación se realiza utilizando una media ponderada de los índices de sensor multiplicado por 1000, de modo que un valor de retorno de 0 indica que la línea está directamente debajo de sensor 0 (o fue visto por última vez por el sensor de 0 antes de perderse), un valor de retorno de 1000 indica que la línea está directamente debajo de sensor 1, 2000 indica que está por debajo de sensor 2, etc. los valores intermedios indican que la línea se encuentra entre dos sensores. La fórmula es: 0 * valor0 + 1000 * 2000 * + valor1 valor2 + ... -------------------------------------------valor0 + valor1 valor2 + + ... Mientras sus sensores no están demasiado separados en relación con la línea, esta volvió valor está diseñado para ser monótona, que lo hace ideal para su uso en el control de PID de bucle cerrado. Además, este método recuerda donde se vio por última vez la línea, por lo que si alguna vez pierde la línea hacia la izquierda o la derecha, que es la posición de línea continuará indicando la dirección que necesita ir a readquirir la línea. Por ejemplo, si el sensor 4 es su sensor de más a la derecha y se acaba completamente fuera de la línea a la izquierda, esta función continuará a volver 4000. Por defecto, esta función supone una línea oscura (valores altos), rodeada de blancos (valores bajos). Si su línea es luz sobre negro, ajustar el segundo argumento opcional WhiteLine true. En este caso, cada valor del sensor será reemplazado por el valor máximo posible menos su valor real antes de la promediación. unsigned int * calibratedMinimumOn Los valores mínimos calibrados medidos para cada sensor, con emisores en. Los punteros no asignado y se ponen a 0 hasta Calibrar () se llama, y después se asignan a exactamente el tamaño requerido. Dependiendo de la readMode argumento para calibrar (), solo los valores Activar o Desactivar pueden ser asignados, según sea necesario. Esta y las siguientes variables se hacen públicos para que pueda usarlos para sus propios cálculos y hacer cosas como guardar los valores en la EEPROM, la realización de la cordura de cheques, etc. unsigned int * calibratedMaximumOn Los valores máximos calibrados midieron para cada sensor, con emisores en. unsigned int * calibratedMinimumOff Los valores mínimos calibrados midieron para cada sensor, con emisores de apagado. unsigned int * calibratedMaximumOff Los valores máximos calibrados midieron para cada sensor, con emisores de apagado. Destructor: ~ QTRSensors () El destructor para la clase QTRSensors libera la memoria asignada para las matrices de calibración. Constructor: QTRSensorsRC () Esta versión del constructor realiza ninguna inicialización. Si se utiliza, el usuario debe llamar a init () antes de usar los métodos de esta clase. Joaquín Berrocal Piris 50
Constructor: QTRSensorsRC (unsigned char * digitalPins , unsigned char numSensors , unsigned int timeout = 2000, unsigned char emitterPin = QTR_NO_EMITTER_PIN); Este constructor sólo llama a init () , a continuación. anulará
QTRSensorsRC
char numSensors ,
:: init (unsigned
unsigned
int timeout =
char
* digitalPins ,
2000,
unsigned
unsigned
char emitterPin =
QTR_NO_EMITTER_PIN) Inicializa una matriz de sensores QTR-RC (digital). La matriz digitalPins deben contener los números de pin digital Arduino para cada sensor. numSensors especifica la longitud de la digitalPins array (el número de sensores QTR-RC que está utilizando). numSensors deben ser mayores de 16 años. tiempo de espera especifica la cantidad de tiempo en microsegundos más allá de que considere la lectura del sensor completamente negro. Es decir, si la longitud del pulso para un pasador supera el tiempo de espera , el tiempo de impulsos se detendrá y la lectura para que el pin se considera negro completo. Se recomienda que ajuste el tiempo de espera para ser entre 1000 y 3000 nosotros, dependiendo de factores como la altura de los sensores y la iluminación ambiente. Esto le permite acortar la duración de un ciclo de sensor de lectura, mientras que el mantenimiento de las medidas útiles de reflectancia. emitterPin es el pin digital Arduino que controla si los LED IR están encendidos o apagados. Este pin es opcional y sólo existe en el 8A y matrices de sensores 8RC QTR. Si se especifica un PIN válido, los emisores sólo se activan durante una lectura. Si el valor QTR_NO_EMITTER_PIN se usa (255), puede dejar el pasador emisor desconecta y los emisores IR siempre estará encendida. Constructor: QTRSensorsAnalog () Esta versión del constructor realiza ninguna inicialización. Si se utiliza este constructor, el usuario debe llamar a init () antes de usar los métodos de esta clase. Constructor: QTRSensorsAnalog (unsigned char numSensors ,
unsigned
char
* analogPins ,
char numSamplesPerSensor =
4,
unsigned unsigned
char emitterPin = QTR_NO_EMITTER_PIN) Este constructor sólo llama a init () , a continuación. void init (unsigned
char
* analogPins ,
unsigned
char numSensors ,
unsigned
char numSamplesPerSensor = 4, unsigned char emitterPin = QTR_NO_EMITTER_PIN) Inicializa una matriz de sensores QTR-A (analógico). La matriz de pasadores deben contener el número pin de entrada analógica Arduino para cada sensor. Por ejemplo, si pasadores es {0, 1, 7}, sensor 1 está en la entrada analógica 0, sensor 2 es en la entrada analógica 1, y el sensor 3 está en la entrada analógica 7. numSensors especifica la longitud de la analogPins array (el número de sensores QTR-A que está utilizando). numSensors deben ser mayores de 16 años. numSamplesPerSensor indica el número de muestras analógicas de 10 bits a media por canal (por sensor) para cada lectura. El número total de conversiones de analógico a digital realizados será igual a numSensors veces numSamplesPerSensor . El aumento de este Joaquín Berrocal Piris 51
parámetro aumenta la supresión de ruido en el costo de la frecuencia de muestreo. Este parámetro no debe exceder de 64. El valor recomendado: 4. emitterPin es el pin digital Arduino que controla si los LED IR están encendidos o apagados. Este pin es opcional y sólo existe en el 8A y matrices de sensores 8RC QTR. Si se especifica un PIN válido, los emisores sólo se activan durante una lectura. Si el valor QTR_NO_EMITTER_PIN se usa (255), puede dejar el pasador emisor desconecta y los emisores IR siempre estará encendida. Notas de uso Calibración Esta biblioteca le permite usar la Calibrar () método para calibrar fácilmente sensores para las condiciones particulares que se encontrará. Calibración de los sensores puede dar lugar a lecturas del sensor mucho más fiables, que a su vez puede ayudar a simplificar su código desde entonces. Como tal, se recomienda construir una fase de calibración en la rutina de inicialización de la aplicación. Esto puede ser tan simple como una duración fija sobre la que se repite la llamada de calibración () método. Durante esta fase de calibración, que tendrá que exponer a cada uno de los sensores de reflectancia a las lecturas más claras y oscuras que van a encontrar. Por ejemplo, si usted ha hecho un seguidor de línea, tendrá que deslizarse a través de la línea durante la fase de calibración por lo que el cada sensor puede obtener una lectura de lo oscura que la línea es y cómo iluminar el suelo es. Una rutina de calibración de la muestra sería: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#include <QTRSensors.h> // create an object for your type of sensor (RC or Analog) // in this example we have three sensors on analog inputs 0 - 2, a.k.a. digital pins 14 - 16 QTRSensorsRC qtr((char[]) {14, 15, 16}, 3); // QTRSensorsA qtr((char[]) {0, 1, 2}, 3); void setup() { // optional: wait for some input from the user, such as
a button press
// then start calibration phase and move the sensors over both // reflectance extremes they will encounter in your application: int i; for (i = 0; i < 250; i++) // make the calibration take about 5 seconds { qtr.calibrate(); delay(20); } // optional: signal that the calibration phase is now over and wait for further // input from the user, such as a button press }
La lectura de los sensores Esta biblioteca le da un número de diferentes formas de leer los sensores. 1. Puede solicitar los valores del sensor primas utilizando la lectura () método, que toma un argumento opcional que le permite realizar la lectura con los emisores IR desactivado (tenga en cuenta que al girar los emisores fuera sólo es compatible con las redes de sensores de reflectancia QTR-8x). 2. Puede solicitar valores de los sensores calibrados utilizando el readCalibrated () método, que también toma un argumento opcional que le permite realizar la lectura con los emisores IR apagados. Valores de los sensores calibrados siempre variar de 0 a 1000, con 0 siendo tan o más reflectante (es decir, más blanco) que la superficie más reflectante encontrado durante la Joaquín Berrocal Piris 52
calibración, y 1.000 siendo tan o menos reflectante (es decir, más negro) que la superficie menos reflectante encontrado durante la calibración . 3. Para las aplicaciones de línea de detección, puede solicitar la ubicación de la línea utilizando el readLine () método, que toma como parámetros opcionales un booleano que indica si la línea es de color blanco sobre un fondo negro o negro sobre un fondo blanco, y un booleano que indica si los emisores IR deben estar encendido o apagado durante la medición. readLine () proporciona valores de calibrado para cada sensor y devuelve un entero que le indica donde se cree es la línea. Si está utilizando N sensores, un valor devuelto de 0 significa que piensa que la línea está en o hacia el exterior del sensor 0, y un valor devuelto de 1000 * ( N -1) significa que piensa que la línea está en o hacia el exterior de sensor N -1. A medida que desliza sus sensores a través de la línea, la posición de línea cambiará monotónicamente de 0 a 1000 * ( N -1), o viceversa. Este valor-posición de la línea se puede utilizar para el control de PID de bucle cerrado. Una rutina de muestra para obtener los valores de los sensores y realizar línea rudimentaria siguiente sería: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
void loop() { unsigned int sensors[3]; // get calibrated sensor values returned in the sensors array, along with the line position // position will range from 0 to 2000, with 1000 corresponding to the line over the middle // sensor. int position = qtr.readLine(sensors); // if all three sensors see very low reflectance, take some appropriate action for this // situation. if (sensors[0] > 750 && sensors[1] > 750 && sensors[2] > 750) { // do something. Maybe this means we're at the edge of a course or about to fall off // a table, in which case, we might want to stop moving, back up, and turn around. return; } // compute our "error" from the line position. We will make it so that the error is zero // when the middle sensor is over the line, because this is our goal. Error will range from // -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, a reading of // -1000 means that we see the line on the left and a reading of +1000 means we see the // line on the right. int error = position - 1000; int leftMotorSpeed = 100; int rightMotorSpeed = 100; if (error < -500) // the line is on the left leftMotorSpeed = 0; // turn left if (error > 500) // the line is on the right rightMotorSpeed = 0; // turn right // set motor speeds using the two motor speed variables above }
control PID El valor entero devuelto por readLine () se puede convertir fácilmente en una medida de su error de posición para aplicaciones de línea siguiente, como se demostró en el ejemplo de código anterior. La función que se utiliza para generar este valor de posición / error está diseñado para ser monótona, lo que significa que el valor casi siempre va a cambiar en la misma dirección a medida que barre sus sensores en toda la línea. Esto hace que sea una gran cantidad a utilizar para el control PID. Al explicar la naturaleza del control PID está más allá del alcance de este documento, pero Wikipedia tiene un muy buen artículo sobre el tema. El siguiente código da un ejemplo muy simple de control PD (me parece por lo general el Joaquín Berrocal Piris 53
término integral PID no es necesario cuando se trata de la línea que sigue). La naturaleza específica de las constantes será determinado por su aplicación particular, pero se debe tener en cuenta que la constante derivado Kd es por lo general mucho más grande que la constante proporcional Kp . Esto es debido a que la derivada del error es una cantidad mucho menor que el error en sí mismo, por lo que a fin de producir una corrección significativa que debe ser multiplicado por una constante mucho mayor. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
int lastError = 0; void loop() { unsigned int sensors[3]; // get calibrated sensor values returned in the sensors array, along with the line position // position will range from 0 to 2000, with 1000 corresponding to the line over the middle // sensor int position = qtr.readLine(sensors); // compute our "error" from the line position. We will make it so that the error is zero when // the middle sensor is over the line, because this is our goal. Error will range from // -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, a reading of // -1000 means that we see the line on the left and a reading of +1000 means we see the // line on the right. int error = position - 1000; // set the motor speed based on proportional and derivative PID terms // KP is the a floating-point proportional constant (maybe start with a value around 0.1) // KD is the floating-point derivative constant (maybe start with a value around 5) // note that when doing PID, it's very important you get your signs right, or else the // control loop will be unstable int motorSpeed = KP * error + KD * (error - lastError); lastError = error; // M1 and M2 are base motor speeds. That is to say, they are the speeds the motors should // spin at if you are perfectly on the line with no error. If your motors are well matched, // M1 and M2 will be equal. When you start testing your PID loop, it might help to start with // small values for M1 and M2. You can then increase the speed as you fine-tune your // PID constants KP and KD. int m1Speed = M1 + motorSpeed; int m2Speed = M2 - motorSpeed; // it might help to keep the speeds positive (this is optional) // note that you might want to add a similiar line to keep the speeds from exceeding // any maximum allowed value if (m1Speed < 0) m1Speed = 0; if (m2Speed < 0) m2Speed = 0; // set motor speeds using the two motor speed variables above }
------------------------------------- 0 -----------------------------------------DRIVERS POSIBLES LAMBORHINO https://www.luisllamas.es/arduino-motor-dc-tb6612fng/ muy Buena página de Luis Llamas https://www.sparkfun.com/products/9457 lo mismo en sparkfun
Conductor Sparkfun Motor - TB6612FNG Dual (1A) ROB-09457 ROHS 15
Descripción: El controlador de motor TB6612FNG puede controlar hasta dos motores de corriente continua a una corriente constante de 1,2 A (pico 3.2A). Dos señales de entrada (IN1 y IN2) se pueden utilizar para controlar el motor en uno de cuatro modos de funcionamiento - CW, CCW, corto de freno, y parada. Las dos salidas de motor (A y B) pueden ser controladas por separado, la velocidad de cada motor se controla a través de una señal de entrada PWM con una frecuencia de hasta 100 kHz. El pasador ESPERA debe tirar alta para tomar el motor fuera del modo de espera. tensión de alimentación de lógica (VCC) puede estar en el intervalo de 2.7-5.5VDC, mientras que la alimentación del motor (VM) está limitada a una tensión máxima de 15 V CC. La corriente de salida tiene una clasificación de hasta 1.2A por canal (o hasta 3.2A por un corto pulso único,). Joaquín Berrocal Piris 54
Junta viene con todos los componentes instalados como se muestra. condensadores de desacoplamiento se incluyen en ambas líneas de suministro. Todos los pines de la TB6612FNG se rompen a dos 0.1" cabeceras de tono; los pasadores se disponen de modo que los pines de entrada están en un lado y pines de salida están en el otro. Nota: Si usted está buscando el controlador del motor Sparkfun con las cabeceras, que se puede encontrar aquí o en los productos recomendados a continuación. COMIENZA CON EL CONDUCTOR DEL MOTOR DE GUÍA DE CONEXIÓN caracteristicas: • • • • • • •
Tensión de alimentación: VM = 15V max, VCC = 2.7-5.5V Corriente de salida: Iout = 1.2A (promedio) / 3.2A (pico) control de reposo para ahorrar energía CW / CCW / freno / parada corta modos de control del motor Incorporado en el circuito de apagado térmico y el circuito de detección de bajo voltaje Todos los pines de la TB6612FNG rompen a 0.1" pasadores espaciados condensadores de filtrado de ambas líneas de suministro
Dimensiones: 0.8x0.8" Documentos: • • • • • •
Esquemático Los archivos de eagle Guía de conexión Hoja de datos (TB6612FNG) bildr Tutorial GitHub
Joaquín Berrocal Piris 55
-------------------------------------------------------------------------------
TB6612FNG 1A de sparkfun CONTROLAR DOS MOTORES DC CON ARDUINO Y DRIVER TB6612FNG SHARE ON: — 18 AGOSTO, 2016
¿QUÉ ES UN TB6612FNG ? El TB6612FNG es un controlador (driver) de motores que nos permite manejar dos motores de corriente continua desde Arduino, variando tanto la velocidad como el sentido de giro. El TB6612FNG puede ser considerado una versión mejorada del L298N. Al igual que esté, internamente está formado por dos puentes-H, junto con la electrónica necesaria para simplificar su uso, y eliminar posibles cortocircuito por errores de uso. Sin embargo, en el caso del TB6612FNG los puentes-H están formados por transistores MOSFET, en lugar de transistores BJT como en el L298N. Esto permite que el TB6612FNG tiene mejor eficiencia y menores dimensiones que el L298N. El TB6612FNG también permite controlar intensidades de corriente superiores, siendo capaz de suministrar 1.2A por canal de forma continua, y 3.2A de pico. Recordar que el L298N tiene una intensidad máxima teórica de 2A, pero las pérdidas hace que en la práctica sólo pueda suministrar 0.8-1A. Además, el TB6612FNG no tiene la caída de tensión que sí tiene el L298N debido a sus transistores BJT, que podían llegar a ser superiores a 3V. En su lugar, el TB6612FNG se comporta como una pequeña resistencia de 0.5 Ohm. Como puntos negativos, el TB6612FNG puede proporcionar tensiones inferiores, de hasta 13.5V (frente a los 35V del L298N). Además, es algo más difícil de montar, ya que las placas con L298N frecuentemente incorporan placas de conexión, que permiten Joaquín Berrocal Piris 56
conectar de forma sencilla el motor. Finalmente, la protección contra corrientes inducidas son algo más limitadas que las del L298N, por lo que podemos tener algún reinicio de Arduino cuando alimentamos cargas medianas o grandes. El TB6612FNG dispone de dos canales, por lo que es posible controlar dos motores de corriente continua de forma independiente. También puede controlar un único motor paso a paso aunque, en general, preferiremos usar controladores específicos. En cada canal podemos controlar el sentido de giro y la velocidad, para lo cual admite una señal PWM de frecuencia máxima de 100 kHz (muy por debajo del rango normal de PWM en Arduino) El TB6612FNG dispone de protecciones térmicas, de inversión de corriente en la fuente de suministro de los motores, condensadores de filtrado en ambas líneas de alimentación, detección de bajo voltaje, y protecciones contra las corrientes inducidas en los motores. El TB6612FNG también incorpora un modo de Standby, que desactiva por completo el controlador, entrando en un modo de ahorro de energía. El controlador TB6612FNG puede ser empleado en proyectos de electrónica y robótica. Es ampliamente usado en proyectos electrónico y robótica, por su sencillez de uso, bajo coste, y buena calidad precio PRECIO El controlador TB6612FNG es un dispositivo barato. En un principio el TB6612FNG era más caro que el L298N, pero los precios descendieron y en la actualidad el TB6612FNG es más barato que el L298N. Podemos encontrar un TB6612FNG por 1,10€ en vendedores internacionales de AliExpress o eBay.
ESQUEMA DE MONTAJE El esquema de montaje no es demasiado complicado. Por un lado, suministramos la tensión que alimentará el motor desde una fuente de alimentación externa, mediante el pin VM. La tensión máxima es de 15V. Además, tenemos que alimentar la electrónica del módulo mediante el pin VCC. El rango de tensión para VCC es 2.7 a 5.5V. Para el control del módulo Los pines AIN1, AIN2 Y PWMA controlan el canal A, mientras que los pines BIN1, BIN2, y PWMB controlan el canal B. Finalmente, el pin STBY controla el modo Standby. Debemos ponerlo en HIGH para activar el motor. Podemos conectarlo a un pin digital de Arduino, si queremos poder activar el modo Standby, o conectarlo a VCC si queremos dejarlo permanentemente desconectado.
Joaquín Berrocal Piris 57
La conexión, vista desde Arduino quedaría de la siguiente forma.
EJEMPLOS DE CÓDIGO El código necesario es similar al que vimos al ver el L298N. Igualmente, conviene que agrupemos el código en funciones que podamos reutilizar, o el código crecerá rápidamente. El siguiente código permite desplazar y girar un vehículo, actuando sobre ambos motores. Empleamos el modo Standby para reducir el consumo cuando esté parado, alargando la batería.
1 2 3 4 5 6 7
const int pinPWMA = 6; const int pinAIN2 = 7; const int pinAIN1 = 8; const int pinBIN1 = 9; const int pinBIN2 = 10; const int pinPWMB = 11; const int pinSTBY = 12; Joaquín Berrocal Piris 58
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
const int waitTime = 2000; //espera entre fases const int speed = 200; //velocidad de giro const int pinMotorA[3] = { pinPWMA, pinAIN2, pinAIN1 }; const int pinMotorB[3] = { pinPWMB, pinBIN1, pinBIN2 }; enum moveDirection { forward, backward }; enum turnDirection { clockwise, counterClockwise }; void setup() { pinMode(pinAIN2, OUTPUT); pinMode(pinAIN1, OUTPUT); pinMode(pinPWMA, OUTPUT); pinMode(pinBIN1, OUTPUT); pinMode(pinBIN2, OUTPUT); pinMode(pinPWMB, OUTPUT); } void loop() { enableMotors(); move(forward, 180); delay(waitTime); move(backward, 180); delay(waitTime); turn(clockwise, 180); delay(waitTime); turn(counterClockwise, 180); delay(waitTime); fullStop(); delay(waitTime); } //Funciones que controlan el vehiculo void move(int direction, int speed) { if (direction == forward) { moveMotorForward(pinMotorA, speed); moveMotorForward(pinMotorB, speed); } else { moveMotorBackward(pinMotorA, speed); moveMotorBackward(pinMotorB, speed); } } void turn(int direction, int speed) JoaquÃn Berrocal Piris 59
70 { 71 if (direction == forward) 72 { 73 moveMotorForward(pinMotorA, speed); 74 moveMotorBackward(pinMotorB, speed); 75 } 76 else 77 { 78 moveMotorBackward(pinMotorA, speed); 79 moveMotorForward(pinMotorB, speed); 80 } 81 } 82 83 void fullStop() 84 { 85 disableMotors(); 86 stopMotor(pinMotorA); 87 stopMotor(pinMotorB); 88 } 89 90 //Funciones que controlan los motores 91 void moveMotorForward(const int pinMotor[3], int speed) 92 { 93 digitalWrite(pinMotor[1], HIGH); 94 digitalWrite(pinMotor[2], LOW); 95 96 analogWrite(pinMotor[0], speed); 97 } 98 99 void moveMotorBackward(const int pinMotor[3], int speed) 100 { 101 digitalWrite(pinMotor[1], LOW); 102 digitalWrite(pinMotor[2], HIGH); 103 104 analogWrite(pinMotor[0], speed); 105 } 106 107 void stopMotor(const int pinMotor[3]) 108 { 109 digitalWrite(pinMotor[1], LOW); 110 digitalWrite(pinMotor[2], LOW); 111 112 analogWrite(pinMotor[0], 0); 113 } 114 115 void enableMotors() 116 { 117 digitalWrite(pinSTBY, HIGH); 118 } 119 120 void disableMotors() 121 { 122 digitalWrite(pinSTBY, LOW); 123 } En un proyecto complejo, estas funciones estarĂan integradas en los objetos que integran nuestro modelo.
JoaquĂn Berrocal Piris 60
https://www.pololu.com/product/2130 DRV8833
Este pequeño tablero del desbloqueo para DRV8833 controlador dual motor de TI puede entregar 1,2 A por canal de forma continua (2 Un pico) a un par de motores de corriente continua. Con un rango de tensión de funcionamiento de 2,7 V a 10,8 V y una protección incorporada contra inversa voltaje, bajo voltaje, sobreintensidad de corriente, y el exceso de temperatura, este controlador es una gran solución para la alimentación de motores pequeños, de bajo voltaje --------------------driver motor DRV885 me ahorro 2 cables --------------https://www.pololu.com/product/2135
caracteristicas • • • • • • • •
controlador de motor-H-puente Dual: puede conducir dos motores de corriente continua o un motor paso a paso bipolar tensión de alimentación del motor: 0 V a 11 V tensión de alimentación lógica: 2 V a 7 V Corriente de salida: 1.2 A continua (1,5 A pico) por motor salidas del motor pueden conectar en paralelo para suministrar 2,4 A continua (3 Un pico) a un único motor Dos posibles modos de interfaz: IN / IN (salidas principalmente entradas espejo) o fase / activar (una clavija para la dirección y otro para la velocidad) Las entradas son compatibles 3V-y-5V de bloqueo de sub-voltaje en el suministro de la lógica y la protección contra sobre-corriente y de la temperatura Joaquín Berrocal Piris 61
• •
protección Reverse-tensión en la alimentación del motor El tamaño compacto (0,7 "x 0,4") con el factor de forma de un paquete DIP de 14 pines hardware incluido
Dos 1 × 7-pin de ruptura 0.1 "conectores macho se incluyen con el portador de conductor de doble motor DRV8835, que puede ser soldada en utilizar el controlador con placas universales , perfboards , o 0.1" conectores hembra . (Las cabeceras pueden enviar como una sola pieza 1 × 14 que puede ser roto por la mitad). La imagen de la derecha de arriba muestra las dos posibles orientaciones de mesa cuando se utiliza con estos pasadores de cabecera (partes visibles o serigrafía visible). También puede soldar sus cables del motor y otras conexiones directamente a la placa. Uso del controlador de motor diagrama de cableado mínimo para la conexión de un microcontrolador para un portador de conductor del motor dual DRV8835 en modo de fase a habilitar.
Motor y la potencia del motor conexiones se realizan en un lado de las conexiones de junta y la lógica de potencia y control se realizan por el otro. El controlador necesita una tensión de motor entre 0 V y 11 V para ser suministrada a la VIN o pasador VMM y una tensión lógica entre 1,8 V y 7 V para ser suministrada a la clavija de VCC; la tensión lógica típicamente puede ser suministrada por o compartida con el dispositivo de control. El pasador VIN es la entrada de alimentación del motor protegido inversa y es el punto recomendado para la conexión de potencia del motor. Sin embargo, el rendimiento del conductor se comienza a sentirse peor cuando el voltaje de entrada al circuito de protección inversa está por debajo de unos pocos voltios y 1,5 V es el límite inferior de donde se puede utilizar el pasador de VIN. Para las aplicaciones de muy baja tensión, la alimentación del motor debe estar conectado directamente a VMM, que no pasa por el circuito de protección inversa. El DRV8835 cuenta con dos posibles modos de control: EN / EN FASE y / Habilitar. El pasador MODE determina la interfaz de control. Cada entrada de control está a nivel bajo a través de una débil resistencia de pull-down (aproximadamente 100 kW), por lo que el conductor estará en la R I /O En el modo si el PIN del modo permanece desconectado, y las salidas del controlador será desactivado por defecto. Ajustar el PIN modo de alta, ya sea con una resistencia pull-up o una línea de conducción de alta I / O, establece que el conductor de fase / modo, donde el pasador FASE Joaquín Berrocal Piris 62
determina la dirección del motor de ENABLE y el pasador de ENABLE puede ser suministrado con un PWM señal para controlar la velocidad del motor. Este modo es generalmente más fácil de usar, ya que sólo requiere de un PWM por canal, pero sólo permite la operación de accionamiento / freno. (Funcionamiento / freno Drive por lo general proporciona una relación más lineal entre el ciclo de trabajo PWM y la velocidad de motor de funcionamiento de la unidad / costa, y generalmente recomienda el uso de la operación de accionamiento / freno cuando sea posible.)
Nota deduzco que por defecto esta el pin MODE en down con
Joaquín Berrocal Piris 63
funcionamiento de la unidad de freno / simplificado con MODE = 1 (FASE / ENABLE) XPhase xENABLE xOUT1 xOUT2 modo operativo 0
PWM
PWM
L
adelante / freno a la velocidad PWM%
1
PWM
L
PWM
revertir / freno a la velocidad PWM%
x
0
L
L
bajo freno (salidas en cortocircuito a tierra)
Cuando el pasador MODO se desconecta o se baja, la interfaz de control es IN / IN, que permite opciones de control un poco más avanzados. La siguiente tabla de verdad muestran cómo lograr la unidad / costa y funcionamiento de la unidad / freno a través de la EN / EN interfaz de control: Conduce / costa o conducir la operación / freno con MODE = 0 (EN / EN) XIN1 xIN2 xOUT1 xOUT2 modo operativo 0
0
PWM 0
ABIERTO ABIERTO costa (salidas desactivadas) PWM
L
adelante / costa a una velocidad PWM%
0
PWM L
PWM
reversa / costa a velocidad PWM%
1
PWM PWM
L
adelante / freno a la velocidad de 100% - PWM%
PWM 1
L
PWM
revertir / freno a la velocidad de 100% PWM%
1
L
L
bajo freno (salidas en cortocircuito a tierra)
1
Joaquín Berrocal Piris 64