Содержание
- Обзор
- Технические характеристики
- Подключение к Arduino
- Получение показаний
- Пример использования
- Часто задаваемые вопросы
Обзор датчика пространства GY-521 (MPU6050)
GY-521 (рис. 1) – модуль с гироскопом, акселерометром и термометром на базе микросхемы MPU-6050 используется в любительской робототехнике для определения положения в пространстве.
Рисунок 1. Модуль 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. Схема подключения показана на рис. 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 found\n"); 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 для удаленного управления движущейся платформой.
Нам потребуются следующие компоненты. Для пульта управления:
- Плата Arduino Nano – 1;
- Плата прототипирования – 1;
- Модуль MPU6050 – 1;
- передатчик FS1000A – 1;
- Провода.
Для движущейся платформы:
- Плата Arduino Nano – 1;
- Двухколесная движущаяся платформа – 1;
- Модуль драйвера L298N – 1;
- приемник MX-RM-5V – 1;
- Блок батарей 18650 – 1;
- Провода.
Схема соединения элементов пульта управления показана на рис. 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. Движущаяся платформа
Часто задаваемые вопросы
Ответ: Проверьте правильность подключения датчика к плате Arduino.