3-х осевой гироскоп и акселерометр GY-521 (MPU 6050): описание, подключение, схема, характеристики | ВИКИ

3-х осевой гироскоп и акселерометр GY-521 (MPU 6050): описание, подключение, схема, характеристики | ВИКИ Вертолеты

Урок 11. подключение гироскопа gy-521 mpu-6050 к arduio. – описания, примеры, подключение к arduino

Модуль Gy-521 выполнен на базе микросхемы MPU6050, это 3-осевой гироскоп и акселерометр. Данную модель можно использовать для определения положения в пространстве.

3-х осевой гироскоп и акселерометр GY-521 (MPU 6050): описание, подключение, схема, характеристики | ВИКИ

В данном уроке нам понадобится:

Для реализации проекта нам необходимо установить библиотеки:

В данном уроке рассмотрим библиотеку, которая позволяет преобразовать показания координат X и Y.

Подключение модуля производится следующим образом.

Gy-521 (mpu6050)Arduino (Uno)
VCC 3.3 V
GNDGND
SCLA5
SDAA4

Для питания модуля необходимо использовать строго 3.3V! Для этого можно использовать преобразователь напряжения на 3.3V.

Пришло время записать следующий скетч в нашу Arduino:

#include <Wire.h>
#include "Kalman.h"
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;
void setup() {
  Wire.begin();
  Serial.begin(9600);
  i2cWrite(0x6B,0x00); // Disable sleep mode      
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();
}
void loop() {
  /* Update all the values */
  uint8_t* data = i2cRead(0x3B,14);
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]);
  tempRaw = ((data[6] << 8) | data[7]);
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
  /* Calculate the angls based on the different sensors and algorithm */
  accYangle = (atan2(accX,accZ) PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ) PI)*RAD_TO_DEG;  
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle  = kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  gyroYangle  = kalmanY.getRate()*((double)(micros()-timer)/1000000);
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();
Serial.println();
    Serial.print("X:");
    Serial.print(kalAngleX,0);
    Serial.print(" ");
    Serial.print("Y:");
    Serial.print(kalAngleY,0);
    Serial.println(" ");
  // The accelerometer's maximum samples rate is 1kHz
}
void i2cWrite(uint8_t registerAddress, uint8_t data){
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
  uint8_t data[nbytes];
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i  )
    data [i]= Wire.read();
  return data;
}

Скачать скетч этого урока

Данный пример пересчитывает координату X и Y и выводит в консоль (Монитор последовательного порта)

3-х осевой гироскоп и акселерометр GY-521 (MPU 6050): описание, подключение, схема, характеристики | ВИКИ

Когда X и Y равны 180, значит гироскоп находится в горизонтальной плоскости.

Обзор датчика пространства gy-521 (mpu6050)

GY-521 (рис. 1) – модуль с гироскопом, акселерометром и термометром на базе микросхемы MPU-6050 используется в любительской робототехнике для  определения положения в пространстве.

Рисунок 1. Модуль GY521.

Модуль GY-521 построен на базе микросхемы MPU6050. На плате модуля также расположена необходимая обвязка MPU6050, включая подтягивающие резисторы интерфейса I2C. Гироскоп используется для измерения линейных ускорений, а акселерометр – угловых скоростей. Совместное использование акселерометра и гироскопа позволяет определить движение тела в трехмерном пространстве.

Подключение к плате arduino

Подключение к плате Arduino по интерфейсу I2C. Схема подключения показана на рис. 2.

Рисунок 2.

Загрузив на плату Arduino скетч сканирования I2C-устройств (Листинг 1), в мониторе последовательного порта увидим I2C-адрес модуля MPU6050 – 0x68 (рис. 3).

Листинг 1

#include "Wire.h"

//#define MY_SERIAL //

void setup() 
  {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("nI2C Scanner");
  Wire.begin();
  }

void loop() 
  {
  int nDevices;
  byte error, address;  
 
  Serial.println("Scanning I2C bus...n");
 

  nDevices = 0;

  Serial.print("   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
  
  
  for(address = 0; address < 128; address   )
  {
    if((address % 0x10) == 0)
    {
      Serial.println();
      if(address < 16)
        Serial.print('0');
      Serial.print(address, 16);
      Serial.print(" ");
    }
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);error = Wire.endTransmission();

    
    if (error == 0)
    {
      if (address<16)
         Serial.print("0");
      Serial.print(address, HEX);
    
      nDevices  ;
    }
    else 
    {
      Serial.print("--");
    } 

    Serial.print(" ");
    delay(1);
  }
  Serial.println();
  
  if (nDevices == 0)
     Serial.println("No I2C devices foundn");
   else
   {
    
     Serial.print("Found ");
     Serial.print(nDevices);
     Serial.println(" device(s) "); 
   }
 
  delay(2500);           // wait 5 seconds for next scan

  }

Рисунок 3.

Получение показаний датчика mpu6050

Для работы с датчиком MPU6050 будем использовать библиотеки I2Cdev и MPU6050. После установки библиотек загрузим на плату Arduino скетч для отображения показаний акселерометра по одной из осей – оси x. Содержимое скетча показано в листинге 2.

Листинг 2

#include "I2Cdev.h"
#include "MPU6050.h"

#define TIME_OUT 20

MPU6050 accgyro;
unsigned long int t1;

void setup() {
    Serial.begin(9600);
    accgyro.initialize();
}

void loop() {
    long int t = millis();
    if( t1 < t ){
        int16_t ax, ay, az, gx, gy, gz;

        t1 = t   TIME_OUT;
        accgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
        Serial.println(ax); 
    }
}


Для отображения данных выбираем в настройках Плоттер по последовательному соединению (рис. 4). Смотрим показания вращая датчик по оси x в одну и другую стороны.

Рисунок 4.

Библиотека MPU6050 по умолчанию настраивает датчик на диапазон ±8g (возможные значения ±2g, 4g, 8g и 16g). для 16 разрядного АЦП датчика это значения от -215
до 215 , поэтому возможные значения на графике ±215/16*8 (-16384 до 16384).


Скетч из листинга 3 преобразует сырые показания датчика MPU6050 в угол наклона датчика относительно оси x.

Листинг 3

#include "I2Cdev.h"
#include "MPU6050.h"

#define TO_DEG 57.2957f
#define TIME_OUT 20

MPU6050 accgyro;

float anglex;
long int t1;

void setup() {
    Serial.begin(9600);
    // инициализация датчика 
    accgyro.initialize(); 
}

void loop() {
    long int t = millis();
    if( t1 < t ){
        int16_t ax, ay, az, gx, gy, gz;
        float accy,gyrox;

        t1 = t   TIME_OUT;
        accgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
 
        // преобразование в единицы гравитации при настройках 1G 
        accy = ax /4096.0;
        //  границы от -1G до  1G  
        accy = clamp(accy, -1.0, 1.0);
        // получить значение в градусах
        if( accy >= 0){
            anglex = 90 - TO_DEG*acos(accy);
        } else {
            anglex = TO_DEG*acos(-ay) - 90;
        }
        Serial.println(anglex); 
    }
}

И смотрим показания угла наклона, вращая датчик по оси x в одну и другую стороны (рис. 5).

Рисунок 5.

Пример использования


В качестве примера рассмотрим проект по созданию пульта на MPU6050 для удаленного управления движущейся платформой.

Нам потребуются следующие компоненты. Для пульта управления:

Для движущейся платформы:


Схема соединения элементов пульта управления показана на рис. 6.

Рисунок 6.

Схема соединений для компонентов для движущейся платформы показана на рис. 7.

Рисунок 7.

Приступим к написанию скетчей. Передатчик отправляет 3 значения – начальный байт отправки B11111111 и 2 значения наклона датчика – по оси x и по оси y.

Содержимое скетча показано в листинге 4.

Листинг 4

#include "I2Cdev.h"
#include "MPU6050.h"
#include <RCSwitch.h>

#define TO_DEG 57.2957f
#define TIME_OUT 20

MPU6050 accgyro;
RCSwitch mySwitch = RCSwitch();

float anglex;
float angley;
long int t1;

void setup() {
    Serial.begin(9600);
    // инициализация датчика 
    accgyro.initialize(); 
    mySwitch.enableTransmit(2);
}

void loop() {
    long int t = millis();
    if( t1 < t ){
        int16_t ax, ay, az, gx, gy, gz;
        float accy,gyrox;

        t1 = t   TIME_OUT;
        accgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
 
        // преобразование в единицы гравитации при настройках 1G = 4096
        accx = ax/4096.0;
        accy = ax/4096.0;
        // границы от -1G до  1G  
        accx = clamp(accx, -1.0, 1.0);
        accy = clamp(accy, -1.0, 1.0);

        // получить значение в градусах
        if( accy >= 0){
            anglex = 90 - TO_DEG*acos(accy);
        } else {
            anglex = TO_DEG*acos(-accy) - 90;
        }
        if( accx >= 0){
            angley = 90 - TO_DEG*acos(accx);
        } else {
            angley = TO_DEG*acos(-accx) - 90;
        }
        // отправка данных
        mySwitch.send(B11111111, 8);
        delay(50);
        mySwitch.send((byte)anglex, 8);
        delay(50);
        mySwitch.send((byte)angley, 8);
        delay(100); 
    }
}

Плата Arduino на движущейся платформе должна получать данные и преобразовывать их в команды установки скорости для двух моторов.

Содержимое скетча показано в листинге 5.

Листинг 5

// подключение библитеки
#include <RCSwitch.h>
// создание объекта
RCSwitch mySwitch = RCSwitch();

int motor=0;

void setup() {
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(6,OUTPUT);
  // запуск приемника
  mySwitch.enableReceive(0);
}

void loop() {
    if( mySwitch.available() ){
        // получить данные
        int value = mySwitch.getReceivedValue();
        
        if( value == B11111111 ) {// начало передачи
            motor=1;
        }
        else {
            if(motor==1) {
                go(10,9,8,value);
            }
            else if(motor==2) {
                go(5,7,6,value);
            }
            motor  ;
        }
        mySwitch.resetAvailable();
    }
}
// запуск двигателей
void go(int pina,int pin1,int pin2,int val) {
   analogWrite(pina,map(abs(val),0,90,0,255));
   if(val<=0) {
      digitalWrite(pin1,0);
      digitalWrite(pin2,1);
   }
   else {
      digitalWrite(pin1,1);
      digitalWrite(pin2,0);
   }
}

Рисунок 8. Пульт

Рисунок 9. Движущаяся платформа

Технические характеристики

МодульGY-6500
ЧипMPU-6500, 16 битный АЦП, 16-ти битный вывод данных
Напряжение питания3 – 5 Вольт
Интерфейсстандартный I2C (400кГц) / SPI (1 МГц) протокол связи
Рабочие диапазоны акселерометра /- 2G, /- 4G, /- 8G, /- 16 G
Рабочие диапазоны гироскопа /- 250, /- 500, /- 1000, /- 2000°/с
Рабочий токгироскоп – 3,2 мА, акселерометр – 450 мкА
Ток в режиме сна8 8 мкА (гироскоп акселерометр)
Габариты25 х 16 x 3 мм
Вес модуля2 г
Диаметр отверстий для монтажа3 мм (2 шт.)
Шаг распиновки2.54 мм
Смотрите про коптеры:  Приложение mi home плохо работает
Оцените статью
Радиокоптер.ру
Добавить комментарий