Общие сведения
BMI160 — датчик движения от Bosch: трёхосевой акселерометр и трёхосевой гироскоп в одной микросхеме (6DOF). Акселерометр показывает, как плата наклонена и с каким ускорением её трясут, гироскоп — как быстро она поворачивается. Из этих данных собирают балансирующих роботов, стабилизаторы, шагомеры и пульты, которые управляют наклоном руки.
Плата фиолетовая, все 12 выводов подписаны с обратной стороны. Стабилизатор на 3,3 В уже стоит на плате, поэтому её питают от 5 В Arduino через вывод VIN. Две гребёнки в комплекте, их нужно припаять.
Характеристики
- Микросхема: Bosch BMI160;
- Акселерометр: ±2, ±4, ±8 или ±16 g, 16 бит;
- Гироскоп: ±125, ±250, ±500, ±1000 или ±2000 °/с, 16 бит;
- Интерфейс: I2C (адрес 0x68 или 0x69) или SPI;
- Питание платы: 5 В на VIN или 3,3 В на 3V3.
Цифры взяты из даташита Bosch на BMI160.
Выводы
- VIN, 3V3, GND — питание: 5 В на VIN или 3,3 В на 3V3, одно из двух;
- SCL и SDA — шина I2C (в режиме SPI — тактовый сигнал и данные);
- SAO — выбирает адрес на шине I2C: 0x68 или 0x69;
- CS — выбор микросхемы для SPI, при работе по I2C его не подключают;
- INT1 и INT2 — выходы прерываний, например «готовы новые данные» или «обнаружен удар»;
- OCS, SCX, SDX — дополнительный интерфейс для внешнего магнитометра, для обычной работы не нужны.
Подключение к Arduino по I2C
| BMI160 | Arduino Uno |
|---|---|
| VIN | 5V |
| GND | GND |
| SCL | A5 |
| SDA | A4 |
Скетч обходится без сторонних библиотек. Он сам ищет датчик по адресам 0x68 и 0x69, включает акселерометр и гироскоп и пять раз в секунду выводит ускорение в g и скорость поворота в градусах в секунду. Регистры и коэффициенты взяты из даташита: после включения акселерометр стоит на диапазоне ±2 g (16384 единицы на 1 g), гироскоп — на ±2000 °/с (16,4 единицы на 1 °/с).
#include <Wire.h>
uint8_t addr = 0; // адрес найдём сами: 0x68 или 0x69
uint8_t readReg(uint8_t reg) {
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(addr, (uint8_t)1);
return Wire.read();
}
void writeReg(uint8_t reg, uint8_t val) {
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.write(val);
Wire.endTransmission();
}
void setup() {
Serial.begin(9600);
Wire.begin();
for (uint8_t a = 0x68; a <= 0x69 && addr == 0; a++) {
addr = a;
if (readReg(0x00) != 0xD1) addr = 0; // в регистре 0x00 у BMI160 всегда 0xD1
}
if (addr == 0) { Serial.println("BMI160 не найден"); while (true); }
Serial.print("BMI160 найден, адрес 0x");
Serial.println(addr, HEX);
writeReg(0x7E, 0x11); delay(10); // акселерометр — в рабочий режим
writeReg(0x7E, 0x15); delay(100); // гироскоп — в рабочий режим, ему нужно до 55 мс
}
void loop() {
Wire.beginTransmission(addr);
Wire.write(0x0C); // с 0x0C идут гироскоп X, Y, Z, затем акселерометр X, Y, Z
Wire.endTransmission(false);
Wire.requestFrom(addr, (uint8_t)12);
int16_t v[6];
for (int i = 0; i < 6; i++) {
uint8_t lo = Wire.read();
uint8_t hi = Wire.read();
v[i] = (int16_t)((hi << 8) | lo);
}
Serial.print("g: ");
for (int i = 3; i < 6; i++) { Serial.print(v[i] / 16384.0, 2); Serial.print(' '); }
Serial.print(" град/с: ");
for (int i = 0; i < 3; i++) { Serial.print(v[i] / 16.4, 1); Serial.print(' '); }
Serial.println();
delay(200);
}Положите плату ровно и откройте монитор порта на скорости 9600: по оси Z акселерометр покажет около 1 g (это сила тяжести), по X и Y — около нуля.
Если что-то не так
- «BMI160 не найден» — проверьте, не перепутаны ли SDA и SCL и припаяны ли гребёнки. Без пайки контакт в отверстиях то есть, то нет.
- Гироскоп в покое показывает не ноль — это смещение нуля. Перед работой посчитайте среднее за пару секунд неподвижности и вычитайте его.
- Угол, посчитанный только по гироскопу, со временем уплывает, а только по акселерометру — дрожит. Для устойчивого угла их объединяют фильтром, например комплементарным или Madgwick.
Комплектация
- 1× плата BMI160;
- 2× гребёнка (на 7 и 5 выводов).

















