Arduino - 陀螺仪传感器 - ISR - 时间戳



我目前正在重新创建一个四轴飞行器控制器。

我正在努力从我的陀螺仪传感器获取数据,为此,我正在使用 带有中断的 ISR。

我的问题是,当我在主程序上调用我的函数"gyro.getX"时,它可以工作。 但是,当我从我的 ISR 调用此函数时,它不起作用。 我认为我找到了错误的版本,我正在使用的功能由"Adafruit_LSM9DS0"库(来自 ST)提供,并且它使用了"时间戳"。 我认为我的 ISR 的当前时间与我的主程序的当前时间不同,但我不知道如何解决它。

这是我程序的快捷方式:

void loop(){
/*main prog*/
}
/*
*Reserve interrupt routine service (ISR) by Arduino
*/
ISR(TIMER2_OVF_vect)
{
TCNT2 = 256 - 250; // 250 x 16 µS = 4 ms
if (varCompteur++ > 25)// 25 * 4 ms = 100 ms (half-period)
{
varCompteur = 0;

SensorGet(pX, pY);//Feed gyro circular buffers
}
}
void SensorGet(float * pRollX, float * pPitchY)
{   
lsm.getEvent(&accel, &mag, &gyro, &temp);

GiroX_Feed(pX, gyro.gyro.x);
GiroY_Feed(pPitchY, gyro.gyro.y);
}


bool Adafruit_LSM9DS0::getEvent(sensors_event_t *accelEvent,
sensors_event_t *magEvent,
sensors_event_t *gyroEvent,
sensors_event_t *tempEvent)
{
/* Grab new sensor reading and timestamp. */
read();
uint32_t timestamp = millis();
/* Update appropriate sensor events. */
if (accelEvent) getAccelEvent(accelEvent, timestamp);
if (magEvent)   getMagEvent(magEvent, timestamp);
if (gyroEvent)  getGyroEvent(gyroEvent, timestamp);
if (tempEvent)  getTempEvent(tempEvent, timestamp);
return true;
}

问题不在于时间。 问题可能是您的传感器使用 I2C 并且在中断例程期间被禁用,或者它是依赖于中断运行的其他通信协议,因此在 ISR 期间被禁用。

你真的是在滥用中断。 这不是中断的用途。 中断应该超快,没有时间在那里进行通信。 所以真正的问题是你为什么认为你需要为此中断?

就我个人而言,我不太喜欢修补复杂的,有时甚至是嵌套的millis()-elapsed语句。我通常更喜欢使用类似状态机的循环和一些计时器中断的组合来设置状态,因为我发现它们更通用。

计时器
  1. (也可以是计时器中断)设置状态变量STATE = READ
  2. loop()内部调用与内部read_sensor()函数关联的STATE,并将STATE重置为IDLE
// NOTE: Is use ESP32, so maybe timer implementation might be a little different on other platforms
void IRAM_ATTR ISR_timer() {
STATE = READ;
}
// in global definitions
hw_timer_t* timer = NULL;
// inside setup()
timer = timerBegin(0, 80, countUp);                     // countUp [true/false]
timerAttachInterrupt(timer, ISR_timer, edge);           // edge [true: rising/false: falling]
timerAlarmWrite(timer, interval_ms * 1e3, autoreload);  // autoreload [true/false]
timerAlarmEnable(timer);        // starts timer
// timerAlarmDisable(timer);    // stops timer

// inside loop()
switch(STATE) 
{ 
case IDLE: break;
... 
case READ: 
read_sensor(...);
STATE = IDLE;
break;
...
}

希望这有帮助。如果您对此有任何想法,请随时添加评论。

最新更新