Usando codificadores rotatorios sin pines de interrupción

3

Primero un poco de fondo ..
Tengo 4 ruedas separadas en mi robot y un codificador en cada rueda. Estoy usando un arduino mega 2560 que solo tiene 6 pines de interrupción, cada código que he visto usa 2 líneas de interrupción por codificador o 1, pero no es tan preciso.

Mi idea:
Mi idea aquí es que los codificadores funcionan a alrededor de 300Hz a la velocidad máxima para mi robot, así que estoy usando una interrupción por desbordamiento del temporizador para leer todas las entradas a las que están conectados los codificadores a aproximadamente 1kHz, lo que también me da bastante tiempo (1 ms) ) para verificar si las entradas cambiaron y hacer mis cálculos y luego regresar de la interrupción.

Mi pregunta:
¿Mi pensamiento es correcto? ¿Podré leer correctamente la posición y los cambios del codificador? ¿Hay algo mejor que pueda hacer? ¿Hay alguna advertencia que deba tener en cuenta al tratar esto?

Actualización: De la discusión en los comentarios y respuestas actualmente tengo las dos alternativas siguientes:

  1. Apégate a la idea de sondeo (aumentar la frecuencia cuando sea necesario)
  2. Use una interrupción "compartida" disponible en cada pin (no sabía que era posible)
pregunta Pablo

4 respuestas

-1

Gracias a la sugerencia de Chris Stratton conseguí que esto funcionara correctamente. He utilizado un intterupts de cambio de pin ... con el enmascaramiento adecuado funcionó a la perfección :)

Gracias a todos por todas las sugerencias y experiencia.

    
respondido por el Pablo
0

Si realmente encuestas mucho más rápido de lo que se mueve el codificador, esto funcionará. Si es una buena idea, depende de qué tan rápido pueda moverse el codificador y de lo importante que es que no se pierdan los clics. Ciertamente lo odio cuando hago girar un dial para desplazarme por una larga lista de UI y se mueve lentamente hacia atrás, aunque no hay ningún daño real. Si el codificador recibe información de un motor, los clics que faltan podrían causar problemas mayores, como daños mecánicos.

Puede usar lógica dedicada para hacer un contador, o podría usar un microcontrolador diferente que tenga un codificador integrado en el periférico, pero para la mayoría de los propósitos, el sondeo está bien si lo hace lo suficientemente rápido.

    
respondido por el Evan
0

¿Ha considerado sondear muy rápido y destellar un par de 71451 con cuatro direcciones separadas para obtener el par de entradas que necesita, en forma de round robin (pero muy rápido)? Luego puede leer un bit de cada chip, uno por salida de codificador que se está abordando en este momento.

Esto reducirá el número de pines de entrada necesarios a dos.

    
respondido por el TomServo
0

todos están bien

Tienes que sobreexplotar cada codificador, lo que significa que la muestra es más rápida de lo que se están moviendo. Suponiendo que 300Hz es correcto. 1kHz es bastante rápido, suficiente espacio por si acaso. ¿Asumiendo un codificador de 2 pines? Sólo hay dos próximos estados válidos del estado actual, ¿sí? Actualice su posición según el estado actual y el siguiente (incremente una posición o disminuya, o cualquiera que sea su solución). Para cada rueda. valor almacenado en un global utilizado por la tarea de primer plano

si puede tenerlo, entonces cualquiera de los cambios de estado de gpio pines provoca una interrupción que también funciona, menos sobrecarga de interrupciones, pero si hay algún rebote en el cambio de estado, puede obtener múltiples interrupciones (con valores falsos). (Sobremuestreo también puede tener problemas de rebote).

Debes tener cuidado con las interrupciones y tu código. Compruebe la salida del compilador. Rusty en AVR pero los registros son 8 bit si? Las cargas y las tiendas parecen ser de 8 bits. Entonces, si tiene un contador de posición de 16 bits, su tarea forground está leyendo ese contador, lo que significa que tiene que hacer al menos dos instrucciones para obtener las dos partes de la variable global escrita por el isr y leída por la aplicación. La posición actual es 0x0FFF. Usted lee 0x0F, obtiene una interrupción, la posición cambia a 0x1000, regresa de la interrupción, la tarea inicial lee la segunda mitad 0x00 y cree que la posición es 0x0F00. 255 cuentas mal. Para un bucle de la tarea forground. Así que debes tener cuidado de que esto no suceda, hay muchas maneras generales de evitarlo, pero específico para este objetivo, no lo recuerdo. o puede hacer cálculos matemáticos de manera que su posición por rueda se ajuste a un byte.

sondeo, siempre y cuando el sondeo sea lo suficientemente rápido, que funcione bien (así que rebotar si hay alguno en su codificador no es correcto, supongamos que no tiene ninguno). a veces tienes que sondear más de una vez a través del bucle, haz que sea una función

while(1)
{
  do stuff
  poll_wheels();
  do stuff
  poll_wheels();
  ...
  poll_wheels();
}

o tal vez el bucle del peor de los casos sea lo suficientemente rápido

while(1)
{
   poll_wheels();
   do stuff.
}

necesita lidiar con los estados no válidos de alguna manera, tal vez durante el desarrollo, si alguna vez ve un estado inválido, establezca una variable de pánico, simplemente detenga los motores y todo y o establezca un led o algo así para indicar visualmente que esto sucedió. no es mucho lo que puede hacer, pero aún así debería tener un código adicional que indique que si el estado actual de un codificador no es un estado próximo al último estado de ese codificador, entonces, aparte de configurar la variable de alarma / led / bit / contador, no actualice el posición pero use el estado actual como el último estado para la siguiente prueba. simplemente simule desde una perspectiva de posición que no se produjo ningún movimiento, sino que se encuentra en una nueva posición del codificador. Si tiene codificadores de tres bits o más, puede ver si se saltó uno y saltó dos, pero si es solo un codificador de dos bits, no puede hacerlo necesariamente.

    
respondido por el old_timer

Lea otras preguntas en las etiquetas