lunes, 10 de noviembre de 2014

CONTADOR DE PULSOS DE ENCODER CON ARDUINO



(Recomiendo conocer primero el funcionamiento de los encoders, pueden ver este link y/o buscar por otras fuentes) 

Los encoders tienen como principio  generan señales digitales en respuesta al movimiento, sea de un disco o cinta perforada.

Éstos se utilizan, en su mayoría de las aplicaciones, para el control de posición y/o velocidad de un motor. Considerando básicamente el número de pulsos leído y la cantidad de ranuras que existen en un disco o cinta para controlar una posición específica o una velocidad.




Sin embargo, este post se centrará en realizar  el conteo de pulsos que genera un encoder. Para ello se necesitará el sensor optoacoplador y el disco o cinta ranurada, resistencias que se especifican en el circuito más adelante y la placa Arduino. 


Recomendación: Si se desea fabricar uno disco recomiendo utilizar programas (como OPTICAL ENCODER ó CODEWHEEL GENERATOR) que puedan diseñar éstos e imprimirlos en cartulinas, tres o cuatro y pegarlas; ó pegar una hoja de cartulina impresa en un cartón. Pero no utilizar plástico a no ser que se pegue una cartulina impresa a cada lado. 


Bueno, el sensor optoacoplador generará pulsos de acuerdo a cuantas franjas blancas o transparentes detectó. Estos pulsos serán contados por Arduino. 

Como se sabe la sensibilidad de los sensores, es posible que en algunos casos no esté claro un pulso y exista errores pequeños que con el tiempo se van haciendo muy notorios y eso afecta el objetivo final. Razón suficiente para añadir un circuito extra ó un programa específico. En este caso expongo el primero, añadiendo un disparador Schmitt (74LS14) previniendo dicho ruido.

Efecto del uso del schmitt trigger 
(B) en vez de un comparador (A)


Como se conoce los pulsos tienen únicamente dos respuestas ALTO(1) y BAJO(0), que da lugar a conectar a una entrada digital del Arduino, como se observa en la imagen.



Toma en cuenta el esquema del CI 74LS14. Para este caso únicamente se utiliza 4 pines de conexión, puedes considerar cualquier par que te sea más cómodo (Ix y Qx) y los de alimentación (VCC y GND).




Considerando al optoacoplador:

La configuración de estos sensores puede ser también de la siguiente manera (considerando que su estructura interna es la misma).





El programa es de la siguiente manera:
boolean anterior = 0;    
boolean actual = 0; 
int contador = 0;  


void setup() 
{
  Serial.begin(9600);  
  pinMode(2,INPUT);    
}

 boolean debounce(boolean dato_anterior) 
 {

   boolean dato_actual = digitalRead(2);
   if (dato_anterior != dato_actual)
   {
     delay(10);
     dato_actual = digitalRead(2);
   }
   return dato_actual;
 }  

void loop() 
{           

  actual = debounce(anterior); 
  

  if ( anterior == 0 && actual == 1) 
  {
         contador++;              
         
         delay (100);          
         Serial.println(contador);
  }
  
    anterior = actual; 
}


De esta manera acoplando un disco o cinta, como se mencionó anteriormente, ó sólo para hacer la prueba podrían interrumpir con una cartulina o cartón interponiéndolo en el optoacoplador para observar el conteo de pulsos generado. 





Considere contar también con un módulo para Arduino que compone de este sensor y todo el circuito adicional acondicionado. Éste tiene salidas digitales y analógicos, los digitales ayudarán a ejecutar la tarea de contar los pulsos como se presentó en este post. Mientras los analógicos ayudarán a usar a este sensor como retroalimentación en un lazo cerrado y así aplicar PID por ejemplo.



5 comentarios:

  1. funciona perfectamente.. pero si cambio de rotación en un motor, como decremento el valor ?
    es decir que regrese acero o punto inicial... GRACIAS

    ResponderEliminar
    Respuestas
    1. Se debe tener dos filas de ranuras desplazadas 90 grados y tener un sensor para cada fila de ranuras. Dependiendo del sentido de rotación, uno de los sensores detecta primero el cambio.

      Eliminar
  2. Cómo hago tengo un problema para que me ayude con una tarjeta

    ResponderEliminar
  3. Por lo que veo en el programa, para la lectura del sensor no es necesario usar las interrupciones externas, es decir lo pudiera hacer desde el loop cierto? con la función digitalread o se puede implementar de las dos maneras el mismo código?

    ResponderEliminar