Урок 11. подключение гироскопа gy-521 mpu-6050 к arduio. – описания, примеры, подключение к arduino
Модуль Gy-521 выполнен на базе микросхемы MPU6050, это 3-осевой гироскоп и акселерометр. Данную модель можно использовать для определения положения в пространстве.
В данном уроке нам понадобится:
Для реализации проекта нам необходимо установить библиотеки:
В данном уроке рассмотрим библиотеку, которая позволяет преобразовать показания координат X и Y.
Подключение модуля производится следующим образом.
Gy-521 (mpu6050) | Arduino (Uno) |
---|---|
VCC | 3.3 V |
GND | GND |
SCL | A5 |
SDA | A4 |
Для питания модуля необходимо использовать строго 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 и выводит в консоль (Монитор последовательного порта)
Когда 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 мм |