Raspberry Pi. Настройка и использование шины I2C.

Продолжаем осваивать различные модули Raspberry Pi, так вот сегодня пришла очередь разобрать работу с шиной I2C! Не будем ходить вокруг да около, а сразу же перейдем к делу. И начнем с постановки задачи, которую будем решать в этой статье.

Итак, возьмем какое-нибудь устройство, работающее по I2C и подключим его к Raspberry Pi. У меня под рукой обнаружилась такая плата с 9-осевым датчиком MPU-9250:

MPU-9250

Вполне подойдет для наших экспериментов. Естественно, выбор именно этого устройства не накладывает никаких ограничений на работу с шиной. То есть все, что мы сегодня разберем на примере MPU-9250 актуально и для любых других устройств, подключенных по I2C.

Схема подключения выглядит следующим образом:

Подключение к Raspberry Pi по I2C

При работе с I2C обязательно нужны подтягивающие резисторы, которые подтягивают линии SDA и SCL к напряжению питания:

Подтягивающие резисторы

В моем случае эти резисторы уже распаяны на плате с MPU-9250, так что дополнительных действий не требуется. На этом с подключением заканчиваем и переходим к программной части статьи.

Включение I2C на Raspberry Pi.

Первым делом нам следует включить интерфейс I2C. Для этого воспользуемся утилитой для конфигурации Raspberry Pi – raspi-config. Вводим в терминале команду:

sudo raspi-config

Далее переходим в пункт Interfacing options и включаем I2C:

Настройка Raspberry Pi
Включение I2C для Raspberry Pi

После этого необходимо перезапустить плату:

sudo reboot

Альтернативным способом включения I2C является редактирование файла /boot/config.txt. В файле находим и раскомментируем строку:

dtparam=i2c_arm=on 

После чего аналогичным образом перезапускаем плату. При следующем включении модуль I2C будет активирован. Оба этих способа можно использовать, подключившись к плате по SSH.

Работа с I2C через консоль.

Для I2C, как и для других модулей платы, существуют разные варианты и методы использования. И начнем мы с применения команд непосредственно в консоли, в чем нам поможет пакет i2c-tools. Устанавливаем командой:

sudo apt-get install -y i2c-tools

После успешной установки мы можем использовать команду i2cdetect для просмотра доступных шин I2C:

i2cdetect -l

Результат выполнения в моем случае выглядит так:

Команда i2cdetect

Из вывода команды следует, что у нас активирована шина i2c-1, которую мы и будем использовать. Для новых версий плат Raspberry Pi всегда по умолчанию используется именно i2c-1. Для более старых же модификаций, например Raspberry Pi Model B с оперативной памятью 256 МБ, будет использована шина i2c-0.

Двигаемся дальше, следующая команда, которую мы рассмотрим:

sudo i2cdetect -y 1

Цифра 1 здесь как раз и относится к тому, что мы будем работать с шиной i2c-1. Кроме того, используем ключ -y. По умолчанию команда i2cdetect ожидает подтверждения от пользователя прежде, чем вмешиваться в работу шины, а ключом -y мы даем ей добро на работу с I2C без дополнительного разрешения.

Итак, вывод этой команды может быть таким:

Команда i2cdetect для Raspberry Pi

Здесь мы видим все подключенные к I2C устройства и их адреса. Поскольку я подключил датчик MPU-9250, адрес которого – 0x68, то его мы тут и обнаружили:

Пример использования i2cdetect

Кроме того, пакет i2c-tools включает в себя ряд других команд для работы с шиной, в частности:

  • i2cdump – позволяет прочитать значения всех регистров подключенного к шине устройства. Например:
i2cdump -y 1 0x68
Команда i2cdump

Здесь мы снова указываем номер шины (1), а также адрес устройства, регистры которого хотим проанализировать (0x68). Здесь выделено одно значение, а именно 0x71, соответствующее регистру с адресом 0x75. Из документации на датчик мы можем определить, что именно такое значение и должно быть у этого регистра.

  • i2cget – чтение значения конкретного регистра определенного устройства. Конечно, же рассмотрим пример:
i2cget -y 1 0x68 0x75

Считываем значение все того же регистра с адресом 0x75 и проверяем, верное ли значение выдает команда:

Команда i2cget
  • i2cset – запись определенного значения в регистр устройства. И снова не обходимся без примера:
i2cset -y 1 0x68 0x1A 0x03

Здесь мы последовательно указываем – номер шины, адрес устройства, адрес регистра и значение, которое будет записано в этот регистр. В данном случае записываем в регистр с адресом 0x1A значение 0x03.

На этом завершаем работу с I2C через консоль, мы рассмотрели все основные и необходимые операции и переходим к работе с I2C при помощи Python.

Работа с I2C на Python.

Для работы с шиной I2C необходимо установить пакет python-smbus:

sudo apt-get install -y python-smbus

По традиционной схеме создаем файл, в котором и будем писать код для работы с I2C, назовем файл, к примеру, i2c_test.py. Ну и для наглядной демонстрации прочитаем значение все того же регистра с адресом 0x75 и сравним результаты. Собственно, пишем минимально необходимый для этого код:

from smbus import SMBus

bus = SMBus(1)
data = bus.read_byte_data(0x68, 0x75)
print(hex(data))
bus.close()

Давайте разберем, что тут происходит, поэтапно. Делаем import библиотеки:

from smbus import SMBus

Открываем использующуюся у нас шину i2c-1:

bus = SMBus(1)

И, наконец, читаем значение регистра, выводим его на экран и заканчиваем работу с I2C:

data  = bus.read_byte_data(0x68, 0x75)
print(hex(data))
bus.close()

Первый аргумент функции – адрес устройства, второй – адрес регистра. Запускаем выполнение нашего кода:

python i2c_test.py

И в результате видим верное значение регистра:

Работа с I2C на Python

А это говорит нам о том, что код сработал абсолютно верно. Напоследок, рассмотрим некоторые другие функции библиотеки smbus, которые можно использовать по своему усмотрению:

Функция Описание
long read_byte(int addr) Чтение байта данных
long write_byte(int addr, char val) Запись байта данных
long read_byte_data(int addr, char cmd) Чтение значения регистра
long write_byte_data(int addr, char cmd, char val) Запись значения в регистр
long[] read_block_data(int addr, char cmd) Чтение блока данных (до 32-х байт) из регистра
write_block_data(int addr, char cmd, long vals[]) Запись блока данных в регистр
long read_word_data(int addr, char cmd) Чтение слова (2-х байт) из регистра
long write_word_data(int addr, char cmd, int val) Запись слова (2-х байт) в регистр

На этом заканчиваем обзор работы с шиной I2C для Raspberry Pi, на очереди – интерфейс SPI, который будем запускать в следующей статье.

Поделиться!

Подписаться
Уведомление о
guest
0 комментариев
Inline Feedbacks
View all comments

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Ноябрь 2020
Пн Вт Ср Чт Пт Сб Вс
 1
2345678
9101112131415
16171819202122
23242526272829
30  

© 2013-2020 MicroTechnics.ru