ESP32 с MPU-6050: акселерометр, гироскоп и датчик температуры (Arduino)
В этом руководстве вы узнаете, как использовать модуль акселерометра и гироскопа MPU-6050 с ESP32. MPU-6050 IMU (Inertial Measurement Unit – инерциальный измерительный модуль) представляет собой 3-осевой акселерометр и 3-осевой гироскоп. Акселерометр измеряет гравитационное ускорение, а гироскоп – угловую скорость вращения. Кроме того, этот модуль также измеряет температуру. Данный датчик идеально подходит для определения ориентации движущегося объекта.
У нас есть аналогичное руководство для ESP8266: ESP8266 NodeMCU with MPU-6050 Accelerometer, Gyroscope and Temperature Sensor (Arduino)
В этом руководстве мы рассмотрим два примера:
Получение показаний гироскопа, акселерометра и температуры (Serial Monitor)
Отображение показаний гироскопа и акселерометра на OLED-дисплее
Знакомство с датчиком MPU-6050 (гироскоп и акселерометр)
MPU-6050 – это модуль с 3-осевым акселерометром и 3-осевым гироскопом.
Гироскоп измеряет угловую скорость вращения (рад/с) – это изменение углового положения во времени по осям X, Y и Z (крен, тангаж и рыскание). Это позволяет определить ориентацию объекта.
Акселерометр измеряет ускорение (скорость изменения скорости объекта). Он воспринимает статические силы, такие как гравитация (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 Unified Sensor». Прокрутите вниз, чтобы найти библиотеку, и установите её.
Наконец, найдите «Adafruit Bus IO» и установите её.
После установки библиотек перезапустите 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: акселерометр, гироскоп и температура
Библиотека 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);
}
Как работает код
Начните с подключения необходимых библиотек для датчика 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 на плате. На экране отобразятся показания датчика.
Перемещайте датчик и наблюдайте за изменением значений.
Калибровка датчика
В идеале, когда датчик неподвижен, значения гироскопа должны быть равны нулю по всем осям, но в нашем случае это не так. Когда датчик неподвижен, мы получаем следующие значения гироскопа:
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-дисплее
Библиотека Adafruit MPU6050 предоставляет пример, который отображает показания гироскопа и акселерометра MPU-6050 на OLED-дисплее.
Необходимые компоненты
Список компонентов, необходимых для выполнения этого примера:
Схема подключения – ESP32 с MPU-6050 и OLED-дисплеем
Подключите все компоненты, как показано на следующей схеме. Поскольку OLED-дисплей и датчик MPU-6050 используют разные I2C-адреса, мы можем подключить их к одной шине I2C (к одним и тем же выводам ESP32).
Подробнее об использовании OLED-дисплея с ESP32: ESP32 OLED Display with Arduino IDE
Код – Отображение показаний MPU-6050 на OLED-дисплее
Для использования этого примера убедитесь, что у вас установлена библиотека Adafruit SSD1306. Эту библиотеку можно установить через менеджер библиотек Arduino.
Перейдите в Sketch > Library > Manage Libraries и найдите «SSD1306», затем установите библиотеку SSD1306 от Adafruit.
Для этого примера скопируйте следующий код или перейдите в 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);
}
Как работает код
Начните с подключения необходимых библиотек для датчика 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 – это акселерометр и гироскоп. Он измеряет ускорение по осям x, y и z, а также угловую скорость. Этот модуль также измеряет температуру.
Данный модуль датчика обменивается данными по протоколу I2C. Поэтому подключение очень простое. Достаточно подключить датчик к стандартным выводам I2C на ESP32.
В этом руководстве вы научились подключать датчик и получать его показания. Надеемся, это вводное руководство было полезным. У нас есть руководства по другим популярным датчикам:
ESP32 с датчиком температуры и влажности DHT11/DHT22 (Arduino IDE)
ESP32 с BME280 (Arduino IDE) – давление, температура, влажность
ESP32 с барометрическим датчиком BMP180 (температура и давление)
ESP32 с датчиком окружающей среды BME680 (газ, давление, влажность, температура)
Узнайте больше о ESP32 с нашими ресурсами:
Спасибо за чтение.
Источник: ESP32 with MPU-6050 Accelerometer, Gyroscope and Temperature Sensor (Arduino)