2009-07-21 10 views
8

La versione breve:Algoritmo per determinare l'effettiva "differenza di fase" tra due segnali con frequenze diverse?

Nei algoritmo ho potuto usare per determinare la "differenza di fase" tra due segnali ad onda quadra con diverse frequenze, se l'unica informazione che ho è il momento in cui ogni fronte di salita si verifica?

La versione dettagliata:

Sto lavorando su un progetto di software embedded, e mi sono imbattuto in un problema interessante. Sto raccogliendo dati da due hall-effect speed sensors, ciascuno dei quali è rivolto a una delle due maglie ingranaggi, come mostrato nello schema seguente:

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

nota:
Come Jaime indicate, i segnali in questo diagramma avrebbe in realtà le stesse frequenze. Il vero hardware ha diverse fasi di cambio tra i due ingranaggi di destinazione, alcuni dei quali sono collegati da alberi invece di denti a maglie, quindi io do finiscono con due onde quadre che hanno frequenze diverse, e il rapporto tra loro è ancora un costante. Volevo semplificare il diagramma per arrivare alla carne della questione, ma sembra che l'abbia semplificato troppo!
/nota

L'uscita sensori di velocità di un segnale ad onda quadra la cui frequenza è direttamente proporzionale alla velocità di rotazione di ciascuna ruota dentata. I bordi ascendenti (e discendenti) dell'onda quadra si verificano quando i bordi iniziali (e finali) di un singolo ingranaggio passano accanto al sensore.

So quanti denti ci sono su ciascuna marcia e sulla base di queste informazioni sono in grado di misurare con precisione la velocità di rotazione di ogni ingranaggio in base alla frequenza dei segnali a onda quadra.

Per misurare le frequenze, ogni segnale del sensore di velocità è collegato a un pin del timer di acquisizione ad alta velocità sul controller incorporato. I timer di acquisizione rilevano automaticamente i fronti di salita del segnale a onda quadra, caricano un registro con un valore che rappresenta il momento in cui si è verificata la transizione e attivano un interrupt. I punti di cattura per ciascun segnale sono indicati in giallo sul diagramma. La routine di servizio simile a questa:

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; 
} 

Quello che vorrei fare:

Mi piacerebbe essere in grado di rilevare piccole differenze nella relativa tempistica di questi due un'onda quadra segnali. La chiamo "differenza di fase" per mancanza di un termine migliore. Se i due segnali avessero la stessa identica frequenza, ciò sarebbe semplice e phase difference sarebbe il termine corretto da utilizzare.

Ecco cosa voglio dire: Se dovessi registrare i due segnali per un lungo periodo di tempo, e poi rallentare artificialmente verso il basso (o "allungare") il segnale ad alta velocità (blu) di un fattore 16/9, avrebbe la stessa frequenza del segnale a bassa velocità (rosso), e i due segnali avrebbero una differenza di fase misurabile, cioè la differenza di tempo tra un interrupt di segnale rosso e un interrupt di segnale blu.Vorrei calcolare la stessa differenza di tempo (o qualcosa di equivalente) senza dover registrare i segnali per un lungo periodo di tempo. Le risorse sono limitate sul controller incorporato, quindi la memorizzazione di array di grandi dimensioni con tempi di transizione passati non è un'opzione.

Qualcuno si è imbattuto in questo prima? Il progetto attuale ha diverse configurazioni di ingranaggi e sensori, quindi sto cercando un algoritmo elegante che possa riutilizzare. Grazie in anticipo!

+0

poiché i 2 ingranaggi sono interbloccati. Come suggeriresti che possano essere "fuori fase"? – Toad

+0

stress sulle parti, usura sui denti degli ingranaggi, piccoli effetti del mondo reale. Questo è (ovviamente) un esempio semplificato. Il sistema reale può avere altri stadi di ingranaggi tra i due su cui sono montati i sensori. Tutte le piccole tolleranze tra i denti possono sommarsi a una buona dose di gioco. Hai ragione nel senso che gli ingranaggi non possono ottenere * sostanzialmente * "fuori fase" senza un grave guasto nel sistema fisico. Quello che sto cercando di misurare sono lievi variazioni rispetto alla norma. –

+1

Se si "allunga" un segnale, è necessaria un'origine (t = 0). Questo è arbitrario, ma quella scelta determinerebbe la differenza di fase. Quindi, anche se dovessi creare una differenza di fase "vera" in questo modo, il suo valore sarebbe arbitrario a causa della tua scelta di t = 0 – MSalters

risposta

2

Il segnale generale, ovvero il segnale che si ottiene quando si aggiungono il rosso e il blu, ha una lunghezza della fase 16 volte il blu e 9 volte il segnale rosso. È possibile misurare la differenza di tempo tra ogni 16 ° blu e ogni 9 ° fianco rosso in aumento.

Immagino che quello che vuoi misurare sia l'usura degli ingranaggi. Penso che questa misura possa essere influenzata (introducendo il rumore) dalla tolleranza degli ingranaggi, se non c'è una trazione uniforme.

0

Penso che la cosa migliore da fare sarebbe quella di creare un diagramma X-Y di tutte le temporizzazioni delle coppie di denti. Sceglieresti arbitrariamente un dente su ogni cog come T = 0 ..

+0

Sembra promettente, farebbe una bella immagine se non altro :) – Tom

1

Penso che sia ancora più semplice di così.

Ogni 16 * 9 campionamenti (del grosso ingranaggio) le ruote sono nello stesso identico punto in cui sono state avviate.

Quindi, ciò che si fa è la seguente:

  • scegliere qualsiasi punto nel tempo con un campionamento sul grande COG. Misura la quantità di tempo prima di campionare anche il piccolo ingranaggio. Ricorda questo valore.

  • ogni 16 * 9 campionamenti del grande ingranaggio (perché suona equivoco?) Eseguono di nuovo la stessa misura e li confrontano con il valore di base. Quando i tempi iniziano a cambiare, hai un problema.

R

+0

Con le avvertenze dei miei commenti alla domanda OP, penso che non sia sufficiente fare una misurazione ogni ciclo: se uno degli ingranaggi coinvolti perde un dente che non sta funzionando al momento della misurazione, non lo noteresti mai. Penso che sia necessario un confronto tra i ** segnali ** completi, che non è alterato dai ridimensionamenti locali, cioè non si desidera che le variazioni istantanee della velocità dell'albero di trasmissione diano un falso allarme. Vorrei sperimentare qualcosa sulla falsariga della correlazione incrociata tra input e output, che è probabilmente irrealizzabile con i vincoli di archiviazione ... – Jaime

1

Sto avendo qualche difficoltà a visualizzare la configurazione hardware. E il comportamento che stai cercando di rilevare. Un albero che scivola? Denti che indossano?

In ogni caso, vorrei scrivere una simulazione della situazione in modo da ottenere alcuni risultati, forse esagerati, senza rumore per testare gli algoritmi contro.

Gli algoritmi avrei test sarebbe variazioni della seguente:

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

Questo merita un upvote, ma per oggi ho raggiunto il limite. Continuerò a votare in 5 ore o giù di lì. –

+0

... ed eccolo. +1 –

2

Dato che stiamo parlando di "fase", quindi sembra ragionevole misurare la "battere" che si verifica quando le due forme d'onda rafforzano reciprocamente altro.

Qualcosa di simile, forse:

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; 
    } 

} 

Ora, se inseriamo questo in una simulazione di due ruote dentate, una delle 9 denti e uno di 16 denti, sia girando a 10 giri al secondo

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 

E ora se si aggiunge un ritardo di 1 msec a una delle ruote dentate:

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 

questa sembra una speranza b eginning :-)

0

Implementerei due loop a fase bloccata nel software. Supponiamo che una rotazione dell'ingranaggio A corrisponda a b giri dell'ingranaggio B. Calcola il minimo comune multiplo di a e b m: = lcm (a, b). Bloccaggio di fase PLLa con ingranaggio A (con fattore di m/a) e PLLb con ingranaggio B (con fattore di m/b). Quindi entrambi i PLL dovrebbero avere la stessa frequenza. Di conseguenza, le differenze di fase dovrebbero essere facili da rilevare. Dal momento che hai un controller devi solo calcolare la convoluzione dei due segnali a fase bloccata. Il massimo della funzione di convoluzione quindi ti dice la differenza di fase.

Problemi correlati