我需要不断收集数据的6个传感器(GPS,IMU等)。出于我的目的,我需要从每个(在很短的时间范围内)读取一个完整的数据包。现在我正在使用中断,但这导致某些传感器的数据比其他传感器更多,并且如上所述,我需要将数据匹配。
移动到基于轮询的系统会更好吗?我可以按设定的顺序轮询每个传感器?这样我每个'周期'都可以从每个传感器获得数据。
然而,我担心轮询的速度,因为这个系统需要接近实时运行。
答案 0 :(得分:1)
轮询与“主定时器中断”相结合可能是您的朋友。假设您的“最慢”传感器可以以20ms的间隔提供数据,而其他传感器可以更快地读取。那是每秒50次更新。如果它足够接近实时(可能接近IMU),也许你会这样做:
当定时器熄灭时,在中断服务程序中设置一个标志:
volatile uint8_t timerFlag = 0;
ISR(TIMER_ISR_whatever)
{
timerFlag = 1; // nothing but a semaphore for later...
}
然后,在timerFlag
说出时间的主循环动作中:
while(1)
{
if(timerFlag == 1)
{
<read first device>
<read second device>
<you get the idea ;) >
timerflag = 0;
}
}
通过这种方式,您可以阅读每个设备并保持读数同步。这是在嵌入式空间中解决此问题的典型方法。现在,如果您需要的数据速度超过20毫秒,那么您可以缩短计时器等。在这种情况下,最重要的问题是“您能够以多快的速度进行投票”与“您需要多快查询一次”。 “只有实验并了解各种设备的特性和时间才能告诉您。但是,当所有时间“适合”时,我建议的是一般解决方案。
编辑,一种不同的方法
更基于中断的示例:
volatile uint8_t device1Read = 0;
volatile uint8_t device2Read = 0;
etc...
ISR(device 1)
{
<read device>
device1Read = 1;
}
ISR(device 2)
{
<read device>
device2Read = 1;
}
etc...
// main loop
while(1)
{
if(device1Read == 1 && device2Read == 1 && etc...)
{
//< do something with your "packet" of data>
device1Read = 0;
device2Read = 0;
etc...
}
}
在这个例子中,所有设备都可以被中断驱动,但主循环处理仍然由最慢中断的节奏控制,节奏。无论速度或延迟如何,都可以使用每个设备的最新完整读数。这种模式更接近您的想法吗?
答案 1 :(得分:1)
轮询是一个非常好且易于实现的想法,以防您的传感器几乎可以立即提供数据(与您想要的输出频率相比)。当您拥有需要大量(甚至可变)时间来提供读数或需要异步&#34;启动/收集&#34;的数据源时,它确实陷入了噩梦。周期。您必须对轮询周期进行排序以适应最慢的&#34;数据来源。
如果您知道平均数据转换率&#34;可能会有什么解决方案。每个源的设置是设置一些在poll time - data conversion rate
触发的定时器(每个数据源),并从那些定时器ISR开始测量。然后让最后一个在poll timer + some safety margin
处触发的计时器收集所有转换结果。
另一方面,你有明显的问题&#34;测量太多&#34;来自&#34;快速&#34;只要您没有与浪费的CPU /传感器负载有任何合理关系,数据源就不会让我感到烦恼。
如果您有一些浪费的周期,最后一种更简单的方法是:简单地对数据源进行排序&#34;最慢&#34;最快&#34;并按该顺序启动测量,然后以相同的顺序等待结果并进行轮询。