Андрей Смирнов
Время чтения: ~15 мин.
Просмотров: 14

Подключаем гироскоп-акселерометр (MPU-6050) к плате Arduino

Акселерометр — это прибор, позволяющий измерять ускорение тела под действием внешних сил. Подробно об устройстве этого датчика мы уже рассказывали на одном из уроков: Акселерометр: что это такое и как им определять наклон тела

На этот раз мы перейдем от теории к практике: подключим датчик к Ардуино, и напишем пару программ для работы с ним. Подключать будем модуль MPU6050 от RobotClass.

PART-ROC-Q-MPU6050-1024x768.jpg

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

Характеристики модуля MPU6050 ROC:

  • напряжение питания: от 3,5 до 6 В;
  • потребляемый ток: 500 мкА;
  • ток в режиме пониженного потребления: 10 мкА при 1,25 Гц, 20 мкА при 5 Гц, 60 мкА при 20 Гц, 110 мкА при 40 Гц;
  • диапазон: ± 2, 4, 8, 16g;
  • разрядность АЦП: 16;
  • интерфейс: I2C (до 400 кГц).

На плате имеется 8 контактов:

  • VCC — положительный контакт питания;
  • GND — земля;
  • SDA — линия данных I2C;
  • SCL — линия синхроимпульсов I2C;
  • INT — настраиваемое прерывание;
  • AD0 — I2C адрес; по-умолчанию AD0 подтянут к земле, поэтому адрес устройства — 0x68; если соединить AD0 к контактом питания, то адрес изменится на 0x69;
  • XCL, XDA — дополнительный I2C интерфейс для подключения внешнего магнитометра.

Подключение MPU6050 к Ардуино

Соединим контакты датчика с Ардуино Уно согласно стандартной схеме для интерфейса I2C:

MPU6050 ROC GND VCC SDA SCL
Ардуино Уно GND +5V A4 A5

Принципиальная схема

ardu-mpu6050_sh.png

Внешний вид макета

ardu-mpu6050_bb-1024x693.png

Программа для получения сырых данных с акселерометра MPU6050

Составим программу, которая будет каждые 20 миллисекунд получать данные из MPU6050 и выводить их в последовательный порт.

#include "I2Cdev.h" #include "MPU6050.h"  #define T_OUT 20  MPU6050 accel;  unsigned long int t_next;  void setup() {     Serial.begin(9600);     accel.initialize();     Serial.println(accel.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); }  void loop() {     long int t = millis();     if( t_next < t ){         int16_t ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw;          t_next = t + T_OUT;         accel.getMotion6(&ax_raw, &ay_raw, &az_raw, &gx_raw, &gy_raw, &gz_raw);           Serial.println(ay_raw); // вывод в порт проекции ускорения на ось Y     } }

Для работы программы потребуются библиотеки: MPU6050 и I2Cdev, ссылки на которые можно найти в конце урока.

Загружаем программу на Ардуино и открываем окно графика. Поворачиваем датчик вокруг оси X на 90 градусов в одну сторону, потом на 90 в другую. Получится примерно такая картина.

На графике хорошо видно, что при наклоне оси Y вертикально, акселерометр выдает значения близкие к четырём тысячам. Откуда берется это число?

Точность измерения ускорения в MPU6050

Дело в том, что датчик MPU6050 позволяет настраивать точность измерений. Можно выбрать один из четырех классов точности: ±2G, 4G, 8G и 16G, где 1G — это одна земная гравитация.  Используемая нами библиотека по-умолчанию настраивает датчик на диапазон ±8G (прим. по ссылке внизу статьи библиотека по-умолчанию устанавливает ±2G).

С другой стороны, MPU6050 имеет 16 разрядный АЦП. 2 в степени 16 даст нам число 65 536. Поскольку датчик может измерять и отрицательное и положительное ускорение, то он будет выдавать нам числа от -32768 до +32768.

Сложив эти два факта вместе получаем, что при таких настройках 1G будет равен числу 4096 (ну а -1G равен числу -4096). Это вполне совпадает с наблюдаемыми на графике значениями!

Следующий шаг — преобразование этих странных чисел в привычные нам углы, измеряемые в градусах.

Программа для вычисления угла наклона акселерометра MPU6050

Добавим в предыдущую программу вычисление угла поворота датчика вокруг оси X:

#include "I2Cdev.h" #include "MPU6050.h"  #define TO_DEG 57.29577951308232087679815481410517033f #define T_OUT 20  MPU6050 accel;  float angle_ax; long int t_next;  float clamp(float v, float minv, float maxv){     if( v>maxv )         return maxv;     else if( v= 0){             angle_ax = 90 - TO_DEG*acos(ay);         } else {             angle_ax = TO_DEG*acos(-ay) - 90;         }           Serial.println(angle_ax); // вывод в порт угла поворота вокруг оси X     } }

Загружаем программу в Ардуино и снова пробуем вращать датчик. Теперь на графике отображается угол наклона в градусах!

Ну вот, мы получили уже что-то пригодное для дальнейшего использования. Видно, что датчик поворачивался сначала на 30 с лишним градусов в одну сторону, потом примерно на 60 в другую. Работает!

Заключение

На этом уроке мы получили с датчика MPU6050 сначала сырые данные, а потом и угол его наклона в градусах. Это большое достижение. Но впереди еще немного математики и еще более крутые результаты! Будем делать комплементарный фильтр, который позволит работать с датчиком даже в условиях вибрации и тряски.

Несколько идей/заданий:

  • Детектор стука, он же детектор попадания пули в мишень. Программа должна обнаружить всплеск показаний датчика по одной из осей и сигнализировать об этом, например, с помощью зуммера.
  • Кодовый замок, открывающийся по определенной последовательности стука. То же, что и в предыдущем задании, только нужно считать паузы между стуками и сверять их с эталонной последовательностью.
  • Детектор свободного падения. Если значения акселерометра по всем трем осям близки к нулю, значит тело находится в состоянии свободного падения.
  • Пульт управления роботом. Можно прикрепить датчик на перчатку и отслеживать наклоны ладони по двум осям. Передавать значения датчика через Bluetooth роботу.

Принципиальная схема датчика

Полезные ссылки

2+

Аналоговый трёхосный акселерометр ADXL335

Arduino

В этот раз мы займёмся подключением аналогового трёхосного акселерометра ADXL335 к Arduino.

Нам понадобится:

  • плата Arduino UNO или иная совместимая;
  • модуль с акселерометром ADXL335;
  • соединительные провода (рекомендую вот такой набор);
  • макетная плата (breadboard);
  • персональный компьютер со средой разработки Arduino IDE.

1Принцип действияцифрового акселерометра

Акселерометры используют для определения вектора ускорения. Акселерометр ADXL335 имеет три оси, и благодаря этому он может определять вектор ускорения в трёхмерном пространстве.

Ввиду того, что сила земного притяжения – это тоже вектор, мы можем определять ориентацию акселерометра в трёхмерном пространстве относительно центра Земли.

На иллюстрации приведены рисунки из паспорта на акселерометр ADXL335. Здесь изображены координатные оси чувствительности акселерометра по отношению к геометрическому размещению корпуса устройства в пространстве, а также значения ускорений, принимаемые с 3-х каналов акселерометра в зависимости от его ориентации в пространстве. Данные приводятся для находящегося в состоянии покоя датчика, на который действует только сила земного тяготения.

Принцип снятия измерений с аналогового акселерометра ADXL335

Рассмотрим подробнее, что же показывает нам акселерометр. Пусть датчик лежит горизонтально, например, на столе. Тогда проекция вектора ускорения будет равна «1g» по оси Z, или Zout = 1g. По остальным двум осям будут нули: Xout = 0 и Yout = 0. При повороте датчика «на спину», он будет направлен в противоположную сторону относительно вектора силы тяжести, т.е. Zout = −1g. Аналогично измерения снимаются по всем трём осям. Понятно, что акселерометр может быть расположен как угодно в пространстве, поэтому со всех трёх каналов мы будем снимать отличные от нуля показания.

Если датчик сильно тряхнуть вдоль вертикальной оси Z, то значение Zout будет больше, чем «1g». Максимальное измеряемое ускорение составляет «±3g» по каждой из осей («плюс» и «минус» тут обозначают направление ускорения).

Думаю, с принципом работы акселерометра разобрались. Теперь рассмотрим схему подключения.

2Схема подключения акселерометра к Arduino

Чип аналогового акселерометра ADXL335 довольно мелкий и помещён в BGA корпус, и в домашних условиях его сложно смонтировать на плату. Поэтому я буду использовать готовый модуль GY-61 с акселерометром ADXL335.

Для питания акселерометра необходимо подать на вывод VCC модуля напряжение +3,3 В. Измерительные каналы датчика подключаются к аналоговым выводам Arduino, например, «A0», «A1» и «A2». Это вся схема 🙂

Схема подключения аналогового трёхосевого акселерометра ADXL335 к Arduino

3Калибровкааналогового акселерометра ADXL335

Arduino имеет 10-разрядный АЦП, а максимальное допустимое напряжение на выводе – 5 вольт. Измеренные напряжения кодируются битами, которые могут принимать только 2 значения – 0 или 1. Это значит, что весь диапазон измерений будет поделён на (1+1)10, т.е. на 1024 равных отрезка. Для того чтобы перевести снимаемые показания в вольты, нужно каждое измеренное на аналоговом входе значение поделить на 1024 (отрезка), а затем умножить на 5 (вольт).

Загрузим вот такой скетч в память Arduino. Будем считывать с аналоговых входов показания по трём каналам, преобразовывать их в напряжение и выводить в последовательный порт.

Посмотрим, что же реально приходит с акселерометра на примере оси Z (см. последний столбец на иллюстрации). Когда датчик расположен горизонтально и смотрит вверх, приходят числа (2,03±0,01). Это должно соответствовать ускорению «1g» по оси Z и углу 0° согласно паспорту на ADXL335. Перевернём датчик. Приходят числа (1,69±0,01), что должно соответствовать «−1g» и углу 180°.

Калибровка аналогового акселерометра ADXL335

4Определение ускоренийпо трём осям акселерометра

Снимем значения с акселерометра при углах 90° и 270° и занесём в таблицу. Таблица показывает углы поворота акселерометра (столбец «A») и соответствующие им значения Zout в вольтах (столбец «B»).

Определение ускорений по трём осям акселерометра ADXL335

Для наглядности приведён график напряжений на выходе Zout в зависимости от угла поворота. Голубое поле – это область значений в спокойном состоянии (при ускорении 1g). Розовое поле на графике – это запас для того чтобы мы могли измерять ускорение до +3g и до −3g.

При угле поворота 90° на ось Z приходится нулевое ускорение. Т.е. значение 1,67 вольт – это условный ноль Z. Тогда определим ускорение так: g = Zout – Z / Sz, здесь Zout – измеренное значение в милливольтах, Z – значение при нулевом ускорении в милливольтах, Sz – чувствительность датчика по оси Z, измеренная в мВ/g.

Чувствительность акселерометра приведена в паспорте и равна в среднем 300 мВ/g или 0,3 В/g, но вообще лучше провести калибровку акселерометра и вычислить значение чувствительности конкретно для вашего датчика по формуле: Sz = Z(0°) – Z(90°) В данном случае чувствительность акселерометра по оси Z = 2,03 – 1,68 = 0,35 В/g. Аналогично чувствительность нужно будет посчитать для осей X и Y.

В столбце «С» таблицы приводится расчётное ускорение при чувствительности, равной 350 мВ/g. Как видно, расчёты практически совпадают с номинальными величинами, которые даются на первом рисунке из паспорта на датчик ADXL335, т.е. наш датчик довольно точно показывает свою ориентацию в пространстве (я показал это просто для самопроверки, дальше это не пригодится).

5Определение углов поворота акселерометра

Вспомнив базовый курс школьной геометрии, выведем формулу для вычисления углов поворота акселерометра: angle_X = arctg[ √(Gz2 + Gy2) / Gx ]. Значения получаются в радианах. Чтобы перевести радианы в градусы, поделим результат на число π и умножим на 180°.

В итоге полный скетч, вычисляющий ускорения и углы поворота акселерометра по всем осям, приведён на врезке. В комментариях даны пояснения к коду программы.

При выводе в порт Serial.print() символ t обозначает знак табуляции, чтобы столбцы были ровные, и значения располагались друг под другом. Символ &plus; означает конкатенацию (объединение) нескольких строк. Оператор String() явно указывает компилятору, что численное значение нужно преобразовать в строку. Оператор round() округляет угол с точностью до 1°.

Подключение аналогового акселерометра ADXL335 к Arduino с помощью макетной платы

Итак, мы с вами научились снимать и обрабатывать данные с аналогового акселерометра ADXL335 при помощи Arduino.

Полезный совет

Определите «нулевые» значения напряжений и чувствительности по осям X, Y и Z для вашего датчика с помощью скетча, описанного в разделе «Калибровка аналогового акселерометра ADXL335». Иначе углы и ускорения будут вычисляться со значительными ошибками.

Последнее изменениеПятница, 11 Январь 2019 19:56 Прочитано 24687 раз

Технический рынок наполнен тысячами модулями датчиков, которые стоят недорого и используются в проектном конструировании. Перед этим модули связывают с программируемым микроконтроллером. Акселерометр – инструмент, использующийся для расчета разности между настоящим и гравитационным ускорением предмета. Датчик состоит из платы со встроенной микросхемой.

Прибор применяют везде. Статья ниже – вспомогательная инструкция по подключению акселерометра к Ардуино.

Шаг 1. Компоненты для подключения акселерометра к Arduino

Для проекта понадобятся несколько компонентов:

Микроконтроллер Arduino UNO R3

МК создан с использованием материалов контроллера ATmega328:

  1. цифровые входы и выходы в количестве 14 штук, причем половина приходится на ШИМ-выходы;
  2. аналогичные входы, количество – 6 штук;
  3. резонатор на основе кварца, мощностью 16 МГц;
  4. встроен usb-вход;
  5. контакт для подключения питания;
  6. на МК располагается кнопка, с помощью которой возможен сброс данных и кода;
  7. контакт для программирования данных, находящихся внутри схемы, именуемый ICSP.

Старт работы начинается с подачи электрического питания в плату. Пользователь подключает к плате со схемой блок питания или зарядное устройство. Также процедура осуществляется с помощью usb-кабеля, который подключен к компьютеру и микроконтроллеру. Для разработки программы понадобится бесплатная среда программирования – Arduino IDE.

Внимание! Пользователь разрабатывает приложения с использованием Ардуино, только если платы совместимы с архитектурой микроконтроллера. В противном случае программа не заработает.

Пользователь создает в бесплатной среде код, затем его компилирует и загружает проработанную программу в пространство памяти в Ардуино. Язык, на котором программируется код, Wiring максимально приближен к популярному среди программистов языку – C++. Кроме того МК поддерживает версии для осей Виндовс, Мак ОС и Линукс.

Модуль датчика для гироскопа акселерометра на Аrduino с 3 осями – GY-521 (MPU-6050)

В основе компонента лежит микросхема MPU-6050. В комплект входят 2 предмета – гироскоп и акселерометр. Данные устройства перед конструированием обрабатываются и затем переносятся прямиком в микроконтроллер через интерфейс

Модуль датчика помогает определять место и перемещение инструмента в пространстве. Измеряются дифферент и углы крена посредством вектора силы тяжести и скорости в процессе вращения. Также включена функция измерения температурного режима. Перемещение определяется линейным ускорением и угловой скоростью. Полная картина рисуется по 3 осям.

Компонент нередко сравнивают с человеческим вестибулярным аппаратом, который помогает людям чувствовать силу тяготения и удерживать равновесие.

Макетная плата, предназначенная для прототипирования

Отладка – неотъемлемая часть построения электронных схем. Макетная плата незаменима для конструкции электронной аппаратуры. Ранее в изобретательстве использовали традиционные макетные платы, но сейчас широко распространены макетные платы, которые удобны тем, что не требуют дополнительных спаек.

Таким образом, процесс сборки и отладки электронной схемы в разы ускоряется: не приходится часто использовать паяльник, чтобы поменять сломанные радиодетали.

Материал для изготовления беспаечных макетных плат – пластик. Кроме того, все контакты надежно скреплены к плате, поэтому частые переключения не испортят элемент.

Соединительные провода папа-папа

Обычные провода папа-папа нам подойдут, еще их называют провода-перемычки. Такие стоят недорого и продаются везде, на любом рынке или в любом онлайн-магазине для радиолюбителей.

Шаг 2. Схема подключения акселерометра к микроконтроллеру Arduino

Порядок и схема подключения довольно просты:

GY-521 (MPU-6050) Arduino Uno
VCC 3.3 V
GND GND
SCL A5
SDA A4
  1. Присоединяем модуль датчика к микроконтроллеру.
  2. На МК Ардуино загружаем проработанный код, представленный в разделе ниже.
  3. Открываем среду разработки Arduino IDE и мониторим последовательный порт.
  4. Сверяем выводимые данные акселерометра и гироскопа.
  5. Во время поворота датчика сведения не производят изменений.

Гироскоп – инструмент, который позволяет измерить реакцию тела на перемещение углов и вообще ориентации. Акселерометр же служит измерителем проекции ускорения, которое только кажется.

Шаг 3. Программируем Arduino для обработки информации, полученной с акселерометра

Алгоритм написания программы в последовательности:

// Подключаем необходимые для работы библиотек  #include "MPU6050.h";  #include "I2Cdev.h";  #include "Wire.h";    // Создаем объект, символизирующий модуль датчика  MPU6050 axeler;    // Создаем объект библиотеки Wire  Wire b;    // Создаем объект, который символизирует контакт I2C  I2Cdev h;    // Вводим цифровые данные, отвечающие за точки в 3-х осях  int16_t axx, axy, axz;  int16_t gix, giy, giz;    // Объявляем метод, который будет запускать программу  void setup()    {  // Начинаем работу  Wire.begin();  h.begin(38400);    // Производим инициализацию, отчет выводится после компиляции  h.println("Initializing I2C devices...");  axeler.initialize();  delay(100);  }    // Считываем значения гироскопа и акселерометра с помощью адресов, которые принадлежат описанным выше переменным  void loop()  {  axeler.getMotion6(&axx, &axy, &axz, &gix, &giy, &giz);    // Выводим получившиеся значения на экран  h.print("a/g:t");  h.print(axx);   h.print("t");  h.print(axy);  hl.print("t");  hl.print(axz);   h.print("t");  h.print(gix);   h.print("t");  h.print(giy);   h.print("t");  h.println(giz);  }

Вуаля! Акселерометр Аrduino запрограммирован.

В принципе, для разнообразия можно написать еще один скетч (ниже), но тогда нам нужна будет еще одна библиотека — Kalman (Gy-521, mpu6050), которая преобразует показания координат X и Y.

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

После второго скетча вы на экране сможете увидеть подобные цифры:

Заключение

Модуль датчика – устройство, которое широко используется во многих сферах человеческой жизни. С помощью датчика приводят в норму полет квадрокоптера, потому что гироскоп и акселерометр часто применяются в совокупности.

Модуль помогает скоординировать различные электронные устройства. Например, часто прибор встраивают в детектор движения и систему ориентирования, которая встраивается в роботы для управления. Другие подобные устройства с поддержанием сенсорной функции пользуются успехом в иных областях.

Используемые источники:

  • https://robotclass.ru/tutorials/arduino-accelerometer-mpu6050/
  • https://soltau.ru/index.php/arduino/item/350-kak-podklyuchit-akselerometr-k-arduino
  • https://arduinoplus.ru/podkluchaem-akselerometr-k-arduino/

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации