9

快速版本:

如果我拥有的唯一信息是每个上升沿发生的时间,我可以使用什么算法来确定两个不同频率的方波信号之间的“相位差” ?

详细版本:

我正在从事一个嵌入式软件项目,并且遇到了一个有趣的问题。我正在从两个霍尔效应速度传感器收集数据,每个传感器都针对两个啮合齿轮之一,如下图所示:

啮合齿轮和脉冲信号

注意:
正如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倍,它将具有与较低速度(红色)信号完全相同的频率,并且两个信号将具有一些可测量的相位差,即红色信号中断和蓝色信号中断之间的时间差。我想计算这个相同的时间差(或等效的东西),而不必长时间记录信号。嵌入式控制器上的资源有限,因此存储大量过去的转换时间不是一种选择。

有没有人遇到过这个?实际项目有几个这样的齿轮和传感器布置,所以我正在寻找一种可以重用的优雅算法。提前致谢!

4

6 回答 6

2

整体信号,即当你添加红色和蓝色时得到的信号,相位长度是蓝色信号的 16 倍和红色信号的 9 倍。您可以测量每 16 个蓝色上升沿和每 9 个红色上升沿之间的时间差。

我想您要测量的是齿轮的磨损情况。我认为如果没有均匀的牵引力,这种测量可能会受到齿轮公差的影响(引入噪音)。

于 2009-07-21T08:14:49.720 回答
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

这似乎是一个充满希望的开始:-)

于 2009-07-22T19:52:37.430 回答
1

I think it is even simpler than that.

Every 16*9 samplings(of the big cog) the wheels are in the exact same spot they started.

So what you do is the following:

  • pick any point in time with a sampling on the big cog. Measure the amount of time before you sample the small cog too. Remember this value.

  • every 16*9 samplings of the big cog (why does this sound dubious?) do the same measurement again and compare it to your base value. When the timing begins to shift, you have a problem.

R

于 2009-07-21T13:57:03.103 回答
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
于 2009-07-21T16:01:56.240 回答
0

我认为最好的办法是创建所有齿对时序的 XY 图。当 T=0 时,您会在每个齿轮上任意选择一颗牙齿。

于 2009-07-21T08:41:58.057 回答
0

我会在软件中实现两个锁相环。假设齿轮 A 的 a 转对应于齿轮 B 的 b 转。计算 a 和 bm 的最小公倍数:= lcm(a,b)。锁相 PLLa 与齿轮 A(系数为 m/a)和 PLLb 与齿轮 B(系数为 m/b)。那么两个 PLL 应该具有相同的频率。因此相位差应该很容易检测。由于您有一个控制器,您只需计算两个锁相信号的卷积。然后卷积函数的最大值告诉你相位差。

于 2013-08-12T04:49:06.103 回答