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.
В чем моя ошибка? Любое предложение будет оценено по достоинству.
@R. Ho, 👍0
1 ответ
readIMU()
вызывается библиотекой из ISR (Процедуры обслуживания прерываний). Во время выполнения ISR другие прерывания не могут быть обработаны. Датчик IMU работает через I2C, который зависит от обслуживаемых прерываний. Таким образом, при инициировании связи внутри ISR передача никогда не может быть завершена правильно, так как необходимые ISR не выполняются. По крайней мере, в этом случае библиотека, похоже, не блокируется, поэтому код выполняется, но значения никогда не обновляются.
Вы не должны делать зависящие от прерывания вещи внутри ISR. Вместо этого вы можете определить переменную глобального флага, которую вы устанавливаете внутри ISR. Затем в вашем основном коде вы просто постоянно проверяете этот флаг и выполняете код, зависящий от ISR, если флаг установлен. После выполнения вы сбрасываете флаг.
Время отклика зависит от скорости, с которой работает ваш цикл. Но здесь это не должно быть проблемой, так как у вас нет другого кода в цикле ()
, а ваша частота составляет всего 1 Гц, поэтому задержка в несколько микросекунд не должна иметь значения.
Обратите внимание, что использование последовательного также зависит от прерывания. Так что запись или печать на последовательный порт внутри ISR также не очень хороши. Хотя вам это сойдет с рук, если вы убедитесь, что никогда не отправляете больше данных, чем может вместить последовательный буфер, и что вы оставляете достаточно времени между прерываниями для фактической передачи. Внутри ISR операторы печати и записи просто заполнят буфер. Затем данные будут отправляться в фоновом режиме с помощью прерываний.
- Присоедините функцию Arduino ISR к члену класса
- Изменение адреса MPU 9250 подключенного к ESP32
- Как включать и выключать несколько плат одновременно?
- Как соединить два устройства через i2c?
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2