8

Быстрая версия:Алгоритм определения эффективной «разности фаз» между двумя сигналами с разными частотами?

Какого алгоритма я мог бы использовать, чтобы определить «разность фаз» между двумя квадратными волновыми сигналами с различных частотами, если только информация, что у меня есть время, когда каждый нарастающий фронт имеет место?

подробная версия:

Я работаю на встроенном программном проекте, и я перебежать интересную проблему. Я сбор данных от двух hall-effect speed sensors, каждый из которых, направленной на одном из двух зацеплении зубчатых колес, как показано на следующей схеме:

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

примечание:
Как Jaime указывалось, сигналы в этом диаграмма будет иметь одинаковые частоты. В реальном оборудовании есть еще несколько ступеней зацепления между двумя целевыми передачами, некоторые из которых соединены валами вместо сложенных зубьев, поэтому I do заканчиваются двумя квадратными волнами, которые имеют разные частоты, а соотношение между ними по-прежнему является постоянная. Я хотел упростить диаграмму, чтобы добраться до мяса, но похоже, что я слишком упростил ее!
/примечание

Датчики скорости выходного сигнала прямоугольной волны, частота которого прямо пропорциональна скорости вращения каждой шестерни. Восходящие (и падающие) края прямоугольной волны возникают, когда передний (и задний) края зубчатой ​​шестерни проходят через датчик.

Я знаю, сколько зубов на каждой передаче, и на основе этой информации я могу точно измерить скорость вращения каждой передачи в зависимости от частоты сигналов прямоугольной волны.

Для измерения частот у меня есть каждый сигнал датчика скорости, подключенный к высокоскоростному таймеру таймера захвата на встроенном контроллере. Таймеры захвата автоматически определяют нарастающие фронты сигнала квадратной волны, загружают регистр со значением, представляющим время, в которое произошел переход, и запускают прерывание. Точки захвата для каждого сигнала обозначены желтым на диаграмме. Процедура обслуживания прерывания выглядит примерно так:

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

То, что я хотел бы сделать:

Я хотел бы быть в состоянии обнаружить небольшие различия в относительной времени этих двух меандра сигналы. Я называю это «разностью фаз» из-за отсутствия лучшего термина. Если бы оба сигнала имели одинаковую частоту, это было бы просто, и phase difference был бы правильным термином для использования.

Вот что я получаю: если бы я записывал два сигнала в течение длительного периода времени, а затем искусственно замедлял (или «растягивал») высокоскоростной (синий) сигнал в 16/9, он имел бы ту же частоту, что и сигнал с меньшей скоростью (красный), и два сигнала имели бы некоторую измеримую разность фаз, т. Е. Разницу во времени между прерыванием красного сигнала и прерыванием синего сигнала.Я хотел бы вычислить эту разницу во времени (или что-то подобное) без необходимости записи сигналов в течение длительного периода времени. Ресурсы ограничены встроенным контроллером, поэтому хранение больших массивов прошлых периодов перехода не является вариантом.

Кто-нибудь сталкивался с этим раньше? Фактический проект имеет несколько таких механизмов передачи и датчиков, поэтому я ищу элегантный алгоритм, который я могу повторно использовать. Заранее спасибо!

+0

, поскольку 2 зубца соединены друг с другом. Как бы вы предположили, что они могут работать «не в фазе»? – Toad

+0

Напряжение на деталях, износ зубьев шестерни, небольшие эффекты реального мира. Это (конечно) упрощенный пример. Реальная система может иметь другие ступени передачи между двумя, на которых установлены датчики. Все небольшие допуски между наборами зубов могут привести к довольному количеству игры. Вы правы в том, что шестерни не могут получить * по существу * «не в фазе» без серьезного нарушения физической системы. То, что я пытаюсь измерить, - небольшие отклонения от нормы. –

+1

Если вы «растягиваете» один сигнал, вам нужно начало (t = 0). Это произвольно, но этот выбор определит вашу разность фаз. Следовательно, даже если вы создадите «истинную» разность фаз таким образом, ее значение будет произвольным из-за вашего выбора t = 0 – MSalters

ответ

2

Общий сигнал, то есть сигнал, который вы получаете при добавлении красного и синего, имеет длину фазы в 16 раз больше, а красный - в 9 раз. Вы можете измерить разницу во времени между каждыми 16-м синим и каждым 9-м красным восходящим флангом.

Я предполагаю, что то, что вы хотите измерить, это износ на передачах. Я думаю, что на это измерение может повлиять (введение шума) на толерантность передач, если нет единой тяги.

0

Я думаю, что лучше всего было бы создать диаграмму X-Y все зубчатые пары таймингов. Вы произвольно выбираете один зуб на каждом зубце, как T = 0 ..

+0

Это звучит многообещающе, сделало бы красивую картинку, если ничего не было :) – Tom

1

Я думаю, что это еще проще.

Каждые 16 * 9 выборок (большого зубчатого колеса) колеса находятся в том же месте, в котором они были.

Так что вы делаете следующее:

  • выбрать любой момент времени с отбора проб на большом винтик. Измерьте количество времени, прежде чем пробовать маленький зубчик. Помните это значение.

  • каждые 16 * 9 выборок большого зуба (почему это звучит сомнительно?) Повторите то же измерение и сравните его с базовым значением. Когда время начинает смещаться, у вас есть проблема.

R

+0

С предостережениями моих комментариев к вопросу о OP, я думаю, что этого недостаточно для каждого цикла: если одна из задействованных передач теряет зуб, который не работает во время измерения, вы никогда не заметите. Я думаю, вам нужно некоторое сравнение между ** целыми ** сигналами, которые не изменяются локальными масштабированиями, т. Е. Вы не хотите, чтобы мгновенные изменения скорости приводного вала приводили к ложному срабатыванию. Я бы экспериментировал с чем-то в соответствии с кросс-корреляцией между входом и выходом, что, вероятно, нецелесообразно с ограничениями хранения ... – Jaime

1

У меня возникли некоторые проблемы с визуализацией вашей установки оборудования. И поведение, которое вы пытаетесь обнаружить. Сдвиг вала? Зубы носят?

В любом случае, я бы написал симуляцию ситуации, чтобы получить некоторые, возможно, преувеличенные результаты без шума для тестирования алгоритмов.

Алгоритмы я бы испытание было бы вариации следующее:

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

Это заслуживает повышения, но я достиг предела сегодня. Я выйду через 5 часов или около того. –

+0

... и есть. +1 –

2

Поскольку мы говорим о «фазе», то представляется целесообразным, чтобы измерить «бить», которое происходит, когда две формы волны усиливают друг Другие.

Что-то вроде этого, возможно:

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

} 

Теперь, если мы подключить это в симуляции двух шестеренок, один из 9 зубов и один из 16 зубов, как поворот на 10 оборотов в секунду

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 

А теперь, если мы добавим задержку в 1 мс на один из винтиков:

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 

Это кажется обнадеживающим б eginning :-)

0

Я бы реализовал две фазовые блокировки в программном обеспечении. Предположим, что обороты передачи A соответствуют b оборотам шестерни B. Вычислите наименьшее общее кратное a и b m: = lcm (a, b). Фазовая блокировка PLLa с шестерней A (с коэффициентом m/a) и PLLb с шестерней B (с коэффициентом m/b). Тогда обе ФАПЧ должны иметь одинаковую частоту. Следовательно, разность фаз должна быть легко обнаружена. Поскольку у вас есть контроллер, вы просто вычисляете свертку двух фазовых сигналов. Затем максимум функции свертки сообщает вам разность фаз.