MPU 9250 и Arduino

25-02-2020, 11:22 0 комментариев
Сегодня мы хотим познакомить вас с 9-осевым датчиком 3D положения MPU 9250. Этот модуль выбран нами для обзора совсем не случайно, а по веским причинам - из-за функциональности, практичности и миниатюрности. Его можно использовать в различных спортивных диагностирующих приборах, манипуляторах, роботах, 3D-контроллерах и аппаратах автомобильной электроники, устройствах такого плана как квадрокоптеры ∕ дроны, а также подключать к планшетам ∕ смартфонам (например, в качестве компаса или инструмента навигации).

Да и в целом любителям робототехники и проектирования подобный девайс с функцией 3 в 1 (акселерометр, гироскоп, магнитометр) точно не помешает, ведь такие устройства наравне с датчиками движения широко востребованы в среде любителей «самоделок». А раз так – нам необходимо детальнее познакомиться с его техническими характеристиками и схемами подключения к Arduino.
Начнем с первого пункта – параметры:
  • питание: 3.5 – 5 V (имеется внутренний стабилизатор);
  • интерфейс: шина I2C (400кГц), SPI (1 МГц);
  • рабочие диапазоны гироскопа: ± 250 /500 /1000 /2000 ° / сек;
  • --- акселерометра: ± 2 /± /4 ±/ 8 ± /16 г;
  • диапазон измерения магнитометра: ± 4800uT;
  • габаритные размеры: 15 x 25 мм.
Кроме того, в приборе продуманы дополнительное выводы - AUX I2C.

Теперь разберемся с главным вопросом – как подключить MPU 9250 к Ардуино. Для этой цели нам понадобятся: плата расширения Arduino Uno, непосредственно IMU датчик, макетная плата, соединительные провода (для подключения к персональному компьютеру - USB кабель). Схема подключения сенсора выглядит следующим образом (через I2C):
Для считывания данных одновременно с трех датчиков предлагаем написать такой скетч:
#include <Wire.h>
#include <TimerOne.h>
 
#define MPU9250_ADDRESS 0x68
#define MAG_ADDRESS 0x0C
 
#define GYRO_FULL_SCALE_250_DPS 0x00 
#define GYRO_FULL_SCALE_500_DPS 0x08
#define GYRO_FULL_SCALE_1000_DPS 0x10
#define GYRO_FULL_SCALE_2000_DPS 0x18
 
#define ACC_FULL_SCALE_2_G 0x00 
#define ACC_FULL_SCALE_4_G 0x08
#define ACC_FULL_SCALE_8_G 0x10
#define ACC_FULL_SCALE_16_G 0x18
 
// This function read Nbytes bytes from I2C device at address Address. 
// Put read bytes starting at register Register in the Data array. 
void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
    {
      // Set register address
      Wire.beginTransmission(Address);
      Wire.write(Register);
      Wire.endTransmission();
 
      // Read Nbytes
      Wire.requestFrom(Address, Nbytes); 
      uint8_t index=0;
      while (Wire.available())
      Data[index++]=Wire.read();
    }
 
// Write a byte (Data) in device (Address) at register (Register)
void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
    {
      // Set register address
      Wire.beginTransmission(Address);
      Wire.write(Register);
      Wire.write(Data);
      Wire.endTransmission();
    }
 
// Initial time
long int ti;
volatile bool intFlag=false;
 
// Initializations
void setup()
    {
      // Arduino initializations
      Wire.begin();
      Serial.begin(115200);
 
      // Set accelerometers low pass filter at 5Hz
      I2CwriteByte(MPU9250_ADDRESS,29,0x06);
      // Set gyroscope low pass filter at 5Hz
      I2CwriteByte(MPU9250_ADDRESS,26,0x06);
 
      // Configure gyroscope range
      I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_1000_DPS);
      // Configure accelerometers range
      I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_4_G);
      // Set by pass mode for the magnetometers
      I2CwriteByte(MPU9250_ADDRESS,0x37,0x02);
 
      // Request continuous magnetometer measurements in 16 bits
      I2CwriteByte(MAG_ADDRESS,0x0A,0x16);
 
      pinMode(13, OUTPUT);
      Timer1.initialize(10000); // initialize timer1, and set a 1/2 second period
      Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
 
      // Store initial time
      ti=millis();
    } 
 
// Counter
long int cpt=0;
 
void callback()
    { 
      intFlag=true;
      digitalWrite(13, digitalRead(13) ^ 1);
    }
 
// Main loop, read and display data
void loop()
    {
      while (!intFlag);
      intFlag=false;
 
      // Display time
      Serial.print (millis()-ti,DEC);
      Serial.print ("t");
 
      // _______________
      // ::: Counter :::
 
      // Display data counter
      // Serial.print (cpt++,DEC);
      // Serial.print ("t");
 
      // ____________________________________
      // ::: accelerometer and gyroscope :::
 
      // Read accelerometer and gyroscope
      uint8_t Buf[14];
      I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);
 
      // Create 16 bits values from 8 bits data
 
      // Accelerometer
      int16_t ax=-(Buf[0]<<8 | Buf[1]);
      int16_t ay=-(Buf[2]<<8 | Buf[3]);
      int16_t az=Buf[4]<<8 | Buf[5];
 
      // Gyroscope
      int16_t gx=-(Buf[8]<<8 | Buf[9]);
      int16_t gy=-(Buf[10]<<8 | Buf[11]);
      int16_t gz=Buf[12]<<8 | Buf[13];
 
      // Display values
 
     // Accelerometer
     Serial.print (ax,DEC); 
     Serial.print ("t");
     Serial.print (ay,DEC);
     Serial.print ("t");
     Serial.print (az,DEC); 
     Serial.print ("t");
 
     // Gyroscope
     Serial.print (gx,DEC); 
     Serial.print ("t");
     Serial.print (gy,DEC);
     Serial.print ("t");
     Serial.print (gz,DEC); 
     Serial.print ("t");
 
     // _____________________
     // ::: Magnetometer :::
 
     // Read register Status 1 and wait for the DRDY: Data Ready
 
     uint8_t ST1;
     do
         {
           I2Cread(MAG_ADDRESS,0x02,1,&ST1);
         }
     while (!(ST1&0x01));
 
     // Read magnetometer data 
     uint8_t Mag[7]; 
     I2Cread(MAG_ADDRESS,0x03,7,Mag);
 
     // Create 16 bits values from 8 bits data
 
     // Magnetometer
     int16_t mx=-(Mag[3]<<8 | Mag[2]);
     int16_t my=-(Mag[1]<<8 | Mag[0]);
     int16_t mz=-(Mag[5]<<8 | Mag[4]);
 
     // Magnetometer
     Serial.print (mx+200,DEC); 
     Serial.print ("t");
     Serial.print (my-70,DEC);
     Serial.print ("t");
     Serial.print (mz-700,DEC); 
     Serial.print ("t");
 
     // End of line
     Serial.println("");
     // delay(100); 
   }
В этой прошивке используется специализированное ПО - библиотека Wire. Ее можно отыскать и импортировать в Arduino IDE (менеджер библиотек), а вот вторую библиотеку - TimerOne - придется отыскать и скачать в Интернете (архив распаковываем в директории libraries).

На этом пока всё. Хороших вам проектов!
Поделись в социальных сетях:
О авторе
Калугин Антон

Программист микроконтроллеров с 8-ми летним стажем, работал в таких компаниях как IBM, ASUS, Microsoft.

В комментариях с радостью отвечу на ваши вопросы.

Все статьи автора
Похожие новости

Сегодня поговорим о том, как воплотить в жизнь подключение FPM10A к Arduino, что это за модуль, где используется, каковы параметры его работы и т.д. Речь идет...

В новой информационной статье хотим поговорить с вами о том, как подключить GY-521 (MPU 6050), какие задачи имеет данный модуль, где применяется и т.д. Речь...

На повестке дня – подключение L293D к Arduino, знакомство с техническими характеристиками модуля, его практическим применением и простейшими схемами сборки....

Модуль энкодер KY-040 является электромеханическим устройством, а точнее - датчиком угла поворота и вращения оси различных девайсов. Непосредственно сам прибор...

В этой статье мы рассмотрим подключение ADS1115 к Ардуино. Речь идет о 16-битном аналого-цифровом преобразователе, оснащенном 4 входами непосредственно для...

Оставить комментарий