IMU-сенсор 10-DOF v2: инструкция, схемы и примеры использования

Используйте IMU-сенсор (от англ. Inertial Measurement Unit — Инерционное измерительное устройство) для определения положение вашего девайса в пространстве.

Видеообзор

Принцип работы

IMU-модуль на 10 степеней свободы включает в себя четыре отдельных сенсора:

  • Акселерометр для определения величины ускорения свободного падения по осям X, Y, Z.
  • Гироскоп для определения угловой скорости вокруг собственных осей X, Y, Z.
  • Магнитометр для определения углов между собственными осями сенсора X, Y, Z и силовыми линиями магнитного поля Земли.
  • Барометр для определения атмосферного давления, высоты над уровнем моря и температуры.

Показания акселерометра, гироскопа и магнитометра можно использовать как входные данные для фильтра Маджвика, Махони или Калмана, для определения положение вашего девайса в пространстве через кватернионы.

Кватернионы «сильный» инструмент для выполнения вычислений по ориентации объекта в пространстве, но им не хватает наглядности. Поэтому полученные кватернионы из фильтра удобнее представить в самолётных углах Эйлера: Pitch, Roll и Yaw

  • Roll / Крен — определяет наклон тела вокруг продольной оси. Например крен самолёта показывает насколько градусов в бок наклонились его крылья относительно земной поверхности. Если самолёт находится параллельно земле, то крен равен 0°. Если самолёт наклонился влево (левое крыло ниже правого), то крен отрицательный с диапазоном [0°; −90°]. Если самолёт наклонился вправо (левое крыло выше правого), то крен положительный с диапазоном [0°; 90°].
  • Pitch / Тангаж — определяет наклон продольной оси. Например тангаж самолёта показывает насколько градусов поднят (или опущен) его нос относительно земной поверхности. Если самолёт находится параллельно земле, то тангаж равен 0°. Если самолёт поднимает нос (кабрирует / взлетает), то тангаж положительный с диапазоном [0°;180°]. Если самолёт опускает нос (пикирует / приземляется), то тангаж отрицательный [0°;−180°].
  • Yaw / Рыскание — определяет направление вдоль земной поверхности. Например для самолёта угол рысканье определяет куда самолёт летит. Если самолёт летит на север, то рысканье равен 0°. Если самолёт отклоняется от севера влево (на запад, или против часовой стрелки если смотреть сверху), то курс положительный в диапазоне [0°;180°]. Если самолёт отклоняется от севера вправо (на восток, или по часовой стрелке если смотреть сверху), то курс отрицательный в диапазоне [0°;−180°].

В фильтре Маджвика реализовано два варианта определение ориентации объекта в пространстве.

  1. Без магнитометра. Используются данные акселерометра и гироскопа. При этом угол Yaw будет указывать не на север, а на изначальное направление датчика.
  2. С магнитометром. Используются данные акселерометра, гироскопа и магнитометра. При этом угол Yaw будет указывать на север.

В связи с искажениями от внешних магнитных полей, откалибруйте магнитометр для работы в режиме электронного компаса.

Пример работы для Arduino и XOD

В качестве мозга для считывания показаний с датчика рассмотрим платформу из серии Arduino, например, Uno.

Схема устройства

Подключите IMU-сенсор к пинам питания и шины I²C — SDA и SCL на платформе Uno. Для коммуникации используйте соединительные провода «мама-папа»

Для быстрой сборки и отладки устройства возьмите плату расширения Troyka Shield, которая одевается сверху на Arduino Uno методом бутерброда. Для коммуникации используйте трёхпроводной шлейф «мама-мама», который идёт в комплекте с датчиком.

С Troyka Slot Shield провода не понадобятся вовсе.

Вывод показателей сенсоров

В качестве примера выведем в Serial-порт следующие данные:

  • гироскопа: угловую скорость вокруг собственных осей X, Y, Z;
  • акселерометра: направление и величину ускорения свободного падения по осям X, Y, Z;
  • компаса: значения азимута;
  • барометра: абсолютное давление и температуру окружающей среды.
imu-read-data.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с модулями IMU
#include <TroykaIMU.h>
 
// создаём объект для работы с гироскопом
Gyroscope gyro;
// создаём объект для работы с акселерометром
Accelerometer accel;
// создаём объект для работы с компасом
Compass compass;
// создаём объект для работы с барометром
Barometer barometer;
 
// калибровочные значения компаса
// полученные в калибровочной матрице из примера «compassCalibrateMatrix»
const double compassCalibrationBias[3] = {
  524.21,
  3352.214,
  -1402.236
};
 
const double compassCalibrationMatrix[3][3] = {
  {1.757, 0.04, -0.028},
  {0.008, 1.767, -0.016},
  {-0.018, 0.077, 1.782}
};
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(115200);
  // выводим сообщение о начале инициализации
  Serial.println("Begin init...");
  // инициализация гироскопа
  gyro.begin();
  // инициализация акселерометра
  accel.begin();
  // инициализация компаса
  compass.begin();
  // инициализация барометра
  barometer.begin();
  // калибровка компаса
  compass.calibrateMatrix(compassCalibrationMatrix, compassCalibrationBias);
  // выводим сообщение об удачной инициализации
  Serial.println("Initialization completed");
  Serial.println("Gyroscope\t\t\tAccelerometer\t\t\tCompass\t\tBarometer");
}
 
void loop()
{
  // вывод угловой скорости в градусах в секунду относительно оси X
  Serial.print(gyro.readDegPerSecX());
  Serial.print("\t");
  // вывод угловой скорости в градусах в секунду относительно оси Y
  Serial.print(gyro.readDegPerSecY());
  Serial.print("\t");
  // вывод угловой скорости в градусах в секунду относительно оси Z
  Serial.print(gyro.readDegPerSecZ());
  Serial.print("\t\t");
  // вывод направления и величины ускорения в м/с² по оси X
  Serial.print(accel.readAX());
  Serial.print("\t");
  // вывод направления и величины ускорения в м/с² по оси Y
  Serial.print(accel.readAY());
  Serial.print("\t");
  // вывод направления и величины ускорения в м/с² по оси Z
  Serial.print(accel.readAZ());
  Serial.print("\t\t");
  // выводим азимут относительно оси Z
  Serial.print(compass.readAzimut());
  Serial.print(" Degrees\t");
  // вывод значения абсолютного давления
  Serial.print(barometer.readPressureMillibars());
  Serial.print("\t");
  // вывод значения температуры окружающей среды
  Serial.print(barometer.readTemperatureC());
  Serial.print("\t");
  Serial.println("");
  delay(100);
}

Ориентация объекта без азимута

Определим ориентацию объекта в пространстве без учёта направления на север. Для этого показания акселерометра и гироскопа используем как входные данные для фильтра Маджвика. На выходе получим кватернионы, которые для наглядности пересчитаем в самолётные углы Эйлера.

Madgwick6DOF.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с модулями IMU
#include <TroykaIMU.h>
 
// множитель фильтра
#define BETA 0.22f
 
// создаём объект для фильтра Madgwick
Madgwick filter;
 
// создаём объект для работы с акселерометром
Accelerometer accel;
// создаём объект для работы с гироскопом
Gyroscope gyro;
 
// переменные для данных с гироскопов, акселерометров
float gx, gy, gz, ax, ay, az;
 
// получаемые углы ориентации
float yaw, pitch, roll;
 
// переменная для хранения частоты выборок фильтра
float fps = 100;
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(115200);
  Serial.println("Begin init...");
  // инициализация акселерометра
  accel.begin();
  // инициализация гироскопа
  gyro.begin();
  // выводим сообщение об удачной инициализации
  Serial.println("Initialization completed");
}
 
void loop()
{
  // запоминаем текущее время
  unsigned long startMillis = millis();
 
  // считываем данные с акселерометра в единицах G
  accel.readGXYZ(&ax, &ay, &az);
  // считываем данные с акселерометра в радианах в секунду
  gyro.readRadPerSecXYZ(&gx, &gy, &gz);
  // устанавливаем коэффициенты фильтра
  filter.setKoeff(fps, BETA);
  // обновляем входные данные в фильтр
  filter.update(gx, gy, gz, ax, ay, az);
 
  // получение углов yaw, pitch и roll из фильтра
  yaw =  filter.getYawDeg();
  pitch = filter.getPitchDeg();
  roll = filter.getRollDeg();
 
  // выводим полученные углы в serial-порт
  Serial.print("yaw: ");
  Serial.print(yaw);
  Serial.print("\t\t");
  Serial.print("pitch: ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.print("roll: ");
  Serial.println(roll);
 
  // вычисляем затраченное время на обработку данных
  unsigned long deltaMillis = millis() - startMillis;
  // вычисляем частоту обработки фильтра
  fps = 1000 / deltaMillis;
}

Ориентация объекта c азимутом

Определим ориентацию объекта в пространстве с учётом направления на север. Для этого показания акселерометра, гироскопа и компаса используем как входные данные для фильтра Маджвика. На выходе получим кватернионы, которые для наглядности пересчитаем в самолётные углы Эйлера.

Madgwick9DOF.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с модулями IMU
#include <TroykaIMU.h>
 
// множитель фильтра
#define BETA 0.22
 
// создаём объект для фильтра Madgwick
Madgwick filter;
 
// создаём объект для работы с акселерометром
Accelerometer accel;
// создаём объект для работы с гироскопом
Gyroscope gyro;
// создаём объект для работы с компасом
Compass compass;
 
// переменные для данных с гироскопа, акселерометра и компаса
float gx, gy, gz, ax, ay, az, mx, my, mz;
 
// получаемые углы ориентации (Эйлера)
float yaw, pitch, roll;
 
// переменная для хранения частоты выборок фильтра
float fps = 100;
 
// калибровочные значения компаса
// полученные в калибровочной матрице из примера «compassCalibrateMatrixx»
const double compassCalibrationBias[3] = {
  524.21,
  3352.214,
  -1402.236
};
 
const double compassCalibrationMatrix[3][3] = {
  {1.757, 0.04, -0.028},
  {0.008, 1.767, -0.016},
  {-0.018, 0.077, 1.782}
};
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(115200);
  Serial.println("Begin init...");
  // инициализация акселерометра
  accel.begin();
  // инициализация гироскопа
  gyro.begin();
  // инициализация компаса
  compass.begin();
 
  // калибровка компаса
  compass.calibrateMatrix(compassCalibrationMatrix, compassCalibrationBias);
  // выводим сообщение об удачной инициализации
  Serial.println("Initialization completed");
}
 
void loop()
{
  // запоминаем текущее время
  unsigned long startMillis = millis();
 
  // считываем данные с акселерометра в единицах G
  accel.readGXYZ(&ax, &ay, &az);
  // считываем данные с гироскопа в радианах в секунду
  gyro.readRadPerSecXYZ(&gx, &gy, &gz);
  // считываем данные с компаса в Гауссах
  compass.readCalibrateGaussXYZ(&mx, &my, &mz);
 
  // устанавливаем коэффициенты фильтра
  filter.setKoeff(fps, BETA);
  // обновляем входные данные в фильтр
  filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);
 
  // получение углов yaw, pitch и roll из фильтра
  yaw =  filter.getYawDeg();
  pitch = filter.getPitchDeg();
  roll = filter.getRollDeg();
 
  // выводим полученные углы в serial-порт
  Serial.print("yaw: ");
  Serial.print(yaw);
  Serial.print("\t\t");
  Serial.print("pitch: ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.print("roll: ");
  Serial.println(roll);
 
  // вычисляем затраченное время на обработку данных
  unsigned long deltaMillis = millis() - startMillis;
  // вычисляем частоту обработки фильтра
  fps = 1000 / deltaMillis;
}

Визуальное отображение объекта в пространстве

Для наглядности приведём пример отображение IMU-сенсора в пространстве в виде самолёта. Для запуска примера необходимо прошить платформу Arduino кодом ниже и настроить графическую среду Processing.

Порядок действий

Код для Arduino

MadgwickProcessing9DOF.ino
// скетч для вывода кватернионов в serial-порт
// для дальнейшего графического просмотра ориентации объекта
// в среде processing «MadgwickProcessingDraw9DOF.pde»
 
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с модулями IMU
#include <TroykaIMU.h>
 
// множитель фильтра
#define BETA 0.22
 
// создаём объект для фильтра Madgwick
Madgwick filter;
 
// создаём объект для работы с акселерометром
Accelerometer accel;
// создаём объект для работы с гироскопом
Gyroscope gyro;
// создаём объект для работы с компасом
Compass compass;
 
// переменные для данных с гироскопа, акселерометра и компаса
float gx, gy, gz, ax, ay, az, mx, my, mz;
 
// получаемые углы ориентации (Эйлера)
float yaw, pitch, roll;
 
// переменная для хранения частоты выборок фильтра
float fps = 100;
 
// калибровочные значения компаса
// полученные в калибровочной матрице из примера «compassCalibrateMatrixx»
const double compassCalibrationBias[3] = {
  524.21,
  3352.214,
  -1402.236
};
 
const double compassCalibrationMatrix[3][3] = {
  {1.757, 0.04, -0.028},
  {0.008, 1.767, -0.016},
  {-0.018, 0.077, 1.782}
};
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(115200);
  // инициализация акселерометра
  accel.begin();
  // инициализация гироскопа
  gyro.begin();
  // инициализация компаса
  compass.begin();
  // калибровка компаса
  compass.calibrateMatrix(compassCalibrationMatrix, compassCalibrationBias);
}
 
void loop()
{
  // запоминаем текущее время
  unsigned long startMillis = millis();
  // считываем данные с акселерометра в единицах G
  accel.readGXYZ(&ax, &ay, &az);
  // считываем данные с гироскопа в радианах в секунду
  gyro.readRadPerSecXYZ(&gx, &gy, &gz);
  // считываем данные с компаса в Гауссах
  compass.readCalibrateGaussXYZ(&mx, &my, &mz);
  // устанавливаем коэффициенты фильтра
  filter.setKoeff(fps, BETA);
  // обновляем входные данные в фильтр
  filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);
 
  if (Serial.available() > 0) {
    int val = Serial.read();
    // если пришёл символ 's'
    if (val == 's') {
      float q0, q1, q2, q3;
      filter.readQuaternions(&q0, &q1, &q2, &q3);
      // выводим кватернионы в serial-порт
      Serial.print(q0);
      Serial.print(",");
      Serial.print(q1);
      Serial.print(",");
      Serial.print(q2);
      Serial.print(",");
      Serial.println(q3);
    }
  }
  // вычисляем затраченное время на обработку данных
  unsigned long deltaMillis = millis() - startMillis;
  // вычисляем частоту обработки фильтра
  fps = 1000 / deltaMillis;
}

Код для Processing

MadgwickProcessingDraw9DOF.pde
import processing.serial.*;
import toxi.geom.*;
import toxi.processing.*;
 
// The serial port
Serial port;                         
 
String message;
 
float[] q = new float[4];
Quaternion quat = new Quaternion(1, 0, 0, 0);
// new line character in ASCII
int newLine = 13; 
String [] massQ = new String [4];
float[] ypr = new float[3];
 
void setup() 
{
  // size form 300x300
  size(400, 400, P3D); 
  // open serial port
  // replace "COM29" with the COM port on which your arduino is connected
  port = new Serial(this, "COM29", 115200);
  // wait init Serial for Arduino
  delay(1000);
}
 
void draw() 
{
  // read and parse incoming serial message
  serialEvent();
  // set background to black
  background(0);
  printQuaternions();
  printYawPitchRoll();
  // set position to centre
  translate(width / 2, height / 2);
  // begin object
  pushMatrix();
  float[] axis = quat.toAxisAngle();
  rotate(axis[0], axis[2], axis[3], axis[1]);
  // draw main body in red
  drawBody();
  // draw front-facing tip in blue
  drawCylinder();
  // draw Triangles
  drawTriangles();
  // draw Quards
  drawQuards();
  // end of object
  popMatrix();
  // send 's' to Arduino
  port.write('s');
}
 
void serialEvent() { // Function for parsing serial message
  // read from port until new line (ASCII code 13)
  message = port.readStringUntil(newLine);
  if (message != null) {
    // split message by commas and store in String array 
    massQ = split(message, ",");
    q[0] = float(massQ[0]);
    q[1] = float(massQ[1]);
    q[2] = float(massQ[2]);
    q[3] = float(massQ[3]);
  }
  // print values to console
  print(q[0]);
  print("\t");
  print(q[1]); 
  print("\t");
  print(q[2]);   
  print("\t");
  print(q[3]);   
  println("\t");
  // set our toxilibs quaternion to new data
  quat.set(q[0], q[1], q[2], q[3]);
 
}
 
void drawCylinder() {
  float topRadius = 0;
  float bottomRadius = 20;
  float tall = 20;
  int sides = 8;
  // begin object
  pushMatrix();
  translate(0, 0, -120);
  rotateX(PI/2);
  fill(0, 0, 255, 200);
 
  float angle = 0;
  float angleIncrement = TWO_PI / sides;
  beginShape(QUAD_STRIP);
  for (int i = 0; i < sides + 1; ++i) {
    vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
    vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
    angle += angleIncrement;
  }
  endShape();
 
  // if it is not a cone, draw the circular top cap
  if (topRadius != 0) {
    angle = 0;
    beginShape(TRIANGLE_FAN);
 
    // center point
    vertex(0, 0, 0);
    for (int i = 0; i < sides + 1; i++) {
      vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
      angle += angleIncrement;
    }
    endShape();
  }
 
  // if it is not a cone, draw the circular bottom cap
  if (bottomRadius != 0) {
    angle = 0;
    beginShape(TRIANGLE_FAN);
 
    // center point
    vertex(0, tall, 0);
    for (int i = 0; i < sides + 1; i++) {
      vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
      angle += angleIncrement;
    }
   endShape();
  }
  popMatrix(); 
}
 
void drawBody() {
  fill(255, 0, 0, 200);
  box(10, 10, 200);
}
 
void drawTriangles() {
  // draw wings and tail fin in green
  fill(0, 255, 0, 200);
  beginShape(TRIANGLES);
  // wing top layer
  vertex(-100,  2, 30); vertex(0,  2, -80); vertex(100,  2, 30);
  // wing bottom layer
  vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);
  // tail left layer
  vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);
  // tail right layer
  vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);
  endShape();
}
 
void drawQuards() {
  beginShape(QUADS);
  vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
  vertex( 100, 2, 30); vertex( 100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
  vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2,  30); vertex(100, 2,  30);
  vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
  vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
  vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
  endShape();
}
 
void printQuaternions() {
  textMode(SHAPE); // set text mode to shape
  textSize(13);
  fill(255, 255, 255);
  text("Quaternions:", 20, 20, 10);
  text(q[0], 20, 40, 10);
  text(q[1], 20, 60, 10);
  text(q[2], 20, 80, 10);
  text(q[3], 20, 100, 10);
}
 
void printYawPitchRoll() {
  // calculate yaw/pitch/roll angles
  ypr[0] = atan2(2 * q[1] * q[2] - 2 * q[0] * q[3], 2 * q[0] * q[0] + 2 * q[1] * q[1] - 1)*57.2;
  ypr[1] = atan2(2 * q[2] * q[3] - 2 * q[0] * q[1], 2 * q[0] * q[0] + 2 * q[3] * q[3] - 1)*57.2;
  ypr[2] = -atan2(2.0f * (q[0] * q[2] - q[1] * q[3]), 1.0f - 2.0f * (q[2] * q[2] + q[1] * q[1]))*57.2;
 
  text("Yaw:", 150, 20, 10);
  text(ypr[0], 150, 40, 10);
  text("Pitch:", 220, 20, 10);
  text(ypr[1], 220, 40, 10);
  text("Roll:", 290, 20, 10);
  text(ypr[2], 290, 40, 10);
}

При запуске визуализации на «processinge» откроется окно с графическим отображением IMU-сенсора в виде самолёта. Самолёт на экране будет повторять перемещения IMU-сенсора в пространстве.

Пример для Espruino

В качестве мозга для считывания показаний с датчика рассмотрим платформы из серии Espruino, например, Iskra JS.

Схема устройства

Подключите IMU-сенсор к пинам питания и шины I²C — SDA и SCL платформы Iskra JS. Для коммуникации используйте соединительные провода «мама-папа».

Для быстрой сборки и отладки устройства возьмите плату расширения Troyka Shield, которая одевается сверху на Iskra JS методом бутерброда. Для коммуникации используйте трёхпроводной шлейф «мама-мама», который идёт в комплекте с датчиком.

С Troyka Slot Shield провода не понадобятся вовсе.

Вывод показателей сенсоров

В качестве примера выведем в консоль следующие данные:

  • гироскопа: угловую скорость вокруг собственных осей X, Y, Z;
  • акселерометра: направление и величину ускорения свободного падения по осям X, Y, Z;
  • компаса: значения азимута;
  • барометра: абсолютное давление и температуру окружающей среды.
imu-read-data.js
 

Пример для Raspberry Pi

В качестве мозга для считывания показаний с датчика рассмотрим одноплатные компьютеры Raspberry Pi, например, Raspberry Pi 4.

Схема устройства

Подключите датчик IMU к пинам SDA и SCL шины I²C компьютера Raspberry Pi.

Для быстрой сборки и отладки устройства возьмите плату расширения Troyka Cap, которая надевается сверху на малину методом бутерброда.

Программная настройка

Вывод показателей сенсоров

В качестве примера выведем в консоль следующие данные:

  • гироскопа: угловую скорость вокруг собственных осей X, Y, Z;
  • акселерометра: направление и величину ускорения свободного падения по осям X, Y, Z;
  • компаса: значения азимута;
  • барометра: абсолютное давление и температуру окружающей среды.
imu-read-data.py
 

Элементы платы

Акселерометр на LIS331DLH

Акселерометр выполнен на чипе LIS331DLH и представляет собой миниатюрный датчик ускорения, разработанный по технологии MEMS от компании STMicroelectronics. Адрес устройства по умолчанию равен 0x18, но может быть изменен на 0x19. Подробности читайте в разделе смена адреса модуля.

Гироскоп на I3G4250D

Гироскоп выполнен на чипе I3G4250D и представляет собой миниатюрный датчик перемещений в трёхмерном пространстве, разработанный по технологии MEMS от компании STMicroelectronics. Адрес устройства по умолчанию равен 0x68, но может быть изменен на 0x69. Подробности читайте в разделе смена адреса модуля.

Магнитометр/Компас на LIS3MDL

Магнитометр выполнен на чипе LIS3MDL и представляет собой миниатюрный датчик магнитного поля в трёхмерном пространстве, разработанный по технологии MEMS от компании STMicroelectronics. Адрес устройства по умолчанию равен 0x1С, но может быть изменен на 0x1E. Подробности читайте в разделе смена адреса модуля.

Барометр на LPS25HB

Барометр выполнен на чипе LPS25HB по технологии MEMS от компании STMicroelectronics. Адрес устройства по умолчанию равен 0x5С, но может быть изменен на 0x5D. Подробности читайте в разделе смена адреса модуля.

Регулятор напряжения

Линейный понижающий регулятор напряжения NCP698SQ33T1G обеспечивает питание MEMS-чипов и других компонентов сенсора. Диапазон входного напряжения от 3,3 до 5 вольт. Выходное напряжение 3,3 В с максимальным выходным током 150 мА.

Преобразователь логических уровней

Преобразователь логических уровней PCA9306DCT необходим для сопряжения датчика с разными напряжениями логических уровней от 3,3 до 5 вольт. Другими словами сенсор совместим как с 3,3 вольтовыми платами, например, Raspberry Pi, так и с 5 вольтовыми — Arduino Uno.

Troyka-контакты

Датчик подключается к управляющей электронике через две группы Troyka-контактов:

  • Питание (V) — соедините с рабочим напряжением микроконтроллера.
  • Земля (G) — соедините с землёй микроконтроллера.
  • Сигнальный (D) — пин данных шины I²C. Подключите к пину SDA микроконтроллера.
  • Сигнальный (C) — пин тактирования шины I²C. Подключите к пину SCL микроконтроллера.

Смена адреса модуля

Иногда в проекте необходимо использовать несколько IMU-сенсоров. Для этого на модуле предусмотрены четыре пары контактных площадки, по одной на каждый чип. Для смена адреса капните каплей припоя на отведённую контактную площадку.

Модуль Адрес без перемычки Адрес с перемычкой
Акселерометр 0x18 0x19
Гироскоп 0x68 0x69
Магнитометр 0x1С 0x1E
Барометр 0x5С 0x5D

Принципиальная и монтажная схемы

Габаритный чертёж

Характеристики

  • MEMS-датчики: Акселерометр, гироскоп, магнитометр, барометр
  • Интерфейс: I²C
  • Напряжение питания: 3,3–5 В
  • Потребляемый ток: до 10 мА
  • Размеры: 25,4×25,4×10,1 мм
Модуль Чип I²C-адрес (без перемычки) I²C-адрес (с перемычкой) Максимальная чувствительность Диапазон измерений
Акселерометр LIS331DLH 0x18 0x19 9,8×10-3 м/с² ±2 / ±4 / ±8 g
Гироскоп I3G4250D 0x68 0x69 8,7×10-3 °/с ±250 / ±500 / ±2000 °/с²
Магнитометр LIS3MDL 0x1C 0x1E 1,46×10-4 Гс ±4/ ±8/ ±12/ ±16 Гс
Барометр LPS25HB 0x5C 0x5D 2,4×10-4 мбар 260–1260 мбар

Ресурсы