miércoles, 3 de diciembre de 2014

Robot Velocista de Competencia - Parte II: Utilizando la libreria de sensores QTR SENSORS

Utilizando la librería "QTRSensors"




Como les mencione en el post anterior ("Materiales"), los sensores QTR8RC necesitan de  lineas de E/S digitales para su funcionamiento. No es necesario usarlos exclusivamente con  con pines analógicos, aunque la mayoría de los pines analógicos de un microcontrolador también pueden ser configurados como digitales, en comparación  con los QTR8A, que si utilizan entradas exclusivamente analógicas (Esa es la ventaja  de los QTR8RC de poder ser  usados en pines digitales).

Hay que tener en cuenta que los QTR8RC no funcionan de manera analógica, tampoco de manera completamente digital como se piensa a primer momento (no te va dar "1" y "0" si los utilizas de manera directa), su funcionamiento se puede decir que es una combinación de analógico y digital. Juega con la carga y descarga de el condensador ubicado en el colector del foto-transistor de cada sensor, de esta manera se puede hacer una medición del tiempo de carga, y pues para tal tarea  no es necesario  un pin analógico, solo basta con uno digital y la librería hará el trabajo de obtener esos tiempos y convertirlos en una medición cuasi analógica. si quieres ahondar mas en su funcionamiento puedes visitar este link: https://www.pololu.com/docs/0J13/all

Si quizás no puedes comprar este modulo directamente de  Pololu, pues siempre esta la opción de diseñar nuestro propio circuito  del sensor , varios amigos mios me comentaron que se han diseñado sus propios sensores basandose en el esquema de sensor pololu, los sensores pueden variar, pueden ser desde utilizar un cny70 o tcr5000, no necesariamente el que  usa en el modulos qtr8rc (que son los qrd1114), asi que no existen excusas!!

 El transistor mosfet , puede ser facilmente remplazado por un transistor 2n2222a, que es untransistor npn muy común y facil de encontrar.
Los diodos emisores del sensor estan de 2 en 2 con una resitencia de 47 y seguido de otros 2 dos resistores en paralelos de 47 ohms ( usados para el bypass, pero se puede eliminar esta etapa, con tan solo colocar una resistencia de 100 ohms ). y claro cada diodo emisor esta con su respectivo fototransistor (8 en total).


La secuencia tipica  estandar para la lectura de un sensor con estas características es la siguiente:

1. Encender los LEDs IR (opcional).
2. Establecer Un pin  como  salida y hacer un HIGH o "1" logico
3. Deje por lo menos 10us que el condensador se cargue.
4. Hacer el pin  como entrada (alta impedancia).
5. Mida el tiempo de la descomposición de la tension en el pin hasta que sea 0
6. Apague LEDs IR (opcional).
Estos pasos normalmente se pueden ejecutar en paralelo en varias líneas de E / S.
Esto lo hace de manera automatica la libreria <QTRSensors.h>

- >Instalando La biblioteca

Link para descargar la biblioteca:
QTRsensors

Ya descargada la libreria, lo que ahora hay que hacer es descomprimir el archivo y copiar la carpeta "QTRSensors". Luego ir Al directorio donde esta la carpeta del programa   "Arduino " :
arduino-1.0.5 / libraries ... luego pegar ahi la Carpeta "QTRSensors", y eso seria todo , ahora si tenemos disponible la libreria de los sensores
o si tienes problemas  puedes seguir este tutorial: http://www.prometec.net/librerias/

-> Disposición de los pines a 
utilizar:

GND: tierra "-"
Vcc: Alimentacion de 5 volts "+"
Led on: es un "Switch" que enciende y apaga los leds infrarojos de cada uno de los sensores, de manera predeterminada esta encendido "High" , para apagar se necesita dar un estado  digital "Low"
pines 1,2...7,8:   Son los respectivos pines de para la lectura de cada sensor.
3.3v Bypass: Utilizar si es que se requiere alimentar con 3.3v. los sensores, por defecto se alimenta con 5 v. Es mejor no utilizarlo.

Previamente es necesario soldar los espadines para una correcta manipulación de los sensores.


->Primeros pasos para utilización de los sensores
Abrimos  el Ide de Arduino y comprobamos que este disponible la librería



Para Comprobar el funcionamiento de nuestros sensores,  vamos a  abrir un ejemplo que nos trae la libreria, seleccionamos "QTRRCExample"

*Mi robot velocista utiliza estos pines  de arduino para los sensores:
A5, A4, A3, A2, A2, A1, A0, D11, D12, que en valor numérico serian 19, 18, 17, 16, 15, 14, 11, 12.

#define NUM_SENSORS   8  //uso el pin D8
#define TIMEOUT       2500  // tiempo de espera para dar resultado en uS
#define EMITTER_PIN   6    //uso el pin D6

por lo que quedaria definido asi:

Las conexiones físicas son estas:


A continuación muestro el código completo para empezar con la utilización de los sensores:
#include <QTRSensors.h>
#define NUM_SENSORS   8     // numero de sensores usados
#define TIMEOUT       2500  // esperar 2.5 ms para tener una respuesta del sensado
#define EMITTER_PIN   6     // este pin controla el led on del los sensores (enciende y apaga)
 
//aqui se pone el numero de los pines conectados a los sensores
QTRSensorsRC qtrrc((unsigned char[]) {19, 18, 17, 16, 15, 14, 11, 12},
  NUM_SENSORS, TIMEOUT, EMITTER_PIN); 
unsigned int sensorValues[NUM_SENSORS];
 
 
void setup()
{
  delay(500);
  pinMode(13, OUTPUT);        
  digitalWrite(13, HIGH);    //este led encendido indica que comienza la calibracion
  for (int i = 0; i < 200; i++)  // la calibracion se lleva a cabo por 5 segundos 
  {
    qtrrc.calibrate();       // funcion para calibrar los sensores
  }
  digitalWrite(13, LOW);     // se paga el led para que indique que termino la calibracion
 
  // imprime la calibracion minima de los sensores
  Serial.begin(9600);
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtrrc.calibratedMinimumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
   
  // imprime la calibracion maxima de los sensores
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtrrc.calibratedMaximumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  Serial.println();
  delay(1000);
}
 
 
void loop()
{
  // read calibrated sensor values and obtain a measure of the line position from 0 to 5000
  // To get raw sensor values, call:
  //  qtrrc.read(sensorValues); instead of unsigned int position = qtrrc.readLine(sensorValues);
  unsigned int position = qtrrc.readLine(sensorValues);
 
  // print the sensor values as numbers from 0 to 1000, where 0 means maximum reflectance and
  // 1000 means minimum reflectance, followed by the line position
  for (unsigned char i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]);
    Serial.print('\t');
  }
  //Serial.println(); // uncomment this line if you are using raw values
  Serial.println(position); // comment this line out if you are using raw values
   
  delay(50);
}


-> Visualizando los  valores obtenidos con los sensores

Hecho toda la conexión respectiva, cargar el programa al arduino, luego abrir el "monitor serial" del ide arduino. Luego, en una superficie blanca con una linea negra, se puede utilizar un  cinta aislante negra, recorrer los  sensores  por la parte negra, y por la parte blanca (hacer estas pasadas reiteradas veces y procurar que la distancia con respecto a la superficie sea constante), de esta manera estaremos calibrando los sensores. 
Abrir el monitor serial, si la calibración se hizo de forma correcta se mostraran estos resultados en el monitor serial:
(ojo, para un correcto sensado lo ideal es que la distancia entre la superficie  y los sensores se mantenga  constante, a una distancia de 3 mm a 10mm. )




Los valores que nos arroja el monitor serial, son los valores obtenidos de la lectura  de cada sensor. Cuando se esta en una superficie blanca el mínimo valor de reflactancia es "0", y cuando esta se esta sobre una superficie negra, el máximo valor obtenido es "1000". También van existir partes donde los sensores estén sobre una parte blanca y un parte oscura. un valor que arrojaría seria un "500" o "600".
De esta manera se puede hacer un ponderado de cada sensor ,  obteniendo así valores relativos de posición (esto la librería ya lo hace) y se logra visualizar en la ultima columna a la derecha.
 Estos  valores de posición nos dirán que tan alejados de la linea están los sensores con respecto al centro, Esto nos sera de mucha utilidad para  el "Algoritmo Pid" que utilizaremos para  nuestro robot.
los valores de posición comprenden desde "0" hasta "7000"

Para visualizar el funcionamiento de los sensores solo sera posible con una cámara de celular, o cámara digital, algunos celulares traen un filtro y la visualizacion de los  se ve atenuada y hasta nula, por eso recomendaría usar camaras antigua. Directamente nosotros no somos capaces de ver la luz infrarroja.



->Entendiendo algunas definiciones de la libreria

#include <QTRSensors.h>  // Es siempre necesario la inclusión de la libreria de los qtr antes de 
                                          //utlizar sus funciones

Hay que reconocer  definciones que se usan para los sensores:
#define NUM_SENSORS   8       // aqui definimos cuantos sensores estamos utilizando , en este                                                         //caso el arreglo es de  8 sensores

#define TIMEOUT           2500    //este sera el tiempo que esperaremos para que  se de los                                                                  //resultados de lectura de los sensores. 
                                                    // el tiempo optimo esta entre los 1500 us a 2500 us
.
#define EMITTER_PIN    6        // este es el pin del "led on" es necesario especificar en que pin se                                                    // utilizara, en este caso es el D6

*Objeto para  sensor qtr 8rc:
  //aqui van los pines a utilizar para las lecturas
QTRSensorsRC qtrrc((unsigned char[]) {19, 18, 17, 16, 15, 14, 11, 12},
  NUM_SENSORS, TIMEOUT, EMITTER_PIN); 

unsigned int sensorValues[NUM_SENSORS];  // es necesario la creación de un array , esto para el                                                                           //almacenamiento de los valores de reflactancia de                                                                           //los sensores


->Funciones Importantes:

qtrrc.calibrate();       
calibracion de sensores es necesario  antes de utilizar los sensores, esta funcion no devuelve valor alguno

qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, 0);  
Realiza la lectura de los sensores, y devuelve el valor de posición estimada de los sensores, la estimación se hace con un promedio ponderado de cada sensor. El tercer parámetro es para indicar si se requiere leer una superficie blanca con un linea negra ,este valor sera de "0". Si  se quiere leer una superficie negra con una linea Blanca,  se tiene que cambiar el valor a "1". para usarlo es necesario almacenarlo en una variable entera por ejemplo
int posicion=qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, 0);  
         
qtrrc.read(sensorValues);
Realiza  Lecturas en bruto de cada sensor, para obtener estos valores es necesario leer  el  indice de array donde se guarda los valores de cada sensor . Por ejemplo si queremos saber el valor de reflactancia que tiene el sensor numero 1 tenemos que crear una variable y asignar el valor del array que contiene el valor del sensor:
int sensor_1=sensorValues[0];
int sensor_2=sensorValues[1];

Para mas informacion Puedes descargar la Nota de aplicación de Pololu, esta en ingles,  nunca esta de mas dar un vistazo
link: QTR_arduino_library.pdf
Pagina Pololu: https://www.pololu.com/product/961

"Si te sirvió de algo la informacion de la pagina, podrías invitarme un café y ayudarme a seguir manteniendo  en pie este sitio. Solo cuesta  $1 USD y me ayudarías  enormemente a seguir publicando estos contenidos". 




Siguiente post>> algoritmo pid robot velocista

8 comentarios:

hola, primero que todo gracias por poner la información, es de mucha utilidad. me gustaria saber si se puede utilizar el mismo código pero con los qtr 8a. saludos desde Chile.

Sebastián Hernández, si pero tienes que cambiar el objeto qtrc por el del qrta con sus respectivos parametros, el resto del programa funciona igual.

qtrrc.read(sensorValues);
Realiza Lecturas en bruto de cada sensor, para obtener estos valores es necesario leer el indice de array donde se guarda los valores de cada sensor . Por ejemplo si queremos saber el valor de reflactancia que tiene el sensor numero 1 tenemos que crear una variable y asignar el valor del array que contiene el valor del sensor:
int sensor_1=sensorValues[0];
disculpa pero me podrias dar mas ejemplos de esto digamos que por ejemplo quiero saber el valor de mi sensor 2 seria
int sensor_2=sensorValues[1]
y despues puedo usar este dato como yo quiera porque ya esta guardado en mi variable sensor_2
porque lo estaba intentando de la manera tradicional leyendo datos con analogRead y ponia el numero de pin pero la verdaad no me a funcionado
te agradeceria mucho si pudieras ayudarme a resolver esta duda

Hola en que parte cambio las lecturas para línea negra y blanca de la libreria?

Hola en que parte cambio las lecturas para línea negra y blanca de la libreria?

hola, el codigo me arroja un error en   "delay(50);"

me ayudan?

Cuando copia el codigo que dice que "i" no está declarado, ayuda porfavor

Buenas, porfa me podrias indicar que software usaste para el circuito impreso gracias :D

Publicar un comentario