5 votos

Encoder de la rueda usando un sensor de infrarrojos

Hice un codificador rotatorio usando un sensor de infrarrojos y una rueda con rayos blanco y negro impresas. Todo parece funcionar pero me pregunto si hay una mejor manera a este código. Ideal parece una onda cuadrada a la señal IR y lo tengo buscando el flanco ascendente de cada onda. Entonces calcular el tiempo entre los bordes de levantamiento para el cálculo de RPM de la rueda.

int wheelPin = 11; // I/O pin for encoder
int count = 0; // number of encoder ticks 
bool rising = false; // bool for rising edge of encoder signal
double dt; // time between rising edges
long dtStore[2]; // FIFO array holding current and previous rising edge times
float rpm;

void setup(){
  Serial.begin(57600);
}

void loop() {
  int wheelVal = analogRead(wheelPin); // get encoder val

/* check to see if we are at a low spot in the wave.  Set rising (bool) so we know to expect a rising edge */

if (wheelVal < 200) {
  rising = true;
}

/* Check for a rising edge.  Rising is true and a wheelVal above 200 (determined experimentally)*/

if (rising && wheelVal > 200) {
   dtStore[0]=dtStore[1]; // move the current time to the previous time spot
   count++;
   dtStore[1] = millis(); // record the current time of the rising edge
   dt = dtStore[1]-dtStore[0]; // calculate dt between the last and current rising edge time
   rpm = (0.0625)/dt*1000*60; // RPM calculation
   rising = false; // reset flag
 } 
Serial.println(rpm);
}

5voto

Armandas Puntos 552

Hay dos cosas que usted debe hacer.

En primer lugar, aplicar un poco de hysterisis. En la actualidad, parece que está utilizando 200 como el umbral de subida y bajada de la dirección. Lo que usted siempre obtendrá con los sensores analógicos es un poco de ruido. Esto significa que, incluso durante un flanco de subida, en realidad, puede ver una pequeña caída de borde a veces. Usted podría incluso ver a cruzar el umbral hacia arriba, luego hacia abajo, luego hacia arriba otra vez!

Encoder Hysterisis

  • La línea verde muestra lo que usted espera que su sensor está produciendo.
  • La línea roja muestra lo que es probablemente la producción. En realidad, probablemente mucho peor que esta.
  • La línea morada es lo que quieres
  • La línea negra es lo que usted podría conseguir

Así que, cuando la señal está en aumento, el uso de 200 como su umbral. Y cuando la señal se cae, usar algo como 150 como un umbral.

En segundo lugar, se podría utilizar tanto los flancos ascendente y descendente para calcular su velocidad. De esa manera usted puede tener el doble de la tasa de actualización.

2voto

Karthik Puntos 66

Con respecto a una "mejor manera este código" usted podría utilizar Comparador Analógico que está en el chip Atmega. Funciona mediante la comparación de los voltajes que están presentes en dos de los pines del microcontrolador - AIN0 y AIN1. Añadir un potenciómetro que establece un umbral para la transición en AIN1, a continuación, conectar el sensor a AIN0. Cuando el voltaje del sensor está por encima de tensión establecidos por el potenciómetro, comparador Analógico puede ser configurado para un aumento de interrupción de añadir tu lógica para el mantenimiento de rutina por esta interrupción.

Otra forma de este código podría ser de uso externo de interrumpir la funcionalidad en Atmega - usted recibe una interrupción por flanco ascendente o descendente en algunos específicos pin del microcontrolador, pero usted tendría que hacer un acondicionamiento de señal con otro amplificador operacional para poder establecer el umbral y la histéresis.

Usted tendría que recurrir a la programación de un "AVR" nivel C para hacer todo esto en lugar de Arduino jerga.

Editar Usted todavía puede hacer que desde el entorno de desarrollo de Arduino, este es un sniplet sobre el uso de comparador analógico en arduino, sólo utiliza los define a partir de avr-libc directamente dentro del código de arduino:

void setup(){
  pinMode(7,INPUT);
  Serial.begin(9600);
  ACSR = B01011010; // comparator interrupt enabled and tripped on falling edge.
}

void loop(){
}

ISR(ANALOG_COMP_vect) {
  Serial.println("Interrupt Executed!")
}

2voto

user11925 Puntos 26

Yo estoy haciendo algo similar en el momento. Pero con dos differencs:

  • He de schmitt-trigger (74HCT14) entre la fuente de señal y el controlador
  • Yo no medir el tiempo entre dos bordes, pero yo cuento los bordes para una cierta cantidad de tiempo y calcular la RPM de la división del número de aristas y de tiempo

A mí me parece, que la generación de una constante de la frecuencia de interrupción (como 1Hz) y el conteo de los pulsos es más fácil y más robusto que la medición de una vez en ms de intervalo.

Pero tal vez este enfoque no se aplica a su diseño.

1voto

Flory Puntos 1911

Así como la histéresis para la señal analógica de nivel de transiciones, usted podría querer usar un de-rebote algoritmo una vez digitalizados. Se establece de rebote temporizadores para ser un valor pequeño en relación a la espera de la conmutación de la velocidad a la máxima velocidad de rotación.

E. g. Para 4 radios, hasta un máximo de 120 rpm espera un 8 Hz salida de onda cuadrada. Con un período de 125 ms, usted puede permitirse el lujo de rebote temporizadores de decir 10ms en cada transición. La idea es mantener 10ms "pequeño" en relación a su 62.5 ms tiempos de espera. E. g. un L-H de transición que podría obligar a una 1 de salida de 10ms, un H-L de transición que podría obligar a una 0 de salida para 10ms etc.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X