Raspberry Pi. Работаем с I2C на Python
Наконец-то появилось немного свободного времени и я решил более тщательно поковырять порты GPIO у Raspberry Pi. Если хочется просто подрыгать ногами, помигать светодиодами или пообмениваться данными через уарт, то это достаточно просто и в сети полно мануалов, хотя если кому надо, пишите, проведу небольшой ликбез. Я же решил сразу поиграться с шиной I2C и подключить к Raspberry Pi микромеханический трехосный акселерометр MMA7455 (в свое время купил на ебее уже распаянный на платке с выведенными нужными ногами на штыри, цена вопроса 7-10 баксов).
Итак, сначала подключим акс к плате:
В качестве рабочего дистрибутива ОС я использую Raspbian, поскольку его рекомендуют сами разработчики платы и в нем есть все необходимые драйвера, правда сразу все не заработает. Для начала необходимо убрать модуль I2C из блэклиста и добавить его в автозагрузку. Для этого делаем в консоли следующее, открываем файл raspi-blacklist.conf и видим в нем следующее:
Закоментируем две строчки и сохраним файл:
ПРИМЕЧАНИЕ: Все действия я провожу через SSH, поэтому не использую графические утилиты, в редакторе nano для сохранения файла необходимо нажать Ctrl-O, для выхода — Ctrl-Х.
Далее добавляем модуль I2C в автозагрузку, открываем файл /etc/modules
и добавляем в конец строку i2c-dev, должно получиться так:
После перезагрузки проверяем появилось ли нужное устройство в системе:
Если в ответ на эту команду мы получили:
значит все прошло успешно.
Теперь необходимо поставить некоторые дополнительные пакеты:
Теперь, при подключенном акселерометре, выполним команду:
и увидим табличку в которой отобразится адрес подключенного устройства, в случае MMA7455 — 1D, что соответствует даташиту.
Теперь надо написать простенькую программу на Python, которая будет выводить в консоль показания по трем осям акселерометра. При работе в графической оболочке можно еще установить и подключить различные модули, например pygame и визуализировать показания. Выполняем:
и вставляем нижеприведенный листинг
Результат работы (запускать sudo python mma7455.py)
На этом пока все, если что не понятно — спрашивайте.
Python Programming Tutorial: Getting Started with the Raspberry Pi
Experiment 4: I2C Temperature Sensor
In addition to analog sensors and SPI chips, you’ll often find sensors (and other devices) that rely on the Inter-Integrated Chip (IIC or I 2 C) protocol. This is a 2-wire bus that contains a clock and data channel. The master (Raspberry Pi) and device (sensor) can communicate on the same data wire.
To see this protocol in action, we’ll write a program to talk to a TMP102 Temperature Sensor. We’ll use the smbus Python module to handle the low-level communication for us. Note that «SMBus» stands for «System Management Bus» and is another protocol layer built on top of the I 2 C protocol. By using smbus, we lose out on a few I 2 C abilities (e.g. clock stretching), but we can still talk to many I 2 C sensors.
Recommended Reading
- I2C — A detailed look at how the I 2 C protocol works
Hardware Connections
Note: As an alternative, you could also use the the Qwiic cables and the Qwiic TMP102 to easily connect without needing to solder or connect to the four pins.
SparkFun Digital Temperature Sensor — TMP102 (Qwiic)
The SparkFun TMP102 Qwiic is an easy-to-use digital temperature sensor equipped with a couple of Qwiic connectors for easy I2…
SparkFun Qwiic SHIM for Raspberry Pi
The SparkFun Qwiic SHIM for Raspberry Pi is a small, easily removable breakout that easily adds a Qwiic connector to your Ras…
Qwiic Cable — 200mm
This is a 200mm long 4-conductor cable with 1mm JST termination. It’s designed to connect Qwiic enabled components together…
Qwiic Cable — Breadboard Jumper (4-pin)
This is a jumper adapter cable that comes pre-terminated with a female Qwiic JST connector on one end and a breadboard hookup…
Refer back to Experiment 1 to look at the Pinout chart.
- Connect SDA1 (GPIO2, pin 3) to SDA on the TMP102
- Connect SCL1 (GPIO3, pin 5) to SCL on the TMP102
- Connect power (3.3 V) to VCC on the TMP102
- Connect ground (GND) to GND on the TMP102
Connecting through a Pi Wedge:
Connecting directly to the Raspberry Pi:
Code: Read and Calculate Temperature
Depending on your version of Raspbian, you may or may not have to install the smbus package (e.g. Raspbian Lite does not come with some Python packages pre-installed). In a terminal, enter the following:
In a new file, copy in the following code:
Save the file (e.g. tmp102.py), and run it with Python:
You should see the 2 bytes in the CONFIG register be updated and then the temperature is printed to the screen every second.
Code to Note:
Unlike SPI, I 2 C relies on a set of addresses and registers. This is because SPI is configured to talk to one chip at a time while I 2 C can share many devices on one bus. To avoid conflicts, addresses are assigned to devices (by the manufacturer) so that each one knows when the host (the Pi) is trying to talk to it. The address for our TMP102 is 0x48 .
Each time we want to talk to the TMP102, we must send out its address (0x48) on the bus. Only then can we send the memory location (or address) of the register that we want to read from or write to on the TMP102. Note that for most I 2 C devices, a register is a location in the device’s memory that stores 8 bits (1 byte) of data. Sometimes, this data controls the function of the device (as in the case of the CONFIG register). Other times, the registers hold the sensor reading data (as in the case of the temperature register).
We use the following command to read 2 bytes from the temperature register in the TMP102:
These values are stored as a list [x, y] in the val variable. By looking at the TMP102 datasheet, we see that temperature is 12 bits. When we read the two bytes that contain this reading, we need to remove the last 4 bits from the second byte. We also move the first byte over 4 bits:
In order to display negative numbers for the temperature, values from the TMP102 can come in the form of Two’s Complement. In this, the first bit of the 12-bit number determines if the value is positive or negative (0 for positive, 1 for negative). See this article to learn more about Two’s Complement.
To convert a Two’s Complement number to a negative number in Python, we check to see if the first bit is 0 or 1. If it is 0, then we just use the number as is (it’s positive!). If it’s a 1, we subtract the max negative number of the Two’s Complement (2 12 =4096 in this case) from our number.
Challenge: Change the CONFIG register so that the TMP102 updates its temperature reading 8 times per second (instead of 8). Additionally, print out the temperature in degrees Fahrenheit. Hint: see page 7 of the TMP102 datasheet to see which bits need to be changed in the CONFIG register.
SMBus: Работа с шиной I2C на Python в Raspberry Pi/Orange Pi/Banana Pi
SMBus (англ. System Management Bus) — последовательный протокол обмена данными для устройств питания. Основан на шине I²C, но использует более низкое сигнальное напряжение (3,3 В), предложен Intel в 1995 году. Используется, например, для получения информации о состоянии аккумуляторной батареи ноутбука (оставшаяся ёмкость аккумуляторной батареи, температура, количество использованных циклов разряда, и т. д.). С версии SMBus 2.0 (2000 год) используется не только для настройки батареи, но и для иных внутренних устройств компьютера.
SMBus является двухпроводным интерфейсом, по которому простые устройства могут обмениваться информацией с остальной системой. Сообщения идут к устройствам и от них, вместо прохождения по отдельным управляющим линиям.
python-smbus — этот модуль Python обеспечивает доступ к SMBus через интерфейс I2C /dev на хостах Linux. Ядро хоста должно иметь поддержку I2C, поддержку интерфейса устройства I2C и драйвер адаптера шины.
Установка и обновление Python
Python 2 и Python 3 поставляются предварительно установленными в операционных системах Raspbian, но чтобы установить Python в другой ОС Linux или обновить его, просто выполните одну из следующих команд в командной строке:
Установка или обновление Python 3.
Установка или обновление Python 2.
Открытие Python REPL
Чтобы получить доступ к Python REPL (где вы можете вводить команды Python точно так же, как в командной строке), введите python или python3 в зависимости от того, какую версию вы хотите использовать:
Введите Ctrl-D, чтобы выйти из REPL.
Установка I 2 C Tools
I2C Tools — это пакет с полезными консольными инструментами для I2C. После установки нам будут доступны несколько полезных утилит: i2cdetect , i2cdump , i2cget , i2cset .
i2cdetect — это пользовательская программа, которая сканирует шину I2C на наличие устройств.
Отображать список доступных в системе шин I²C:
Отображать таблицу обнаруженных устройств на указанной шине:
Установка SMBus
Описание методов (функций)
SMBus функции
write_quick()
Параметры
int addr — I2C адрес устройства.
Возвращает
long — Отрицательный errno или ноль в случае успеха.
read_byte()
Параметры
int addr — I2C адрес устройства.
Возвращает
long — Отрицательный errno или байт данных в случае успеха.
write_byte()
Параметры
int addr — I2C адрес устройства.
char val — Байт данных.
Возвращает
long — Отрицательный errno или ноль в случае успеха.
read_byte_data()
Чтение байта данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
Возвращает
long — Отрицательный errno или байт данных в случае успеха.
write_byte_data()
Запись байта данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
char val — Байт данных.
Возвращает
long — Отрицательный errno или ноль в случае успеха.
read_word_data()
Чтение двух байт данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
Возвращает
long — Отрицательный errno или два байта данных в случае успеха.
process_call()
Process Call (вызов процесса) .
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
int val — Два байта данных.
Возвращает
long — Отрицательное значение errno или 16-разрядное беззнаковое «слово», полученное от устройства.
read_block_data()
Чтение массива данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
Возвращает
long[] — Отрицательный errno или массив данных в случае успеха.
write_block_data()
Запись массива данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
long[] vals — Массив данных.
block_process_call()
Block Process Call.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
long[] vals — Массив данных.
Возвращает
long[] — Массив данных.
I2C функции
read_i2c_block_data()
Чтение массива данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
int length — Желаемая длина блока.
Возвращает
long[] — Массив данных в случае успеха.
write_i2c_block_data()
Запись массива данных.
Параметры
int addr — I2C адрес устройства.
char cmd — Адрес регистра (команда).
long[] vals — Массив данных.
Примеры программ
Пример 1: чтение байта
Открыть шину I2C «0» и прочитать один байт от адреса 0x39, со смещением 0x0C (адрес регистра).
Пример 2: чтение массива данных
Открыть шину I2C «0» и прочитать 4 байта от адреса 0x39, со смещением 0x0C (адрес регистра). Вы можете прочитать до 32 байтов за раз.
Пример 3: запись байта
Открыть шину I2C «0» и записать один байт по адресу 0x39, со смещением 0x0C (адрес регистра).
Пример 4: запись массива
Открыть шину I2C «0» и записать масив байтов по адресу 0x39, со смещением 0x0C (адрес регистра). Вы можете записать до 32 байтов за раз.