9 степеней свободы подключение MPU-9265 к Raspberry Pi

9 степеней свободы: подключение MPU-9265 к Raspberry Pi

Руководство по подключению и использованию датчика MPU-9265 с 9 степенями свободы (DOF): гироскоп, акселерометр и компас.

MPU-9250 — это инерциальный измерительный блок, включающий в себя 3-осевой гироскоп, 3-осевой акселерометр и 3-осевой компас, обеспечивая 9-осевое отслеживание движения. Он используется в робототехнике, дронах, мобильных устройствах и игровых контроллерах для ориентации и стабилизации. Устройство поддерживает интерфейсы I2C и SPI, питается от 3.3В.

Включение интерфейса I2C

Bash
sudo raspi-config

Перейдем в раздел Intefrace options

Раздел Intefrace options

Затем в I2C

Включим I2C

Включение I2C

Перезагрузимся

Bash
sudo reboot

Подключение MPU-9265 к Raspberry Pi

Схема подключения MPU-9265 к Raspberry Pi
Схема подключения MPU-9265 к Raspberry Pi

Подключим

  • VCC MPU-9265 к 3.3V на Raspberry Pi.
  • GND MPU-9265 к GND на Raspberry Pi.
  • SDA MPU-9265 к GPIO2 (SDA) на Raspberry Pi.
  • SCL MPU-9265 к GPIO3 (SCL) на Raspberry Pi.

Проверка подключения устройства

После включения I2C и подключения датчика, можно проверить, распознается ли оно системой.

Python
sudo i2cdetect -y 1
результат работы sudo i2cdetect -y 1

Вы увидите таблицу с адресами устройств. Устройство подключено по адресу 68 (0x68).

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

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

Python
pip install smbus2

Импорт библиотек и определение адресов

Python
import smbus2 as smbus
import time

# Адреса устройств
MPU_ADDRESS = 0x68
MAG_ADDRESS = 0x0C

# Регистры MPU
PWR_MGMT_1 = 0x6B
ACCEL_XOUT_H = 0x3B
GYRO_XOUT_H = 0x43

# Регистры компаса AK8963
MAG_CNTL1 = 0x0A
MAG_ST1 = 0x02
MAG_XOUT_L = 0x03
MAG_ST2 = 0x09
  • smbus2: Библиотека для работы с шиной I2C.
  • time: Для управления задержками в программе.
  • Адреса устройств:
    • MPU_ADDRESS — I2C-адрес MPU-9265.
    • MAG_ADDRESS — I2C-адрес компаса AK8963
    • Регистры для управления и чтения данных с сенсоров.

Функция чтения 16-битных данных с поддержкой знаковых чисел

Python
def read_word_2c(addr, device_address=MPU_ADDRESS):
    try:
        high = bus.read_byte_data(device_address, addr)
        low = bus.read_byte_data(device_address, addr + 1)
        val = (high << 8) + low
        if val >= 0x8000:
            return -((65535 - val) + 1)
        else:
            return val
    except Exception as e:
        print(f"Ошибка при чтении данных с адреса {device_address:#x}, регистр {addr:#x}: {e}")
        return 0

Эта функция читает два байта данных начиная с указанного регистра и преобразует их в 16-битное знаковое число. Если произошла ошибка чтения, выводится сообщение об ошибке и возвращается 0.

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

Python
def get_accel_data():
    x = read_word_2c(ACCEL_XOUT_H)
    y = read_word_2c(ACCEL_XOUT_H + 2)
    z = read_word_2c(ACCEL_XOUT_H + 4)
    return {'x': x, 'y': y, 'z': z}

Функция читает данные акселерометра по осям X, Y и Z, начиная с регистра ACCEL_XOUT_H, и возвращает их в виде словаря.

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

Python
def get_gyro_data():
    x = read_word_2c(GYRO_XOUT_H)
    y = read_word_2c(GYRO_XOUT_H + 2)
    z = read_word_2c(GYRO_XOUT_H + 4)
    return {'x': x, 'y': y, 'z': z}

Аналогично акселерометру, эта функция получает данные гироскопа по осям X, Y и Z.

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

Python
def get_mag_data():
    try:
        # Проверяем, готовы ли данные
        st1 = bus.read_byte_data(MAG_ADDRESS, MAG_ST1)
        if st1 & 0x01:
            mag_bytes = bus.read_i2c_block_data(MAG_ADDRESS, MAG_XOUT_L, 7)
            x = (mag_bytes[1] << 8) | mag_bytes[0]
            y = (mag_bytes[3] << 8) | mag_bytes[2]
            z = (mag_bytes[5] << 8) | mag_bytes[4]
            if x >= 0x8000:
                x = -((65535 - x) + 1)
            if y >= 0x8000:
                y = -((65535 - y) + 1)
            if z >= 0x8000:
                z = -((65535 - z) + 1)
            st2 = mag_bytes[6]
            if not (st2 & 0x08):
                return {'x': x, 'y': y, 'z': z}
        return {'x': None, 'y': None, 'z': None}
    except Exception as e:
        print(f"Ошибка при чтении компаса: {e}")
        return {'x': None, 'y': None, 'z': None}

Эта функция проверяет готовность данных компаса к чтению. Если данные готовы (st1 & 0x01), она считывает блок данных, объединяет байты для получения значений по осям X, Y и Z, учитывая знаковость чисел. Затем проверяется статус st2 для подтверждения корректности данных. Если все прошло успешно, функция возвращает словарь с измеренными значениями магнитного поля по осям; в противном случае возвращаются значения None для каждой оси.

Инициализация компаса

Python
def init_mag():
    try:
        # Сброс компаса
        bus.write_byte_data(MAG_ADDRESS, MAG_CNTL1, 0x01)
        time.sleep(0.1)  # Ждем завершения сброса

        # Установка в режим непрерывных измерений 100Hz
        bus.write_byte_data(MAG_ADDRESS, MAG_CNTL1, 0x16)
        time.sleep(0.1)  # Ждем завершения настройки
    except Exception as e:
        print(f"Ошибка при инициализации компаса: {e}")

Функция сначала сбрасывает настройки компаса, а затем устанавливает его в режим непрерывных измерений с частотой 100 Гц.

Основная функция программы

Python
def main():
    try:
        # Пробуждаем MPU-9265
        bus.write_byte_data(MPU_ADDRESS, PWR_MGMT_1, 0)

        # Инициализация компаса
        init_mag()

        while True:
            accel_data = get_accel_data()
            gyro_data = get_gyro_data()
            mag_data = get_mag_data()

            print(f"Accelerometer: {accel_data}")
            print(f"Gyroscope: {gyro_data}")
            if mag_data['x'] is not None:
                print(f"Compass: {mag_data}")
            else:
                print("Compass: Данные не готовы или ошибка чтения")

            time.sleep(1)
    except KeyboardInterrupt:
        print("Завершение программы")
    finally:
        bus.close()
  1. Пробуждение MPU-9265: Отправляется команда пробуждения сенсора путем записи 0 в регистр PWR_MGMT_1.
  2. Инициализация компаса: Вызывается функция init_mag().
  3. Бесконечный цикл: В цикле программа считывает данные акселерометра, гироскопа и компаса каждую секунду и выводит их на экран.
  4. Обработка прерывания: При нажатии Ctrl+C программа корректно завершает работу.
  5. Закрытие шины I2C: В блоке finally шина I2C закрывается, освобождая ресурсы.

Результат работы программы

Результат работы скрипта mpu9265.py
Результат работы скрипта mpu9265.py

Полный код

Полный код доступен в репозитории на Гитхабе.