Estoy tratando de generar un ángulo continuo basado en la salida de los dos potenciómetros que están dentro de mi dispositivo. Los potenciómetros están desplazados 180 grados y son capaces de girar continuamente. ¿Cómo puedo utilizar las señales de ambos potenciómetros para determinar la dirección y al mismo tiempo obtener una función de ángulo continuo? Entiendo cómo hacer esto con codificadores rotatorios, pero estoy teniendo dificultades para hacer lo mismo con este dispositivo.
Respuestas
¿Demasiados anuncios?Habrá un hueco en cada uno de los dos potes cerca de donde (idealmente) cambian instantáneamente de 95% a 5% o viceversa dependiendo de la dirección de rotación.
Sugiero utilizar el rango central de cada uno, cambiando de uno a otro cuando el actual salga del centro del rango, en este caso sería 50% +/- 22,5%. Suele haber un pequeño fallo en la transición. Si necesitas eliminarlo, puedes mezclar las dos lecturas con una función que pondere las dos lecturas de forma variable. Lo que se quiere es ignorar la salida que está demasiado cerca de la transición, pero mezclar las dos entradas en el rango intermedio.
No necesitas dos potenciómetros para determinar la dirección. No son codificadores en cuadratura. La razón por la que necesitas dos señales de un codificador en cuadratura (que están desfasadas 90°, no 180°) es porque emiten pulsos que no llevan ninguna información de posición inherente.
Los potenciómetros dan su posición absoluta cada vez que se toma una lectura de ellos. Sólo necesitas un potenciómetro para determinar la dirección. Basta con comparar la posición actual con la anterior.
En cuanto al seguimiento de la dirección y los cambios acumulativos de ángulo, "sólo" hay que calcular la diferencia de ángulo entre la posición actual y la pasada y añadirla a un contador que lleve la cuenta del desplazamiento angular.
Esto parece bastante sencillo y si supieras lo que estás haciendo entonces todo lo que ya he dicho tiene sentido. Donde te quedas atascado es probablemente en la siguiente parte: Realmente calcular la diferencia de ángulo entre la posición actual y la pasada de una manera que refleje la dirección real de rotación.
Aquí hay dos dificultades:
- Entre dos puntos de una circunferencia, siempre se pueden tomar dos caminos entre los puntos. ¿Cuál es el que tomó realmente la rotación?
- Incluso si supieras qué camino elegir entre los dos puntos, ¿cómo calcular la distancia entre los dos puntos si el camino cruza el "punto envolvente" (es decir, cero grados, 360 grados, etc.)
Suponiendo que el muestreo sea lo suficientemente rápido en relación con la velocidad de rotación como para que el camino más corto alrededor del círculo sea efectivamente equivalente al movimiento entre la posición angular anterior y la actual, entonces el camino más corto de los dos recorridos es siempre el representativo del ángulo recorrido.
Por lo tanto, necesitarás un código que decida qué camino alrededor del círculo es el más corto. La forma más directa de hacerlo es calcular literalmente la distancia de ambos caminos (uno de los cuales siempre pasará por cero), y comparar los dos.
Calcular la trayectoria entre dos puntos alrededor de una circunferencia es fácil si la trayectoria no atraviesa el ángulo envolvente. Basta con restar sus posiciones angulares. Pero es más complicado si la trayectoria cruza el punto envolvente.
Lo que hay que hacer es hallar la distancia de un punto al cero, luego hallar la distancia del otro punto al cero y sumar esas distancias. Por supuesto, al encontrar estas dos distancias entre cada punto y el cero también se elige el camino más corto alrededor del círculo, ya que forman el camino más corto alrededor del círculo entre esos dos puntos. En este caso, es fácil saber cuál es el camino más corto, ya que basta con comparar la posición angular con 180 grados para saber en qué dirección se encuentra el camino más corto hacia el cero.
Es difícil, lo sé. Pero, en realidad, lo que tienes que hacer es sentarte con lápiz y papel, dibujar unos cuantos círculos con dos puntos en ellos en diferentes escenarios (el camino más corto no pasa por cero, el camino más corto pasa por cero, etc.) y resolver cada caso. A continuación, escribe un código de bifurcación para cada caso.
También se puede utilizar la matemática de módulos para obtener una solución matemáticamente rigurosa, pero es mucho más abstracta.
Lo que finalmente hice en mi código, fue escribir una biblioteca que hacía clases de un "tipo entero envolvente" con sobrecarga de operadores donde cada entero tenía tres valores: su valor real, valor máximo, y un valor mínimo (que es a menudo, pero no siempre cero en aras de la generalidad). Esto formaba un círculo de números alrededor del cual se desplazaba el valor real a medida que se le sumaba o restaba, provocando el desbordamiento o el desbordamiento por defecto. La resta en este caso se hacía para devolver siempre la longitud del camino más corto. Tanto la suma como la resta también envolvían el resultado si era necesario. Yo estaba usando esas operaciones mucho en mi código y era bastante difícil de manejar que y no quería tener código distinto cada vez que apareció. Eso habría sido inmanejable.
EDITAR: Si quieres combinar los dos potenciómetros de modo que se ignore el punto muerto alrededor de cero, es fácil una vez que tengas resuelto lo anterior. Sólo tienes que elegir el codificador en el que el camino más corto entre el punto pasado y el presente no pase por cero y calcular la longitud de ese camino. Luego añádelo a un contador. Puedes elegir si quieres que el contador envuelva entre 0 y 360 o que cuente hasta el infinito. O puedes simplemente calcular las distancias para ambos potenciómetros y promediarlas antes de añadirlas al contador, rechazando uno de los potenciómetros si su posición presente o pasada está demasiado cerca de cero.
Parte del problema parece ser el "desenvolvimiento" de la información de fase. La otra parte quizá sea la fusión de las lecturas de los dos recipientes.
Asumiendo que los dos potes son leídos por ADCs, y luego los resultados procesados en un MCU, lo siguiente puede parecer al principio un poco pesado y lento, pero es conceptualmente riguroso.
Una buena representación del ángulo es un número complejo. Se puede rotar continuamente, sin tener ninguna discontinuidad en el punto +/- 180.
Sugiero entonces primero mapear las lecturas del potenciómetro a números complejos. Esto implicaría un escalado y una búsqueda de seno y coseno. Para fusionar las dos lecturas de forma realmente nítida, se podría reducir la magnitud del número complejo cuando estuviera cerca de los extremos de la lectura del potenciómetro. Por ejemplo, tener una magnitud unitaria en el 50% medio del rango, y luego reducir a cero la magnitud en los extremos. Las dos lecturas angulares se combinan ahora promediando. El vector resultante estará más ponderado por el potenciómetro en la mitad de su rango, y la lectura final pasará suavemente de una a otra, sin discontinuidades.
Probablemente se podría lograr el mismo tipo de resultado con un simple procesamiento de ángulos, si acaso, e interpolación, con menos ciclos de máquina que los implicados en la generación de sen/cos, pero la ruta compleja es más clara y menos propensa a errores, y en mi humilde opinión algo más fría.