¿Cómo conectar un codificador de cuadratura con PIC?

5

Estoy desarrollando un prototipo que utiliza un codificador de cuadratura para medir su desplazamiento lineal. El codificador está unido al cuerpo del prototipo y tiene una rueda en su eje. A medida que el prototipo avanza, el codificador mide la distancia lineal. Se han resuelto todos los problemas relacionados con la conversión entre unidades lineales / angulares.

La razón para medir la distancia con un codificador es que NECESITO saber cada vez que el prototipo ha viajado exactamente 1 mm (1 milímetro = 0.0393 pulgadas). Cada vez que se mueve 1 mm, PIC activa otro sistema.

La forma en que se hizo antes de comenzar a trabajar con él es mediante la lectura del codificador con un PIC (16F688) en sus puertos de E / S. Estaba muy bien, pero cuando agregué algunas funciones al código PIC, si la velocidad lineal del prototipo es mayor que ~ 1.77 in / s (~ 45 mm / s), el PIC comienza a fallar el recuento.

He intentado usar el IOC (interrupción al cambiar) del puerto A para leer la señal de cuadratura (canales A y B) pero no fue efectivo.

Sé que hay dsPIC's pero necesito resolver esto en mi tablero y solo tengo 14 pines para hacerlo, jajaja. Así que encontré este PIC16F1825 que tiene una frecuencia más alta (4x). ¿Podría ese (mi PIC baja frecuencia) ser mi problema principal?

Estaba pensando en usar las señales LFLS7183 UP / DOWN con el temporizador / contador de PIC u otro contador IC para reducir la cantidad de señalización a PIC. Funcionaría eso? ¿Qué contador debo usar? No tengo 8 pines en mi PIC para usar como en esos enlace .

Mi codificador no es mi problema, lo he comprobado y puede rastrear hasta 76 pies / s para el radio de mi rueda.

    
pregunta Bergamin

6 respuestas

11

Ha omitido toda la información importante acerca de qué tan rápido entrarán los pulsos, por lo que asumiré que en el peor de los casos, los pulsos siguen siendo lo suficientemente lentos para que el firmware escrito correctamente se capture.

He encontrado algunos trucos para hacer la decodificación en cuadratura en el firmware:

  1. No intente capturar cambios individuales, haga encuestas a intervalos regulares. Supongamos que el codificador se puede atascar directamente en la transición para cualquier borde, y ese borde puede por lo tanto rápidamente vacilarse. Esto haría un lío de cualquier interrupción en la técnica de cambio.

    Con el sondeo regular, puede ajustar el sistema cuidadosamente durante cuánto tiempo desea dedicar a la rutina de interrupción. El límite superior de la velocidad del codificador también es bien conocido, y en realidad no es más lento que en el peor de los casos con la interrupción del método de cambio de todos modos. Se garantiza que el método de sondeo funcionará correctamente hasta una velocidad máxima de movimiento que puede calcular fácilmente. El método de interrupción de cambio se degrada de forma impredecible ya que hay rebote en las transiciones.

  2. Siempre decodifica la posición 4x completa. No trates de mostrarse tontas y hacer cosas estúpidas como contar +1 cuando A hace la transición mientras B es alto, etc. Estos "atajos" son en realidad más difíciles de implementar y tienen casos de esquina que lo meten en problemas. Incluso si los niveles superiores solo desean conocer la posición en un solo ciclo completo, se mantendrá fuera de problemas descodificando la nueva posición de cada cambio de estado.

  3. Descodificar utilizando una tabla de búsqueda. Cada interrupción, toma una instantánea del estado actual de las dos líneas del codificador. Esto, junto con la instantánea de la interrupción anterior, es de 4 bits de datos. Desde el estado anterior y el nuevo estado, puede saber si el recuento 4x se mantuvo igual, o aumentó o subió 1. Ya que solo hay 16 casos posibles, puede usarlos para enviar desde una tabla. Hay 4 casos para cada uno de permanecer igual, +1 y -1.

    También hay 4 casos en los que el conteo ha cambiado en 2 que requieren un manejo especial. Un cambio de 2 significa que se perdió una transición y el codificador se está moviendo rápidamente. Al observar solo el estado antiguo y el nuevo, no se sabe si avanzó 1/2 ciclo o hacia atrás. Tenga en cuenta que 1/2 ciclo es un conteo de +2 o -2 en este sistema. La forma en que trato con esto es mantener una última bandera de dirección conocida. El código que hace +1 y -1 establece esta bandera de acuerdo con la dirección conocida. Cuando obtiene un paso de 2, asume que va en la misma dirección que el último paso de 1. Es una suposición bastante buena considerando la inercia de los sistemas mecánicos reales.

    En realidad, por lo tanto, realmente tiene 5 bits de información para procesar cada interrupción, los 2 niveles de línea del codificador anteriores, los nuevos niveles de línea del codificador y la última dirección conocida. Por lo tanto, para obtener la máxima velocidad, esta es una tabla de 32 entradas y maneja cada caso posible con código explícito. El código para cada uno de los casos agrega de -2 a +2 a la posición actual y posiblemente actualiza la bandera de dirección conocida.

Como puede ver, solo se necesitan algunas instrucciones por cada interrupción de sondeo. Su PIC (16F1825) puede funcionar a una velocidad de reloj de hasta 32 MHz, que es una velocidad de instrucción de 8 MHz. Digamos que configura una interrupción cada 50 instrucciones, lo cual es mucho más de lo necesario para hacer lo que describí anteriormente. Eso significa que puedes sondear a 160 kHz. Dado que el codificador puede cambiar hasta 1/2 ciclo por interrupción, esto admite hasta 80 kHz de velocidad de ciclo completo del codificador.

    
respondido por el Olin Lathrop
3

Hice un proyecto similar recientemente usando un microcontrolador Freescale. Hice uso de la capacidad de captura con temporizador para capturar la hora de los eventos, sin tener que depender de que se produzca una interrupción (por ejemplo, interrupción en el cambio) precisamente cuando ocurrió el evento. Su rutina de interrupción solo lee y almacena un valor de contador, y el resto del cálculo es el domo en el código de nivel básico.

Lo verifiqué, y el PIC16F1825 también tiene esta capacidad. Sección 24.1 (Modo de captura) de la hoja de datos que descargué:

  

El modo de captura hace uso del recurso Timer1 de 16 bits. Cuando un evento   ocurre en el pin CCPx, el par de registro CCPRxH: CCPRxL de 16 bits   captura y almacena el valor de 16 bits del par de registros TMR1H: TMR1L,   respectivamente. Un evento se define como uno de los siguientes y es   configurado por el CCPxM < 3: 0 > bits del registro CCPxCON:

     

• Cada borde descendente

     

• Cada flanco ascendente

     

• Cada cuarto borde ascendente

     

• Cada 16º flanco ascendente

     

Cuando se realiza una captura, la solicitud de interrupción   Se establece el bit de bandera CCPxIF del registro PIRx. La bandera de interrupción debe   Se borra en el software. Si se produce otra captura antes del valor en   Se lee el par de registro CCPRxH, CCPRxL, el antiguo valor capturado es   sobrescrito por el nuevo valor capturado.

Aún tienes que lidiar con los valores capturados lo suficientemente rápido para evitar perder un evento.

    
respondido por el tcrosley
2

Use el puerto B para detectar el cambio de borde para los pulsos del codificador. Debe administrar el software para leer los impulsos, ya sea que el codificador gire CW o CCW.

    
respondido por el narendra
1

Su problema es que las interrupciones de cambio de pin generadas por el codificador están ocurriendo demasiado rápido para que su software las maneje. Esto es probablemente porque su controlador de interrupciones se ejecuta demasiado tiempo. La secuencia de eventos es probablemente algo como:

  1. Movimientos del eje
  2. El codificador produce un flanco ascendente
  3. Se produce una interrupción de cambio de pin
  4. El controlador de interrupción de cambio de pin comienza
  5. El eje se mueve de nuevo antes de que finalice el manejador de interrupciones
  6. Se genera otra interrupción, pero no se maneja porque todavía estás manejando la última
  7. El controlador de interrupción de cambio de pin finaliza, borrando el indicador de interrupción
  8. La segunda interrupción nunca se maneja

Así es como se pierden las interrupciones a alta velocidad: la siguiente interrupción se produce antes de que termine de manejar la primera y nunca se maneje.

Primero, no debes hacer nada que lleve mucho tiempo en un controlador de interrupciones. Los manejadores de interrupciones deben ser lo más cortos posible para evitar el problema que está viendo en este momento. Probablemente esté tratando de hacer todo bajo el sol en su controlador. No lo hagas

Segundo, debes cambiar a un método menos pesado de software para leer el codificador. Si tiene un temporizador libre, puede usarlo para medir el desplazamiento de su eje. Si no te importa la dirección o la velocidad del eje , puedes medir el desplazamiento de tu eje en intervalos de 1 mm haciendo lo siguiente:

  1. Calcule cuántos conteos de codificador hay en 1 mm. Esperemos que sea un número bastante grande, en los 100 aproximadamente
  2. Conecte el codificador a una señal de reloj externa de uno de sus temporizadores: en el 16F88 es probable que sea preferible usar el temporizador 1, ya que puede funcionar como contador.
  3. Configure el temporizador para que funcione como contador, sea controlado por el reloj externo e interrumpa en caso de desbordamiento.
  4. Cargue el registro de conteo del temporizador con un valor de MAX - (número de conteos del codificador en 1 mm). El temporizador 1 es un temporizador de 16 bits, por lo que MAX es 0xFFFF.
  5. Inicia el temporizador y habilita las interrupciones.
  6. Cada vez que su temporizador se desborda, en el controlador, vuelva a cargar el registro de conteo con el valor original de MAX- # count in 1mm

Ahora, cada vez que su temporizador se interrumpe, su eje se habrá movido 1 mm. Esto no es perfecto: solo le importa que su eje se mueva 1 mm, pero no tiene idea de en qué dirección se movió el eje ni qué tan rápido va. Sin embargo, este es un método rápido y fácil de obtener una interrupción cuando el eje se mueve 1 mm en cualquier dirección.

    
respondido por el AngryEE
1

Sé que usted dijo explícitamente que solo tiene 14 pines para resolver su problema, pero no entiendo si esto está relacionado con la cantidad de estado real que tiene el PCB o si se trata de una junta heredada. Si esto se debe a un estado real, puede usar un dsPIC33FJ12MC201 , que es una parte de 20 pines. , no muy lejos de su límite de 14 pines, e incluye un módulo QEI que haría su vida mucho más fácil; quizás puedas exprimir esta parte en tu tablero.

Espero que esto ayude.

    
respondido por el Malife
-1

¿Era simple tu PIC ISR?

  •   

    salto de cálculo en función del valor de cuadratura

  •   

    devuelve +1 o -1 o 0

  •   

    luego agregue al valor presente.

Debería poder manejarlo, creo ...

.... cualquier metastato? luego trabe los valores de entrada.

Si todavía nogo. Luego use un CPLD con contadores arriba / abajo y cambie a PIC en un pin de E / S en serie. Elija binario o decimal como desee.

    
respondido por el Tony EE rocketscientist

Lea otras preguntas en las etiquetas