2009-07-21 12 views
8

La versión rápida:Algoritmo para determinar la "diferencia de fase" efectiva entre dos señales con diferentes frecuencias?

Qué algoritmo podría utilizar para determinar la "diferencia de fase" entre dos señales de onda cuadrada con diferentes frecuencias, si la única información que tengo es el tiempo en el que cada flanco de subida ¿ocurre?

La versión detallada:

Estoy trabajando en un proyecto de software embebido, y me he encontrado con un problema interesante. Estoy recogiendo datos de dos hall-effect speed sensors, que están cada uno dirigido a una de las dos engranado engranajes, como se muestra en el siguiente diagrama:

meshed gears and pulse signals http://img291.imageshack.us/img291/4905/gears.png

nota:
Como Jaime señalado, las señales en este el diagrama en realidad tendría frecuencias idénticas. El hardware real tiene varias etapas de engranaje más entre los dos engranajes objetivo, algunos de los cuales están conectados por ejes en lugar de dientes engranados, por lo que I do terminan con dos ondas cuadradas que tienen diferentes frecuencias, y la relación entre ellas sigue siendo una constante. Quería simplificar el diagrama para llegar a la esencia del asunto, pero parece que lo simplifiqué demasiado.
/nota

La salida sensores de velocidad de una señal de onda cuadrada cuya frecuencia es directamente proporcional a la velocidad de rotación de cada engranaje. Los bordes ascendentes (y descendentes) de la onda cuadrada se producen cuando los bordes anteriores (y posteriores) de un solo diente del engranaje pasan por el sensor.

Sé cuántos dientes hay en cada engranaje, y de acuerdo con esta información, puedo medir con precisión la velocidad de rotación de cada engranaje según la frecuencia de las señales de onda cuadrada.

Para medir las frecuencias, tengo cada señal del sensor de velocidad conectada a un pin del temporizador de captura de alta velocidad en el controlador incrustado. Los temporizadores de captura detectan automáticamente los bordes ascendentes de la señal de onda cuadrada, cargan un registro con un valor que representa el momento en que se produjo la transición y desencadenan una interrupción. Los puntos de captura para cada señal se indican en amarillo en el diagrama. La rutina de servicio de interrupción es como la siguiente:

struct 
{ 
    long previousTime; 
    int frequency; 
} 
sensors[2]; 

void CaptureTimer_Interrupt(int channel, long transitionTime) 
{ 
    long timeDifference = transitionTime - sensors[channel].previousTime; 
    sensors[channel].frequency = CONVERSION_FACTOR/timeDifference; 
    sensors[channel].previousTime = transitionTime; 
} 

Lo que me gustaría hacer:

Me gustaría ser capaz de detectar pequeñas diferencias en el relativa momento de estos dos onda cuadrada señales. Yo llamo a esto la "diferencia de fase" por falta de un término mejor. Si las dos señales tuvieran exactamente la misma frecuencia, esto sería sencillo, y phase difference sería el término correcto para usar.

Esto es lo que quiero decir: si tuviera que grabar las dos señales durante un largo período de tiempo, y luego artificialmente reducir (o "estirar") la señal de alta velocidad (azul) por un factor de 16/9, tendría la misma frecuencia que la señal de menor velocidad (roja), y las dos señales tendrían alguna diferencia de fase medible, es decir, la diferencia de tiempo entre una interrupción de señal roja y una interrupción de señal azul.Me gustaría calcular esta misma diferencia de tiempo (o algo equivalente) sin tener que registrar las señales durante un largo período de tiempo. Los recursos están limitados en el controlador integrado, por lo que no es una opción guardar grandes matrices de tiempos de transición pasados.

¿Alguien ha topado con esto antes? El proyecto real tiene varios arreglos de engranajes y sensores, por lo que estoy buscando un algoritmo elegante que pueda reutilizar. ¡Gracias por adelantado!

+0

ya que los 2 engranajes están interbloqueados. ¿Cómo sugerirías que pueden correr "fuera de fase"? – Toad

+0

tensión en las piezas, desgaste en los dientes del engranaje, pequeños efectos en el mundo real. Esto es (por supuesto) un ejemplo simplificado. El sistema real puede tener otras etapas de engranaje entre los dos en los que están montados los sensores. Todas las pequeñas tolerancias entre juegos de dientes pueden sumar una buena cantidad de juego. Tiene razón en que los engranajes no pueden "sustancialmente" "desfasar" sin una avería importante en el sistema físico. Lo que intento medir son pequeñas variaciones de la norma. –

+1

Si "estira" una señal, necesita un origen (t = 0). Eso es arbitrario, pero esa elección determinaría su diferencia de fase. Por lo tanto, incluso si creara una diferencia de fase "verdadera" de esa manera, su valor sería arbitrario debido a su elección de t = 0 – MSalters

Respuesta

2

La señal general, es decir, la señal que obtiene cuando agrega el rojo y el azul, tiene una longitud de fase de 16 veces la señal azul y 9 veces la señal roja. Podrías medir la diferencia de tiempo entre cada 16º azul y cada 9º flanco ascendente rojo.

Supongo que lo que quiere medir es el desgaste de los engranajes. Creo que esta medida podría verse influida (introduciendo ruido) por la tolerancia de los engranajes, si no hay una tracción uniforme.

0

Creo que lo mejor que se puede hacer es crear un diagrama X-Y de todos sincronización de pares de dientes. Usted arbitrariamente escogería un diente en cada diente como T = 0 ..

+0

Eso suena prometedor, sería una bonita imagen si nada más :) – Tom

1

Creo que es incluso más simple que eso.

Cada 16 * 9 muestreos (del gran engranaje) las ruedas están exactamente en el mismo lugar donde comenzaron.

Así que lo que hacemos es la siguiente:

  • elegir cualquier punto en el tiempo con un muestreo en el gran engranaje. Mida la cantidad de tiempo antes de probar el pequeño diente también. Recuerda este valor

  • cada 16 * 9 muestras del gran engranaje (¿por qué suena esto dudoso?) Haga la misma medición otra vez y compárela con su valor base. Cuando el tiempo comienza a cambiar, tienes un problema.

R

+0

Con las advertencias de mis comentarios a la pregunta OP, creo que no es suficiente hacer una medición en cada ciclo: si uno de los engranajes involucrados pierde un diente que no está funcionando en el momento de la medición, nunca lo notarías. Creo que necesita alguna comparación entre las señales ** enteras **, que no se ve alterada por las escalas locales, es decir, no desea que las variaciones instantáneas de velocidad del eje impulsor le den una falsa alarma. Experimentaría con algo parecido a la correlación cruzada entre la entrada y la salida, que probablemente sea inviable con las limitaciones de almacenamiento ... – Jaime

1

Estoy teniendo algunos problemas para visualizar la configuración de hardware. Y el comportamiento que estás tratando de detectar. Un eje deslizándose? Dientes vistiendo?

En cualquier caso, escribiría una simulación de la situación para poder obtener algunos resultados, tal vez exagerados, sin ruido contra el cual probar los algoritmos.

Los algoritmos Me prueba sería variaciones de los siguientes:

Assign signal with lowest frequency to A 

Time A’s rising edge. => Ta1 

Time the next B rising edge . => Tb1 

Calculate time Tb1 – Ta1 => dT1 

Time next A’s rising edge. => Ta2 

Time the next B rising edge. => Tb2 

Calculate time Tb2 – Ta2 => dT2 

Calculate second order difference dT2 – dT1 => d2T1 

Repeat precious steps to get another second order difference => d2T2 

If sign of d2T1 and d2T2 are different, 

repeat previous steps 

else sign of d2T1 and d2T1 are same 

    calculate third order difference d2T2 – d2T2 => d3T1 

Repeat previous steps to get another 3rd order difference => d3T2 

If d3T2 – d3T1 > max noise 

    Raise alarm 
+0

Esto merece un voto positivo, pero he llegado al límite por hoy. Voy a votar en 5 horas más o menos. –

+0

... y ahí está. +1 –

2

Ya que estamos hablando de "fase", entonces parece razonable para medir el "golpe" que se produce cuando las dos formas de onda se refuerzan mutuamente otro.

Algo como esto, tal vez:

void cog_phase_monitor2(int cog, int t) 
{ 
    static int last_a, last_b, last_beat, last_beat_delta = 0;; 
    int beat = 0; 
    if(cog == 1) { 
     if(t - last_b < 1) 
      beat = 1; 
     last_a = t; 
    } 
    if(cog == 2) { 
     if(t - last_a < 1) 
      beat = 1; 
     last_b = t; 
    } 
    if(beat) { 
     printf("**** delta beat %d \n",t-last_beat); 
     if(last_beat_delta) { 
      if(last_beat_delta != t-last_beat) { 
       printf("!!!Warning beat just changed !!!\n"); 
       last_beat_delta = 0; 
      } 
     } else { 
      last_beat_delta = t-last_beat; 
     } 
     last_beat = t; 
    } 

} 

Ahora bien, si tapar esto en una simulación de dos dientes, uno de 9 dientes y una de 16 dientes, tanto que giran a 10 revoluciones por segundo

B at 6 msecs 
A at 11 msecs 
B at 12 msecs 
B at 18 msecs 
A at 22 msecs 
B at 24 msecs 
B at 30 msecs 
A at 33 msecs 
B at 36 msecs 
B at 42 msecs 
A at 44 msecs 
B at 48 msecs 
B at 54 msecs 
A at 55 msecs 
B at 60 msecs 
A at 66 msecs 
B at 66 msecs 
**** delta beat 66 
B at 72 msecs 
A at 77 msecs 
B at 78 msecs 
B at 84 msecs 
A at 88 msecs 
B at 90 msecs 
B at 96 msecs 
A at 99 msecs 
B at 102 msecs 
B at 108 msecs 
A at 110 msecs 
B at 114 msecs 
B at 120 msecs 
A at 121 msecs 
B at 126 msecs 
A at 132 msecs 
B at 132 msecs 
**** delta beat 66 
B at 138 msecs 
A at 143 msecs 
B at 144 msecs 
B at 150 msecs 
A at 154 msecs 
B at 156 msecs 
B at 162 msecs 
A at 165 msecs 
B at 168 msecs 
B at 174 msecs 
A at 176 msecs 
B at 180 msecs 
B at 186 msecs 
A at 187 msecs 
B at 192 msecs 
A at 198 msecs 
B at 198 msecs 
**** delta beat 66 

Y ahora si añadimos un retardo de 1 ms a uno de los engranajes:

B at 6 msecs 
A at 11 msecs 
B at 12 msecs 
B at 18 msecs 
A at 22 msecs 
B at 24 msecs 
B at 30 msecs 
A at 33 msecs 
B at 36 msecs 
B at 42 msecs 
A at 44 msecs 
B at 48 msecs 
B at 54 msecs 
A at 55 msecs 
B at 60 msecs 
A at 66 msecs 
B at 66 msecs 
**** delta beat 66 
B at 72 msecs 
A at 77 msecs 
B at 78 msecs 
B at 84 msecs 
A at 88 msecs 
B at 90 msecs 
B at 96 msecs 
A at 99 msecs 
B delayed at 102 msecs 
B at 103 msecs 
B at 109 msecs 
A at 110 msecs 
B at 115 msecs 
A at 121 msecs 
B at 121 msecs 
**** delta beat 55 
!!!Warning beat just changed !!! 
B at 127 msecs 
A at 132 msecs 
B at 133 msecs 
B at 139 msecs 
A at 143 msecs 
B at 145 msecs 
B at 151 msecs 
A at 154 msecs 
B at 157 msecs 
B at 163 msecs 
A at 165 msecs 
B at 169 msecs 
B at 175 msecs 
A at 176 msecs 
B at 181 msecs 
A at 187 msecs 
B at 187 msecs 
**** delta beat 66 
B at 193 msecs 
A at 198 msecs 
B at 199 msecs 
B at 205 msecs 

esto parece una b esperanzador eginning :-)

0

Yo implementaría dos bucles bloqueados de fase en el software. Supongamos que una revolución del engranaje A corresponde a b revoluciones del engranaje B. Calcule el mínimo común múltiplo de a y b m: = lcm (a, b). Bloqueo de fase PLLa con engranaje A (con un factor de m/a) y PLLb con engranaje B (con un factor de m/b). Entonces ambos PLL deben tener la misma frecuencia. En consecuencia, las diferencias de fase deberían ser fáciles de detectar. Como tiene un controlador, solo calcula la convolución de las señales de dos fases bloqueadas. El máximo de la función de convolución le indica la diferencia de fase.

Cuestiones relacionadas