IMU (MPU9250) и тикер на ESP32

Я хочу периодически считывать данные с IMU (MPU9250). Для этого я использую тикер, как показано в следующем коде:

#include <Ticker.h>
#include "MPU9250.h"

constexpr int SERIAL_BAUDRATE = 115200;
constexpr float SAMPLING_FREQUENCY = 1.0;

Ticker TimerIMU;
MPU9250 IMU(Wire, 0x68);

void readIMU()
{
    // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.println(IMU.getGyroZ_rads(),6);
}


void setup()
{
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}
  // start communication with IMU 
  int retVal = IMU.begin();
  if(retVal < 0)
    Serial.println("IMU initialization unsuccessful: check your wiring or try resetting power to the sensor.");
   // start ticker
  TimerIMU.attach(1.0 / SAMPLING_FREQUENCY, readIMU);
}

void loop()
{
}

Этот подход не дает ожидаемых результатов: ИДУ возвращает всегда одни и те же значения. Включение функции readIMU в основной цикл и комментирование тикера работает хорошо. Я использую ESP32-WROVER.

В чем моя ошибка? Любое предложение будет оценено по достоинству.

, 👍0


1 ответ


1

readIMU() вызывается библиотекой из ISR (Процедуры обслуживания прерываний). Во время выполнения ISR другие прерывания не могут быть обработаны. Датчик IMU работает через I2C, который зависит от обслуживаемых прерываний. Таким образом, при инициировании связи внутри ISR передача никогда не может быть завершена правильно, так как необходимые ISR не выполняются. По крайней мере, в этом случае библиотека, похоже, не блокируется, поэтому код выполняется, но значения никогда не обновляются.

Вы не должны делать зависящие от прерывания вещи внутри ISR. Вместо этого вы можете определить переменную глобального флага, которую вы устанавливаете внутри ISR. Затем в вашем основном коде вы просто постоянно проверяете этот флаг и выполняете код, зависящий от ISR, если флаг установлен. После выполнения вы сбрасываете флаг.

Время отклика зависит от скорости, с которой работает ваш цикл. Но здесь это не должно быть проблемой, так как у вас нет другого кода в цикле (), а ваша частота составляет всего 1 Гц, поэтому задержка в несколько микросекунд не должна иметь значения.


Обратите внимание, что использование последовательного также зависит от прерывания. Так что запись или печать на последовательный порт внутри ISR также не очень хороши. Хотя вам это сойдет с рук, если вы убедитесь, что никогда не отправляете больше данных, чем может вместить последовательный буфер, и что вы оставляете достаточно времени между прерываниями для фактической передачи. Внутри ISR операторы печати и записи просто заполнят буфер. Затем данные будут отправляться в фоновом режиме с помощью прерываний.

,