Cómo manejar el desbordamiento del codificador rotatorio

0

Estoy utilizando un codificador giratorio magnético (AS5048B) para detectar el ángulo de rotación de un eje del motor. Esto se envía a un bucle pid para calcular el valor de PWM para el control de posición del motor. El codificador tiene una salida de 14 bits. Da una salida de 0 - 16383 que luego se desplaza a la derecha en 4 para obtener un rango de 0 - 1023.

Cuando damos valores más cercanos a 1023, el valor del sensor vuelve a 0 después de una rotación completa y el error pid llega a valores enormes que dan como resultado movimientos inestables del motor. Supongamos que mi posición actual es 10 y el punto de ajuste es 1023. El error es 1023 - 10 = 1013 y el motor comienza a moverse hacia 1023 para disminuir el error. Cuando llega a 1023 a veces se sobrepasa y vuelve a un valor de 0, lo que nos da un valor PWM incorrecto de 1023 (1023 - 0). ¿Hay alguna solución para este problema?

Detalles de la implementación: - La configuración de la experimentación consiste en un motor de CC con engranaje de 60 RPM, un puente H (VNH5019) y un codificador giratorio magnético (AS5048B). El puente H tiene una entrada PWM para control de velocidad y otros 2 pines para control de dirección. Es un codificador absoluto que proporciona una salida de 14 bits correspondiente a 0 - 360 grados de rotación del eje del motor y actúa como una señal de realimentación para la planta. La función de actualización PID se escribe como un temporizador periódico que se interrumpe con una frecuencia de 10 KHz. Dentro del ISR, leí el punto de ajuste de un codificador rotatorio y la señal de realimentación del codificador magnético. Luego se calcula un error, se generan los valores PWM correspondientes y se envían al IC del puente H para cambiar la posición del eje del motor para ese error. Debido a la naturaleza de los bucles PID, el motor comienza a girar y cuando el error se acerca a cero, el valor de PWM también se acerca a 0, deteniendo así el motor en el punto de ajuste. Mi plan es hacer que este motor sea un servo de posición de 0 a 359 grados para las aplicaciones normales (y un servo de 0 a 180 grados para las aplicaciones de servos de hobby en el futuro).

Lo intenté con un controlador P solo. Funciona bien en todas las posiciones excepto el punto de desbordamiento. Dado que el error se calcula como la diferencia entre el punto de ajuste y la entrada, un desbordamiento hace que el valor del error sea extremadamente alto. El motor piensa que necesita aplicar esa cantidad de PWM (que disminuye a medida que el error se acerca a 0) para alcanzar esa posición. El resultado neto es un motor que va de 0 a 359 grados (cuando el punto de ajuste es un valor correspondiente a 359 grados), se desborda en 1 grado y regresa a 359, repitiendo así el proceso infinitos veces.

    
pregunta Supreeth

2 respuestas

1

Usar módulo aritmético.

// Pseudo-code
// error
error = (setPoint + 512 - currPos) % 1024 - 512;

Este código cambia el punto de ajuste de {0 .. 1023} a {512 .. 1535}, resta la posición real y obtiene el módulo. La respuesta estará en el rango de 0 a 1023, pero tendrá un desplazamiento positivo de 512 que se restará. El error resultante estará en el rango {-512 .. 511}.

  

Supongamos que mi posición actual es 10 y el punto de ajuste es 1023. El error es 1023 - 10 = 1013 ...

error = (setPoint + 512 - currPos) % 1024 - 512;
// Calculation
error = (1023 + 512 - 10) % 1024 - 512
      = 1525 % 1024 - 512
      = 501 - 512
      = -11

Actualización 1.

Parece que desea que la salida engranada se ejecute de 0 ° a 360 ° pero que el conjunto podría sobrepasarse ligeramente a 360 ° y, supongo, a 0 °. La única forma de manejar esto con su control proporcional es convertir su codificador en software en un codificador multivuelta. Esto significa realizar un seguimiento de sus revoluciones y permitir que su valor "total" se ejecute desde, por ejemplo, -90 ° a + 450 °.

Figura 1. Diagrama de flujo para las pruebas de transición 0 °.

    
respondido por el Transistor
0

Una solución alternativa que uso todo el tiempo es ignorar el valor real del codificador en mi proceso. En lugar de eso, pregunto el valor del codificador cada x microsegundos (o milisegundos, o lo que sea), y determine la diferencia en el recuento desde el último escaneo, y lo agrego a mi registro de conteo real. Solo determine la diferencia en cada escaneo usando matemáticas enteras con signo. En su caso, solo vería los 8 bits más bajos del valor del codificador como un byte firmado.

    
respondido por el R Drast

Lea otras preguntas en las etiquetas