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

Модуль GY521

Модуль GY521

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

Характеристики модуля GY-521 (MPU6050)

  • Питание (В): 3.5 – 6
  • Ток потребления (мкА): 500
  • Акселерометр диапазон измерений: ± 2 ± 4 ± 8 ± 16g
  • Гироскоп диапазон измерений: ± 250 500 1000 2000 ° / s
  • ​Интерфейс: I2C

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

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

Модуль GY521 подключение к Ардуино

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

#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 found\n");
else
{
Serial.print("Found ");
Serial.print(nDevices);
Serial.println(" device(s) ");
}
delay(2500);           // wait 5 seconds for next scan
}

I2C-адрес модуля MPU6050


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

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

#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);
}
}

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

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

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

#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 в одну и другую стороны.

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


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

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

  • Плата Arduino Nano – 1
  • Плата прототипирования – 1
  • Модуль MPU6050 – 1
  • Передатчик FS1000A – 1
  • Провода

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

  • Плата Arduino Nano – 1
  • Двухколесная движущаяся платформа – 1
  • Модуль драйвера L298N – 1
  • приемник MX-RM-5V – 1
  • Блок батарей 18650 – 1
  • ​Провода

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

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

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

#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 на движущейся платформе должна получать данные и преобразовывать их в команды установки скорости для двух моторов.

// подключение библиотеки
#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);
}
}

Пульт

Пульт

Движущаяся платформа

Движущаяся платформа


Что делать если

Нет данных с датчика MPU6050

  • Проверьте правильность подключения датчика к плате Arduino.



 

Рекомендуемые товары

Комментарии 0