Акселерометр — это прибор, позволяющий измерять ускорение тела под действием внешних сил. Подробно об устройстве этого датчика мы уже рассказывали на одном из уроков: Акселерометр: что это такое и как им определять наклон тела.
Гироскоп, он же гиротахометр — устройство для определения угловой скорости вращения. Зная скорость вращения, можно вычислить угол поворота тела. А вместе с акселерометром эти два датчика позволяют сделать альфа-бета фильтр для создания инклинометра.
Микросхема BMI160 от компании BOSCH имеет в своём составе трёхосевой акселерометр и трёхосевой гироскоп, выполненные по технологии MEMS. BMI160 может работать как по I2C, так и по SPI интерфейсу. Для оцифровки сигналов датчиков используется 16-разрядный АЦП.
На этом уроке раз мы подключим датчик 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 RobotClass | G | VIN | SDA | SCL |
Arduino Uno или аналог | GND | +5V | A4 | A5 |
Про выбор адреса шины 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» и «Библиотека BMI160 от DFRobot» находятся файлы для MPU6050
Спасибо, исправлено!
Как перенастроить на диапазон 16g? Заранее спасибо