Акселерометр и гироскоп BMI160

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

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

Микросхема BMI160 от компании BOSCH имеет в своём составе трёхосевой акселерометр и трёхосевой гироскоп, выполненные по технологии MEMS. BMI160 может работать как по I2C, так и по SPI интерфейсу. Для оцифровки сигналов датчиков используется 16-разрядный АЦП.

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

Акселерометр и гироскоп BMI160 RobotClass

Характеристики модуля BMI160 RobotClass:

  • напряжение питания: от 3,3 до 5 В;
  • рабочий ток: от 925 мкА (без учёта потребления светодиода на плате);
  • гироскоп, диапазон: ± 125, 250, 500, 1000, 2000 °/с;
  • акселерометр, диапазон: ± 2, 4, 8, 16g;
  • разрядность АЦП: 16;
  • интерфейс: SPI либо I2C (до 1 МГц).

СПИСОК НЕОБХОДИМЫХ КОМПОНЕНТОВ

Для выполнения простого примера с датчиком BMI160 от RobotClass, кроме самого модуля датчика, потребуется Ардуино-совместимый контроллер и немного проводов. Если вам не хватает чего-то из этого, можно добавить необходимые компоненты в корзину прямо здесь и затем оформить заказ в нашем интернет-магазине.

В корзину
В корзину
В корзину

Подключение BMI160 к Arduino

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

  • VIN — положительный контакт питания, на него можно подать напряжение от 3,5 до 6 Вольт;
  • 3.3 — положительный контакт питания, на него можно подать 3,3 Вольт. В случае питания платы через VIN, данный контакт можно использовать как дополнительный источник напряжения 3,3 Вольт со свободным током 200 мА;
  • G — земля;
  • SDA/MO — линия данных I2C, либо линия MOSI для SPI;
  • SCL/SCK — линия синхроимпульсов I2C, либо SCK для SPI;
  • NC/MI — линия MOSI для SPI;
  • AD/CS — выбор адреса на шине I2C, либо Chip Select для SPI;
  • INT — настраиваемое прерывание.

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

BMI160 RobotClassGVINSDASCL
Arduino Uno или аналогGND+5VA4A5

Про выбор адреса шины I2C

Датчика BMI160 может работать на двух возможных адресах: 0x68 и 0x69. Выбор адреса зависит от состояния контакта AD. В исходном состоянии контакт AD подтянут к земле через резистор на плате, поэтому адрес устройства — 0x68. При необходимости, можно соединить контакт AD с контактом питания и адрес изменится на 0x69.

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

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

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

#include <DFRobot_BMI160.h>

DFRobot_BMI160 bmi160;

// будем использовать такой адрес
const int8_t i2c_addr = 0x69;
 

void setup(){
    Serial.begin(9600);
    delay(100);
  
    // инициализация датчика
    if (bmi160.softReset() != BMI160_OK){
        Serial.println("reset false");
        while(1);
    }
  
    // подключение к датчику по указанному адресу
    if (bmi160.I2cInit(i2c_addr) != BMI160_OK){
        Serial.println("init false");
        while(1);
    }
}

void loop(){
    int i = 0;
    int rslt;

    // в этом массиве будем хранить данные
    // с 0 по 2 индекс - показания гироскопа
    // с 3 по 5 индекс - показания акселерометра
    int16_t accelGyro[6]={0}; 

    // функция запрашивает данные у датчика
    // и размещает результат в нашем массиве accelGyro
    rslt = bmi160.getAccelGyroData(accelGyro);
    if(rslt == 0){
        Serial.print(accelGyro[3]);
        Serial.println();
    } else {
        Serial.println("err");
    }
    delay(100);
}

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

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

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

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

Используемая нами библиотека по-умолчанию настраивает датчик на диапазон ±2G (разные версии библиотеки могут настраивать датчик по-разному). Разумеется, можно указать подходящий для конкретной задачи диапазон при помощи соответствующей функции.

BMI160 имеет 16 разрядный АЦП. С учётом установленного диапазона измерений: от -2G до 2G, датчик выдаст нам число от -32768 до 32767. Соответственно, если корпус BMI160 наклонён так, что сила гравитации действует вдоль выбранной для измерений оси, то он выдаст число 16384, что будет эквивалентно 1G — одной земной гравитации.

Именно это мы и наблюдаем на графике. Чтобы получить из датчика значения не в условных единицах, а в G, следует разделить измеренную величину на 16386. Вот так:

Serial.print(accelGyro[3]/16384.0);

Снова загружаем программу и наклоняем датчик. График будет выглядеть так:

Теперь наклоняя модуль датчика мы видим значения близкие к 1G.

К сведению. В спецификации к любому цифровому датчику имеются значения коэффициентов для всех возможных диапазонов измерений. В частности, для датчика BMI160, настройке от -2G до 2G как раз соответствует так называемая чувствительность 16384 LSB/G.

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

В действительности, в предыдущей программе мы уже получили данные и акселерометра и гироскопа. Нам лишь нужно отобразить на графике какой-нибудь элемент массива с индексом от 0 до 2. Пусть это будут данные для оси X — возьмём индекс 0.

Serial.print(accelGyro[0]);

Загружаем программу в Arduino и снова пробуем вращать датчик вокруг оси X (а не вдоль, как в прошлый раз). Вращаем со скоростью один оборот в секунду, ну или около того. Сначала полный оборот в одну сторону, потом полный в другую.

Здесь та же история, что и с ускорением: условные единицы нужно ещё перевести в градусы в секунду. Используемая нами библиотека устанавливает по-умолчанию диапазон измерений от -2000 до 2000 градусов в секунду. Следовательно, чтобы получить значения в нужных единицах измерения следует посмотреть спецификацию и найти нужное значение чувствительности.

Для данного диапазона чувствительность равна 16,4. Используем это число для корректировки показаний датчика:

Serial.print(accelGyro[0]/16.4);

Опять вращаем датчик вокруг оси X со скоростью один оборот в секунду.

Похоже на правду. График показал максимальную угловую скорость 360 градусов в секунду.

Сама по себе скорость вращения вокруг оси — не очень полезная информация (конечно, если перед вами не стоит задача определить угловую скорость летящей ракеты). А вот если скорость проинтегрировать, получим уже угол поворота. Но как это делать, разберём в другой раз.

К размышлению

Получить данные с датчика — пол дела. Чтобы эти данные можно было использовать для целей позиционирования устройства в пространстве, требуется некоторое количество математической обработки, такой как альфа-бета фильтр или фильтр Мажвика. Разобравшись с этими фильтрами, можно сделать простой гироподвес на сервомоторах или даже дрона с собственной системой стабилизации.

Однако, несколько идей всё-таки можно реализовать и без дополнительных знаний.

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

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

Принципиальная схема модуля BMI160 RobotClass

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


Изменено:

Акселерометр и гироскоп BMI160: 3 комментария

  1. По ссылкам «Спецификация производителя BMI160» и «Библиотека BMI160 от DFRobot» находятся файлы для MPU6050

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.