viernes, 30 de diciembre de 2016

Encoders Seguidor de Línea
Parte 1


El uso de encoders en un robot seguidor de línea sirve para grabar la pista y así poder acelerar más del 50% de la velocidad del robot en líneas rectas. Asimismo, detectar y grabar la pista; En esta sección se pretende explicar y conceptualizar en el funcionamiento del encoder de cuadratura y en la parte 2 se daran a conocer los cálculos matemáticos necesarios para su posterior programación.  
En los seguidores de línea se suele usar motoreductores de Pololu, pues bien, dicha empresa también vende los encoder’s ya sean de tipo magnético o óptico, se recomienda el magnético ya que no le afecta la luz ambiente como el óptico. Bueno, para no extender mucho esto, se puede definir un encoder como un dispositivo o sensor que genera señales en respuesta al movimiento, y existen básicamente 2 tipos:  incremental y absoluto. Y su vez, cada tipo puede ser rotativo o lineal.
Para el caso de los encoders absolutos (encoders pololu), la salida posee información acerca de la velocidad angular, la dirección, y la posición.
A B
https://a.pololu-files.com/picture/0J5832.600x480.jpg?1a7afd1aeb0cd22d610efcf66847279c  https://a.pololu-files.com/picture/0J4767.600x480.jpg?4b1b4a352a5b65138785021302b907b2
Figura 1. A. Encoder de cuadratura magnético y B. Óptico – Pololu
Los encoder’s magnéticos trabajan desde 2.7 a 18V, ya que es el voltaje de alimentación de los sensores de efecto Hall. Además, tiene dos salidas (A y B), una para cada sensor de efecto Hall. Los sensores están separados 90 grados. Esto significa que las salidas de onda cuadrada de los sensores son de 90 grados fuera de fase. Esto se llama una salida en cuadratura. Por consiguiente, dichas salidas sirven para determinar el sentido de giro (Horario o anti-Horario). La imagen siguiente (tomado de la página web de Pololu) muestra la salida típica de un encoder.


https://a.pololu-files.com/picture/0J5831.600x480.jpg?b37c879d2899289012b77d9281c4dc51
Figura 2. Salida de encoder’s de cuadratura.


Cabe destacar que los encoder’s tiene una resolución de 12 pulsos por vuelta y trabajaran a una frecuencia de 1 a 2KHz dependiendo de la velocidad de que girara el motor (1000 RPM a 3000 RPM), pues bien, esto quiere decir que el microcontrolador no podrá estar leyendo el estado de la salida A y B en el bucle infinito, si no que se hará uso de interrupciones, que se ejecutaran cada 1 o 2 milisegundos. A continuación, se añade un código de prueba que utiliza las interrupciones INT0 y INT1 de Arduino UNO y luego imprime cada 500 ms el valor o el número de pulsos de dos encoder’s conectados al Arduino.

Código de prueba de encoders:



/*
* Encoder example sketch
*
* Modificado por Michael Vargas @ BeatBlog
* Creditos:
* by Andrew Kramer
*
* Records encoder ticks for each wheel
* and prints the number of ticks for
* each encoder every 500ms
*
*  1/1/2017
*/
//Pines de conexion de los encoders
#define RH_ENCODER_A 3 //INT1
#define RH_ENCODER_B 5
#define LH_ENCODER_A 2 //INT0
#define LH_ENCODER_B 4
#define RESOLUTION  12 //Numero de pulsos por Vuelta


// Variabes que almacenan el numero de pulsos
volatile unsigned long leftCount = 0;
volatile unsigned long rightCount = 0;
void setup() {
 pinMode(LH_ENCODER_A, INPUT);
 pinMode(LH_ENCODER_B, INPUT);
 pinMode(RH_ENCODER_A, INPUT);
 pinMode(RH_ENCODER_B, INPUT);
 
 // initialize hardware interrupts
 attachInterrupt(0, leftEncoderEvent, CHANGE);
 attachInterrupt(1, rightEncoderEvent, CHANGE);
 
 Serial.begin(9600);
}
void loop() {
 Serial.print("Right Count: ");
 Serial.println(rightCount);
 Serial.print("Left Count: ");
 Serial.println(leftCount);
 Serial.println();
 Serial.print("#Rev Right ");
 Serial.println(rightCount/RESOLUTION);
 Serial.print("#Rev Left");
 Serial.println(leftCount/RESOLUTION);
 Serial.println();
 delay(500);
}
// encoder event for the interrupt call
void leftEncoderEvent() {
 if (digitalRead(LH_ENCODER_A) == HIGH) {
   if (digitalRead(LH_ENCODER_B) == LOW) {
     leftCount++;
   } else {
     leftCount--;
   }
 } else {
   if (digitalRead(LH_ENCODER_B) == LOW) {
     leftCount--;
   } else {
     leftCount++;
   }
 }
}
// encoder event for the interrupt call
void rightEncoderEvent() {
 if (digitalRead(RH_ENCODER_A) == HIGH) {
   if (digitalRead(RH_ENCODER_B) == LOW) {
     rightCount++;
   } else {
     rightCount--;
   }
 } else {
   if (digitalRead(RH_ENCODER_B) == LOW) {
     rightCount--;
   } else {
     rightCount++;
   }
 }
}

Descargar Código Actualizado:
EncodersPololu.ino


Continuar 2da Parte...

Encoders calculos mátematicos


"El conocimiento no es nada si no se comparte "

1 comentario: