Алгоритм определения эффективной «разности фаз» между двумя сигналами с разными частотами? - PullRequest
9 голосов
/ 21 июля 2009

Быстрая версия:

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

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

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

meshed gears and pulse signals

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

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

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

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

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

Что я хотел бы сделать:

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

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

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

Ответы [ 6 ]

2 голосов
/ 22 июля 2009

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

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

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

Это похоже на обнадеживающее начало: -)

2 голосов
/ 21 июля 2009

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

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

1 голос
/ 21 июля 2009

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

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

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

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
1 голос
/ 21 июля 2009

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

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

Итак, что вы делаете, это:

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

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

R

0 голосов
/ 12 августа 2013

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

0 голосов
/ 21 июля 2009

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

...