ESP32 с MPU-6050: акселерометр, гироскоп и датчик температуры (Arduino)

В этом руководстве вы узнаете, как использовать модуль акселерометра и гироскопа MPU-6050 с ESP32. MPU-6050 IMU (Inertial Measurement Unit – инерциальный измерительный модуль) представляет собой 3-осевой акселерометр и 3-осевой гироскоп. Акселерометр измеряет гравитационное ускорение, а гироскоп – угловую скорость вращения. Кроме того, этот модуль также измеряет температуру. Данный датчик идеально подходит для определения ориентации движущегося объекта.

ESP32 с модулем MPU-6050 -- акселерометр, гироскоп, датчик температуры, Arduino

У нас есть аналогичное руководство для ESP8266: ESP8266 NodeMCU with MPU-6050 Accelerometer, Gyroscope and Temperature Sensor (Arduino)

В этом руководстве мы рассмотрим два примера:

  1. Получение показаний гироскопа, акселерометра и температуры (Serial Monitor)

  2. Отображение показаний гироскопа и акселерометра на OLED-дисплее

Знакомство с датчиком MPU-6050 (гироскоп и акселерометр)

MPU-6050 – это модуль с 3-осевым акселерометром и 3-осевым гироскопом.

Модуль MPU-6050 -- акселерометр, гироскоп, датчик температуры

Гироскоп измеряет угловую скорость вращения (рад/с) – это изменение углового положения во времени по осям X, Y и Z (крен, тангаж и рыскание). Это позволяет определить ориентацию объекта.

Углы крена, тангажа и рыскания (Roll, Pitch, Yaw)

Акселерометр измеряет ускорение (скорость изменения скорости объекта). Он воспринимает статические силы, такие как гравитация (9,8 м/с2), а также динамические силы, такие как вибрации или движение. MPU-6050 измеряет ускорение по осям X, Y и Z. В идеале, для неподвижного объекта ускорение по оси Z равно гравитационной силе, а по осям X и Y должно быть равно нулю.

Используя значения акселерометра, можно вычислить углы крена (roll) и тангажа (pitch) с помощью тригонометрии. Однако вычислить угол рыскания (yaw) таким способом невозможно.

Мы можем комбинировать информацию от обоих датчиков для получения более точных данных об ориентации сенсора.

Распиновка MPU-6050

Ниже представлена распиновка модуля датчика MPU-6050.

VCC

Питание датчика (3.3 В или 5 В)

GND

Общий провод (земля)

SCL

Линия тактового сигнала I2C (GPIO 22)

SDA

Линия данных I2C (GPIO 21)

XDA

Используется для подключения других I2C-датчиков к MPU-6050

XCL

Используется для подключения других I2C-датчиков к MPU-6050

AD0

Используется для изменения I2C-адреса

INT

Вывод прерывания – может использоваться для индикации доступности новых данных измерений

Подготовка Arduino IDE

Мы будем программировать плату ESP32 с помощью Arduino IDE. Убедитесь, что у вас установлено дополнение для ESP32. Следуйте следующему руководству:

Если вы предпочитаете использовать VS Code + PlatformIO IDE, следуйте этому руководству:

Установка библиотек

Существует несколько способов получения данных с датчика. В этом руководстве мы будем использовать библиотеку Adafruit MPU6050. Для работы с этой библиотекой также необходимо установить библиотеки Adafruit Unified Sensor и Adafruit Bus IO.

Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Откроется менеджер библиотек.

Введите «adafruit mpu6050» в строке поиска и установите библиотеку.

Установка библиотеки Adafruit MPU6050 в Arduino IDE

Затем найдите «Adafruit Unified Sensor». Прокрутите вниз, чтобы найти библиотеку, и установите её.

Установка библиотеки Adafruit Unified Sensor в Arduino IDE

Наконец, найдите «Adafruit Bus IO» и установите её.

Установка библиотеки Adafruit Bus IO в Arduino IDE

После установки библиотек перезапустите Arduino IDE.

Если вы используете VS Code с PlatformIO, скопируйте следующие строки в файл platformio.ini.

lib_deps = adafruit/Adafruit MPU6050 @ ^2.0.3
    adafruit/Adafruit Unified Sensor @ ^1.1.4

Получение показаний датчика MPU-6050: акселерометр, гироскоп и температура

В этом разделе вы узнаете, как получить показания с датчика MPU-6050: ускорение (x, y, z), угловую скорость (x, y, z) и температуру.

Необходимые компоненты

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

Схема подключения – ESP32 с MPU-6050

Подключите ESP32 к датчику MPU-6050, как показано на следующей схеме: подключите вывод SCL к GPIO 22, а вывод SDA к GPIO 21.

Схема подключения MPU-6050 к ESP32

Код – Получение показаний датчика MPU-6050: акселерометр, гироскоп и температура

Библиотека Adafruit предоставляет несколько примеров для этого датчика. В этом разделе мы рассмотрим базовый пример, который выводит показания датчика в Serial Monitor.

Перейдите в File > Examples > Adafruit MPU6050 > basic_readings. Должен загрузиться следующий код.

Он получает угловую скорость (гироскоп) по осям x, y и z, ускорение по осям x, y и z, а также температуру.

// Basic demo for accelerometer readings from Adafruit MPU6050

// ESP32 Guide: https://RandomNerdTutorials.com/esp32-mpu-6050-accelerometer-gyroscope-arduino/
// ESP8266 Guide: https://RandomNerdTutorials.com/esp8266-nodemcu-mpu-6050-accelerometer-gyroscope-arduino/
// Arduino Guide: https://RandomNerdTutorials.com/arduino-mpu-6050-accelerometer-gyroscope/

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit MPU6050 test!");

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);
}

void loop() {
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(500);
}

Исходный код (basic_readings)

Как работает код

Начните с подключения необходимых библиотек для датчика MPU-6050: Adafruit_MPU6050 и Adafruit_Sensor.

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

Создайте объект Adafruit_MPU6050 с именем mpu для работы с датчиком.

Adafruit_MPU6050 mpu;

setup()

В функции setup() инициализируйте Serial Monitor на скорости 115200 бод.

Serial.begin(115200);

Инициализируйте датчик MPU-6050.

if (!mpu.begin()) {
  Serial.println("Sensor init failed");
  while (1)
    yield();
}

Установите диапазон измерения акселерометра:

mpu.setAccelerometerRange(MPU6050_RANGE_8_G);

Установите диапазон измерения гироскопа:

mpu.setGyroRange(MPU6050_RANGE_500_DEG);

Установите полосу пропускания фильтра:

mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);

loop()

В функции loop() мы получаем показания датчика и выводим их в Serial Monitor.

Сначала необходимо получить новые события датчика с текущими показаниями.

sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);

Далее выводим показания. Для ускорения:

  • a.acceleration.x: получает ускорение по оси x;

  • a.acceleration.y: получает ускорение по оси y;

  • a.acceleration.z: получает ускорение по оси z.

Ускорение измеряется в метрах в секунду в квадрате (м/с2).

Serial.print("Acceleration X: ");
Serial.print(a.acceleration.x);
Serial.print(", Y: ");
Serial.print(a.acceleration.y);
Serial.print(", Z: ");
Serial.print(a.acceleration.z);
Serial.println(" m/s^2");

Для получения показаний гироскопа:

  • g.gyro.x: получает угловую скорость по оси x;

  • g.gyro.y: получает угловую скорость по оси y;

  • g.gyro.z: получает угловую скорость по оси z.

Угловая скорость измеряется в радианах в секунду (рад/с).

Serial.print("Rotation X: ");
Serial.print(g.gyro.x);
Serial.print(", Y: ");
Serial.print(g.gyro.y);
Serial.print(", Z: ");
Serial.print(g.gyro.z);
Serial.println(" rad/s");

Наконец, выводим температуру – она измеряется в градусах Цельсия. Для доступа к показаниям температуры используйте temp.temperature.

Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degC");

Новые показания датчика выводятся каждые 500 миллисекунд.

delay(500);

Демонстрация

Загрузите код на плату ESP32. Перейдите в Tools > Board и выберите используемую плату ESP32. Перейдите в Tools > Port и выберите порт, к которому подключена плата. Затем нажмите кнопку Upload.

Откройте Serial Monitor на скорости 115200 бод, нажмите кнопку RST на плате. На экране отобразятся показания датчика.

Перемещайте датчик и наблюдайте за изменением значений.

Показания датчика MPU-6050 в Serial Monitor Arduino IDE

Калибровка датчика

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

  • x: 0.06 рад/с

  • y: -0.02 рад/с

  • z: 0.00 рад/с

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

То же самое касается значений ускорения. Ускорение по оси Z должно быть ближе к гравитационной силе (9,8 м/с2), а по осям X и Y должно быть ближе к нулю. В нашем случае мы получаем следующие приблизительные значения, когда датчик неподвижен:

  • x: 0.71 м/с2

  • y: 0.28 м/с2

  • z: 9.43 м/с2

Отображение показаний MPU-6050 на OLED-дисплее

ESP32 с MPU-6050 и OLED-дисплеем -- демонстрация

Библиотека Adafruit MPU6050 предоставляет пример, который отображает показания гироскопа и акселерометра MPU-6050 на OLED-дисплее.

Необходимые компоненты

Список компонентов, необходимых для выполнения этого примера:

Схема подключения – ESP32 с MPU-6050 и OLED-дисплеем

Подключите все компоненты, как показано на следующей схеме. Поскольку OLED-дисплей и датчик MPU-6050 используют разные I2C-адреса, мы можем подключить их к одной шине I2C (к одним и тем же выводам ESP32).

Схема подключения ESP32 с MPU-6050 и OLED-дисплеем

Подробнее об использовании OLED-дисплея с ESP32: ESP32 OLED Display with Arduino IDE

Код – Отображение показаний MPU-6050 на OLED-дисплее

Для использования этого примера убедитесь, что у вас установлена библиотека Adafruit SSD1306. Эту библиотеку можно установить через менеджер библиотек Arduino.

Перейдите в Sketch > Library > Manage Libraries и найдите «SSD1306», затем установите библиотеку SSD1306 от Adafruit.

Установка библиотеки SSD1306 Adafruit в Arduino IDE

Для этого примера скопируйте следующий код или перейдите в File > Examples > Adafruit MPU6050 > MPU6050_oled.

// Basic OLED demo for accelerometer readings from Adafruit MPU6050

// ESP32 Guide: https://RandomNerdTutorials.com/esp32-mpu-6050-accelerometer-gyroscope-arduino/
// ESP8266 Guide: https://RandomNerdTutorials.com/esp8266-nodemcu-mpu-6050-accelerometer-gyroscope-arduino/
// Arduino Guide: https://RandomNerdTutorials.com/arduino-mpu-6050-accelerometer-gyroscope/

#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

void setup() {
  Serial.begin(115200);
  // while (!Serial);
  Serial.println("MPU6050 OLED demo");

  if (!mpu.begin()) {
    Serial.println("Sensor init failed");
    while (1)
      yield();
  }
  Serial.println("Found a MPU-6050 sensor");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setRotation(0);
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  display.clearDisplay();
  display.setCursor(0, 0);

  Serial.print("Accelerometer ");
  Serial.print("X: ");
  Serial.print(a.acceleration.x, 1);
  Serial.print(" m/s^2, ");
  Serial.print("Y: ");
  Serial.print(a.acceleration.y, 1);
  Serial.print(" m/s^2, ");
  Serial.print("Z: ");
  Serial.print(a.acceleration.z, 1);
  Serial.println(" m/s^2");

  display.println("Accelerometer - m/s^2");
  display.print(a.acceleration.x, 1);
  display.print(", ");
  display.print(a.acceleration.y, 1);
  display.print(", ");
  display.print(a.acceleration.z, 1);
  display.println("");

  Serial.print("Gyroscope ");
  Serial.print("X: ");
  Serial.print(g.gyro.x, 1);
  Serial.print(" rps, ");
  Serial.print("Y: ");
  Serial.print(g.gyro.y, 1);
  Serial.print(" rps, ");
  Serial.print("Z: ");
  Serial.print(g.gyro.z, 1);
  Serial.println(" rps");

  display.println("Gyroscope - rps");
  display.print(g.gyro.x, 1);
  display.print(", ");
  display.print(g.gyro.y, 1);
  display.print(", ");
  display.print(g.gyro.z, 1);
  display.println("");

  display.display();
  delay(100);
}

Исходный код (MPU6050_oled)

Как работает код

Начните с подключения необходимых библиотек для датчика MPU-6050 и OLED-дисплея.

#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

Создайте объект Adafruit_MPU6050 с именем mpu для работы с датчиком.

Adafruit_MPU6050 mpu;

Создайте объект Adafruit_SSD1306 с именем display для работы с OLED-дисплеем. Это для дисплея с разрешением 128x64 пикселей.

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

setup()

В функции setup() инициализируйте Serial Monitor на скорости 115200 бод.

Serial.begin(115200);

Инициализируйте датчик MPU-6050.

if (!mpu.begin()) {
  Serial.println("Sensor init failed");
  while (1)
    yield();
}

Инициализируйте OLED-дисплей.

// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
  Serial.println(F("SSD1306 allocation failed"));
  for (;;)
    ; // Don't proceed, loop forever
}
display.display();

Установите размер шрифта и цвет для дисплея.

display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);

loop()

В функции loop() мы получаем показания датчика и выводим их на OLED-дисплей.

Начните с создания событий для каждого измерения: акселерометра, гироскопа и температуры.

sensors_event_t a, g, temp;

Получите новые показания датчика.

mpu.getEvent(&a, &g, &temp);

Очистите дисплей в каждом цикле loop() для записи новых показаний.

display.clearDisplay();

Установите курсор дисплея в позицию (0,0) – верхний левый угол. Текст будет выводиться начиная с этого места.

display.setCursor(0, 0);

Следующие строки выводят показания акселерометра в Serial Monitor.

Serial.print("Accelerometer ");
Serial.print("X: ");
Serial.print(a.acceleration.x, 1);
Serial.print(" m/s^2, ");
Serial.print("Y: ");
Serial.print(a.acceleration.y, 1);
Serial.print(" m/s^2, ");
Serial.print("Z: ");
Serial.print(a.acceleration.z, 1);
Serial.println(" m/s^2");

Следующие строки отображают значения ускорения по осям x, y и z на OLED-дисплее.

display.println("Accelerometer - m/s^2");
display.print(a.acceleration.x, 1);
display.print(", ");
display.print(a.acceleration.y, 1);
display.print(", ");
display.print(a.acceleration.z, 1);
display.println("");

Вывод показаний гироскопа в Serial Monitor.

Serial.print("Gyroscope ");
Serial.print("X: ");
Serial.print(g.gyro.x, 1);
Serial.print(" rps, ");
Serial.print("Y: ");
Serial.print(g.gyro.y, 1);
Serial.print(" rps, ");
Serial.print("Z: ");
Serial.print(g.gyro.z, 1);
Serial.println(" rps");

Наконец, вывод показаний гироскопа на дисплей.

display.println("Gyroscope - rps");
display.print(g.gyro.x, 1);
display.print(", ");
display.print(g.gyro.y, 1);
display.print(", ");
display.print(g.gyro.z, 1);
display.println("");

В завершение вызовите display.display() для фактического отображения показаний на OLED-дисплее.

display.display();

Новые показания отображаются каждые 100 миллисекунд.

delay(100);

Демонстрация

Загрузите код на плату ESP32. Перейдите в Tools > Board и выберите используемую плату ESP32. Перейдите в Tools > Port и выберите порт, к которому подключена плата. Затем нажмите кнопку Upload.

Откройте Serial Monitor на скорости 115200 бод, нажмите кнопку RST на плате. Показания датчика будут отображаться как в Serial Monitor, так и на OLED-дисплее.

Демонстрация работы MPU-6050 с OLED-дисплеем на ESP32

Перемещайте датчик и наблюдайте за изменением значений.

Показания датчика MPU-6050 с OLED в Serial Monitor

Заключение

MPU-6050 – это акселерометр и гироскоп. Он измеряет ускорение по осям x, y и z, а также угловую скорость. Этот модуль также измеряет температуру.

Данный модуль датчика обменивается данными по протоколу I2C. Поэтому подключение очень простое. Достаточно подключить датчик к стандартным выводам I2C на ESP32.

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

Узнайте больше о ESP32 с нашими ресурсами:

Спасибо за чтение.


Источник: ESP32 with MPU-6050 Accelerometer, Gyroscope and Temperature Sensor (Arduino)