При создании некоторых проектов, требуется разделить выполняемые задачи между несколькими arduino.
В этом уроке мы научимся соединять две arduino по аппаратной шине I2C.
- Преимущества:
- Недостатки:
- Нам понадобится:
- Видео:
- Схема подключения:
- Код программы:
- Алгоритм работы:
- Настройка параметров шины I2C:
- Функции библиотеки iarduino_I2C_connect:
- Интерфейс I2C и Arduino
- Инструкция по использованию протокола I 2 C совместно с Arduino
- Нам понадобится:
- 1 Описание интерфейса I2C
- 2 Реализация I2Cв Arduino
- 3 Библиотека «Wire» для работы с IIC
- 4 Подключение I2C устройствак Arduino
- 5 Управление устройством по шине IIC
- 6 Дополнительно о шине I2C
- I²C — Inter-Integrated Circuit, краткое руководсто
- Общие сведения:
- Подключение:
- I²C на Arduino
- I²C на Raspberry Pi
- Подробнее о шине I²C:
- Резисторы, ёмкость и длина линий шины
- Сигналы и специальные биты шины
- Обмен данными
- Скорость
- 🌟 Видео
Преимущества:
- Реализуется возможность подключения до 126 устройств.
(не рекомендуется присваивать устройствам адреса 0x00 и 0x7F) - Не требуются дополнительные модули.
- Все устройства одинаково подключаются к шине.
- Каждое ведомое устройство имеет свой уникальный адрес на шине.
Недостатки:
Нам понадобится:
Для реализации проекта нам необходимо установить библиотеки:
- Библиотека LiquidCrystal_I2C_V112 (для подключения дисплеев LCD1602 по шине I2C).
- Библиотека iarduino_I2C_connect (для удобства соединения нескольких arduino по шине I2C).
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki — Установка библиотек в Arduino IDE, а о том, как работать с LCD дисплеями, на странице Wiki — Работа с символьными ЖК дисплеями.
Видео:
Схема подключения:
На шине i2С находятся 4 устройства: 3 arduino и 1 LCD дисплей. Все устройства шины I2C соединены через Trema I2C Hub. Для подключения Arduino используются аппаратные выводы шины I2C.
- Arduino master — к цифровому выводу D2 подключена trema кнопка.
- Arduino slave 0x01 — к цифровому выводу D2 подключена trema кнопка.
- Arduino slave 0x02 — к цифровому выводу D13 подключён trema светодиод, к аналоговому выводу A0 подключён Trema потенциометр.
- LCD I2C дисплей — является устройством slave 0x27.
На шине I2C не используются дополнительные подтягивающие резисторы (для линий SDA и SCL), так как они интегрированы в LDC I2C дисплее.
Код программы:
Arduino master:
Arduino slave 0x01:
Arduino slave 0x02:
Алгоритм работы:
- Arduino master проверяет состояние собственной кнопки.
- Arduino master опрашивает две Arduino Slave.
- Arduino Slave 0x01 возвращает состояние кнопки.
- Arduino Slave 0x02 возвращает значение падения напряжения плеча потенциометра.
- Arduino Slave 0x02 включает или выключает светодиод, в соответствии с полученными данными.
Настройка параметров шины I2C:
Максимальная, аппаратно реализуемая частота передачи данных, может достигать 1/16 от тактовой частоты.
Библиотека Wire позволяет устанавливать скорость передачи данных через функцию setClock(), которую требуется вызвать до функции begin().
Библиотека Wire позволяет аппаратно подключить Arduino к шине I2C с указанием роли Arduino на шине: ведущий или ведомый.
- Wire.setClock(400000); // скорость передачи данных 400 кБит/с.
- Wire.begin(); // подключение к шине I2C в роли ведущего.
- Wire.begin(адрес); // подключение к шине I2C в роли ведомого, с указанием адреса.
Функции библиотеки iarduino_I2C_connect:
В библиотеке iarduino_I2C_connect реализованы 4 функции: 2 для ведущего и 2 для ведомого.
На ведомом устройстве достаточно вызвать функцию begin() с указанием массива, данные которого требуется сделать доступными для мастера. Далее можно работать с этим массивом, «забыв» про шину I2C. Мастер обращаясь к ведомому сможет получать и изменять данные элементов указанного массива (обращаясь к номеру элемента массива как к номеру регистра).
Если требуется запретить мастеру менять значения некоторых ячеек массива, то достаточно вызвать «необязательную» функцию writeMask() с указанием маскировочного массива, каждый элемент которого является флагом, разрешающим запись в соответствующий элемент массива доступного по шине I2C.
На ведущем устройстве доступны функции readByte() и writeByte(). Указывая в качестве параметров функций, адрес ведомого устройства и номер регистра, можно побайтно читать и записывать данные.
Функции для ведомого:
- Назначение: указание массива, элементы которого будут доступны для чтения/записи по шине I2C.
- Синтаксис: begin(массив); // тип данных массива — byte.
- Возвращаемые значения: Нет.
- Примечание: Вызывается 1 раз в коде функции Setup().
- Назначение: указание маскировочного массива, каждый элемент которого является флагом разрешения записи по шине I2C.
- Синтаксис: writeMask(маскировочный_массив); // тип данных массива — bool.
- Возвращаемые значения: Нет.
- Примечание: Вызывается 1 раз в коде функции Setup().
- Пример:
#include
#include
iarduino_I2C_connect ccc;
byte aaa[5]; // объявляем 5 элементов массива, к которому разрешим доступ.
bool bbb[5] = ; // объявляем 5 элементов маскировочного массива.
Wire.begin(0x33); // подключаемся к шине I2C в роли ведомого с адресом 0x33.
ccc.begin(aaa); // разрешаем доступ к массиву aaa по шине I2C.
ccc.wtiteMask(bbb); // маскируем разрешение на запись в массив aaa.- В соответствии со значениями массива bbb, мастер сможет записывать данные в ячейки 1,2,3 массива aaa, а попытка записи в 0 и 4 элементы будет проигнорирована.
- Если массив aaa имеет больше элементов чем массив bbb, то попытка мастера записать данные в «лишние» элементы будет проигнорирована.
- Если не объявлять маскировочный массив (не вызывать функцию writeMask() вообще), то все элементы массива aaa будут доступны для записи мастером.
Функции для ведущего:
- Назначение: Чтение одного байта данных из устройства на шине I2C.
- Синтаксис: readByte(адрес_устройства, адрес_регистра);
- Возвращаемые значения: uint8_t байт — данные считанные из указанного адреса, указанного устройства.
- Примечание: Если производится чтение по шине I2C из массива объявленного функцией begin(), то адрес регистра соответствует номеру элемента массива.
Видео:Подключение нескольких устройств по шине i2cСкачать
Интерфейс I2C и Arduino
Видео:Подключение нескольких устройств, датчиков по I2C (АйТуСи) шинеСкачать
Инструкция по использованию протокола I 2 C совместно с Arduino
Нам понадобится:
- Arduino UNO или другая совместимая;
- цифровой потенциометр AD5171 или другой с управлением по шине IIC;
- светодиод любой (к примеру, вот из такого набора);
- резистор на 220 Ом (рекомендую набор резисторов с номиналами от 10 Ом до 1 МОм);
- 2 резистора по 4,7 кОм (из того же набора);
- макетная плата;
- соединительные провода (например, вот хороший набор);
- компьютер с Arduino IDE.
Видео:Введение в шину I2CСкачать
1 Описание интерфейса I2C
Последовательный протокол обмена данными IIC (также называемый I2C – Inter-Integrated Circuits, межмикросхемное соединение) использует для передачи данных две двунаправленные линии связи, которые называются шина последовательных данных SDA (Serial Data) и шина тактирования SCL (Serial Clock). Также имеются две линии для питания. Шины SDA и SCL подтягиваются к шине питания через резисторы.
В сети есть хотя бы одно ведущее устройство (Master), которое инициализирует передачу данных и генерирует сигналы синхронизации. В сети также есть ведомые устройства (Slave), которые передают данные по запросу ведущего. У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Адрес устройства указывается в паспорте (datasheet). К одной шине I2C может быть подключено до 127 устройств, в том числе несколько ведущих. К шине можно подключать устройства в процессе работы, т.е. она поддерживает «горячее подключение».
Давайте рассмотрим временную диаграмму обмена по протоколу I2C. Есть несколько различающихся вариантов, рассмотрим один из распространённых. Воспользуемся логическим анализатором, подключённым к шинам SCL и SDA.
Мастер инициирует обмен. Для этого он начинает генерировать тактовые импульсы и посылает их по линии SCL пачкой из 9-ти штук. Одновременно на линии данных SDA он выставляет адрес устройства, с которым необходимо установить связь, которые тактируются первыми 7-ми тактовыми импульсами (отсюда ограничение на диапазон адресов: 2 7 = 128 минус нулевой адрес). Следующий бит посылки – это код операции (чтение или запись) и ещё один бит – бит подтверждения (ACK), что ведомое устройство приняло запрос. Если бит подтверждения не пришёл, на этом обмен заканчивается. Или мастер продолжает посылать повторные запросы.
Это проиллюстрировано на рисунке ниже. Задача такая: подключиться к ведомому устройству с адресом 0x27 и передать ему строку «SOLTAU.RU». В первом случае, для примера, отключим ведомое устройство от шины. Видно, что мастер пытается установить связь с устройством с адресом 0x27, но не получает подтверждения (NAK). Обмен заканчивается.
Попытка мастера установить соединение с ведомым по I2C
Теперь подключим к шине I2C ведомое устройство и повторим операцию. Ситуация изменилась. На первый пакет с адресом пришло подтверждение (ACK) от ведомого. Обмен продолжился. Информация передаётся также 9-битовыми посылками, но теперь 8 битов занимают данные и 1 бит – бит подтверждения получения ведомым каждого байта данных. Если в какой-то момент связь оборвётся и бит подтверждения не придёт, мастер прекратит передачу.
Временная диаграмма обмена по протоколу I2C
Видео:Лекция 308. Шина I2CСкачать
2 Реализация I2Cв Arduino
Arduino использует для работы по интерфейсу I2C два порта. Например, в Arduino UNO и Arduino Nano аналоговый порт A4 соответствует SDA, аналоговый порт A5 соответствует SCL.
Реализация I2C в Arduino UNO и Nano
Для других моделей плат соответствие выводов такое:
Плата Пин SDA Пин SCL Arduino Uno, Nano, Pro и Pro Mini A4 A5 Arduino Mega 20 21 Arduino Leonardo 2 3 Arduino Due 20, SDA1 21, SCL1 Видео:I2C хаб — как подключить одинаковые I²C модули к одной шине. Управляем IMU, матрицами, NFC и RTC.Скачать
3 Библиотека «Wire» для работы с IIC
Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire. Она имеет следующие функции:
Функция Назначение begin(address) инициализация библиотеки и подключение к шине I2C; если не указан адрес, то присоединённое устройство считается ведущим; используется 7-битная адресация; requestFrom() используется ведущим устройством для запроса определённого количества байтов от ведомого; beginTransmission(address) начало передачи данных к ведомому устройству по определённому адресу; endTransmission() прекращение передачи данных ведомому; write() запись данных от ведомого в ответ на запрос; available() возвращает количество байт информации, доступных для приёма от ведомого; read() чтение байта, переданного от ведомого ведущему или от ведущего ведомому; onReceive() указывает на функцию, которая должна быть вызвана, когда ведомое устройство получит передачу от ведущего; onRequest() указывает на функцию, которая должна быть вызвана, когда ведущее устройство получит передачу от ведомого. Видео:Урок 24. Узнаём адреса устройств на шине I2CСкачать
4 Подключение I2C устройствак Arduino
Давайте посмотрим, как работать с шиной I2C с помощью Arduino.
Сначала соберём схему, как на рисунке. Будем управлять яркостью светодиода, используя цифровой 64-позиционный потенциометр AD5171 (см. техническое описание), который подключается к шине I2C. Адрес, по которому мы будем обращаться к потенциометру – 0x2c (44 в десятичной системе).
Подключение цифрового потенциометра к Arduino по шине I2C
Видео:Подключение внешних барометра и магнитометра по шине I2C для Inav и BetaflightСкачать
5 Управление устройством по шине IIC
Рассмотрим диаграммы информационного обмена с цифровым потенциометром AD5171, представленные в техническом описании:
Рассмотрим диаграммы чтения и записи цифрового потенциометра AD5171
Нас тут интересует диаграмма записи данных в регистр RDAC. Этот регистр используется для управления сопротивлением потенциометра.
Откроем из примеров библиотеки «Wire» скетч: Файл Образцы Wire digital_potentiometer. Загрузим его в память Arduino.
После включения вы видите, как яркость светодиода циклически нарастает, а потом гаснет. При этом мы управляем потенциометром с помощью Arduino по шине I2C.
По ссылкам внизу статьи, в разделе похожих материалов (по тегу), можно найти дополнительные примеры взаимодействия с различными устройствами по интерфейсу IIC, в том числе примеры чтения и записи.
Видео:Что такое I2C ??? Подключаем GY-521 и Oled 96*16 к STM 32Скачать
6 Дополнительно о шине I2C
Доступно и интересно рассказывает о шине I2C Джереми Блюм в своём видео:
Видео:Шина I2C.Скачать
I²C — Inter-Integrated Circuit, краткое руководсто
Видео:Урок 9. Адреса модулей на шине I2C. Arduino (что такое I2C, адресация, как изменить адрес модуля)Скачать
Общие сведения:
I²C (и-квадрат-це, ай-ту-си, ай-сквэрд-си), Inter-Integrated Circuit — последовательная шина обмена данными между интегральными схемами. Изобретена и в начале 80-х компанией Philips Semiconductor (теперь NXP), передача данных осуществляется по двум проводам в обе стороны. Ведущий и ведомый могут выполнять как роль приёмника, так и передатчика. Для возможности соединения более двух устройств используются адресация. Опрашивать адреса шины может только ведущий. Адрес последовательно выводится на линию SDA сразу после сигнала Start. В этой статье речь пойдёт только о 7-ми битной адресации, так же не будет затронута тема нескольких ведущих. На каждом устройстве, поддерживающем I²C обычно обозначены два вывода: SDA и SCL. SDA (serial data) — означает последовательные данные, SCL (serial clock) — последовательное тактирование. Эти выводы являются выводами открытого коллектора или открытого стока, это означает что ведущий и ведомый могут только притягивать электрический потенциал к земле, поэтому на каждой линии должны быть подтягивающие резисторы. Сопротивление резисторов рассчитывается в зависимости от паразитной ёмкости линии.
Видео:Урок 26.3 Соединяем две arduino по шине I2C #iarduinoСкачать
Подключение:
Шина поддерживает подключение до 112 устройств (при 7-ми битной адресации) по двум проводам (плюс GND и Vcc), может иметь несколько ведущих и ведомых. При использовании нескольких ведущих, каждый из них должен поддерживать этот режим и уметь определять состояние занятой шины.
I²C на Arduino
Arduino UNO R3/Piranha UNO
На Arduino UNO R3/Piranha UNO шина I2C находится на выводах A4, A5. Также в эти выводы продублированы на колодке с цифровыми выводами рядом с кнопкой Reset.
Piranha ULTRA
На Piranha ULTRA шина I²C не занимает аналоговые выводы A4, A5 и находится на цифровой колодке рядом с кнопкой Reset, выводы обозначены SDA и SCL
Arduino MEGA R3
На Arduino MEGA R3 шина I²C находится на цифровой колодке на крайних выводах, близких к разъёму USB и на выводах 20, 21. Выводы объединены.
Примеры для Arduino
Работа с шиной с использованием встроенной библиотеки Wire Arduino IDE на примере Trema-модуля LED Матрицы 8×8 — i2c
В этом примере на матрицу выводится изображение стрелки. Стоит заметить, ко всем нашим модулям написаны библиотеки с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке.
I²C на Raspberry Pi
На Raspberry Pi I²C выводы это 3-й и 5-й выводы колодки, GPIO2 и GPIO3 по номенклатуре BCM и выводы 8, 9 по номенклатуре WiringPi.
Примеры для Raspberry
Работа с шиной с использованием модуля smbus для Python на примере Trema-модуля Матрицы 8×8 — i2c. Для работы с шиной её необходимо включить в настройках Raspberry при помощи утилиты raspi-config . Ссылка на подробное описание как это сделать.
Так же как и в примере с Arduino, в этом примере на матрицу выводится изображение стрелки. Стоит заметить, к Trema-модулю LED Матрица 8×8 — i2c написана библиотека с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке
Видео:Подключение дисплея 1602 lcd i2c. 1602 ардуино дисплейСкачать
Подробнее о шине I²C:
Резисторы, ёмкость и длина линий шины
В официальном описании от NXP ничего не сказано о максимальной длине шины, но не стоит этим злоупотреблять. Шина была придумана для обмена информации между интегральными схемами в пределах одной платы одного устройства. В расчёт бралась только паразитная ёмкость линии, которая сказывается на скорости нарастания фронта волны. От этой ёмкости зависит номинал подтягивающих резисторов. Можно подобрать резисторы так, чтобы фронт волны нарастал согласно спецификации и при 100-метровой длине проводов, но это не избавляет от помех, которые влечёт за собой несимметричная электрическая реализация. Опять же, при слишком маленьком сопротивлении качество сигнала улучшается, но при этом растёт ток который необходимо пропускать устройствам через выводы для притяжки линий.
При использовании шины на модулях не существует принятого стандарта установки подтягивающих резисторов на ведущем или ведомом. У Arduino подтягивающие резисторы отсутствуют и для работы с шиной нужен хотя бы один модуль с ними. У Raspberry Pi на плате установлены подтягивающие резисторы номиналом 1,7 килоОм и для неё нет необходимости в подтяжке на модулях.
Сигналы и специальные биты шины
В состоянии покоя линии шины находятся на верхнем потенциале (обычно 3,3 В или 5 В, но могут быть и другие напряжения). Бездействие устройства, по умолчанию, воспринимается как логическая 1. Для простоты понимания можно рассмотреть аналогию: Вообразим верхний потенциал как уровень воды, а нижний как дно. Представьте, что Вы на рыбалке — попловок в состоянии покоя остаётся на поверхности, когда клюёт — идёт ко дну. Так же и в здесь, при обмене данными линии прижимаются в нулевому потециалу. Далее рассмотрим поочереди сингалы и специальные биты.
Устанавливаемые только ведущим
- Start — сигнал начала обмена данными. Линия тактирования SCL отпущена (логическая 1), ведущий пижимает линию данных SDA (переход из логической 1 в логический 0). После этого обмен данными происходит побайтово. Первый байт — семь бит адреса ведомого и бит направления (запись или чтение). Последующие байты — данные. после этого сигнала шина считается занятой.
Краткое обозначание сигнала S — заглавная буква S латинского алфавита.
- Бит Read — Если ведущий желает получить данные, он устанавливает логическую 1 сразу после адреса, информируя ведомого о том, что данные будут считываться (управление линией данных передаётся ведомому).
Краткое обозначание R — заглавная буква R латинского алфавита.
- Бит Write — Если ведущий желает записать данные, он устанавливает логический 0 сразу после адреса для информирования ведомого о том что данные будут записываться (управление линией данных остаётся у ведущего).
Краткое обозначение W̅ — заглавная буква W латинского алфавита с чертой сверху.
- Stop — сигнал окончания обмена данными. Ведущий прекращат тактирование, линия тактирования SCL отпущена (логическая 1), линия данных SDA переведена ведущим из логического 0 в логическую 1. После этого сигнала шина считается свободной.
Краткое обозначение P — заглавная буква P латинского алфавита.
- Restart — сигнал продолжения обмена данными (используется взамен сигналу Stop с последующим Start для продолжения опрашивания шины ). Используется в основном при наличии нескольких ведущих на шине, чтобы управление не перешло другому ведущему после сигнала Stop. Линия тактирования SCL отпущена ведущим, линия данных SDA переведена ведущим из логической 1 в логический 0.
Обозначается Sr — заглавная буква S и строчная буква r латинского алфавита.
Устанавливаемые ведущим и ведомым
Данные биты может устанавливат как ведущий, так и ведомый. В такой ситуации устанавливающее устройство или модуль (ведущий или ведомый) называют передатчиком, а считывающее устройство — приёмником.
- Бит ACK — (сокращ. англ. acknowledged — подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была прижата приёмником (логический 0) — принятые данные верны, передача может быть продолжена или закончена.
Обозначается A — заглавная буква A латинского алфавита
- Бит NACK — (сокращ. англ. not acknowledged — не подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была отпущена принимающим или принимающего нет на шине (логическая 1) — принятые данные неверны, произошла ошибка, передача не может быть продолжена. Обозначается A̅ — заглавная буква A латинского алфавита с чертой сверху.
Видео:Как подключить несколько I²C с одинаковыми адресами. Железки АмперкиСкачать
Обмен данными
При обмене данными тактированием занимается только ведущий, а ведомый может удерживать линию тактирования только если не успевает за ведущим, так называемое растягивание тактирования (clock-stretching). Не все модули поддерживают удержание. Установка бита на линии данных может происходит в момент, когда линия тактирования прижата, а считывания, когда линия отпущена (подтянута к Vcc), но в большинстве случаев это происходит по фронту волны на линии тактирования.
Рассмотрим пример простого обмена данными:
Запись в регистры ведомого. Данные взяты из примеров, приведённых выше.
После сигнала Start и указания адреса ведущий записывает адрес регистра с которого будет производиться дальнейшая запись. Стоит заметить, что у ведомого есть внутренний счётчик и каждый последующий байт после подтверждения будет записан в следующий регистр. Таким образом байт со значением 0x00 будет записан в регистр 0x11, байт со значением 0x18 будет записан в регистр 0x12, байт со значением 0x3C будет записан в регистр 0x13 и т. д. В этом примере биты ACK устанавливает ведомый.
Вот так сигналы этого примера выглядят на осциллографе:
- Канал 1 — тактирование (SCL)
- Канал 3 — данные (SDA)
- Линия B1 — декодирование данных осциллографом
Чтение из регистров ведомого. Предположим, мы хотим прочитать байт из регистра 0x13.
После сигнала Start и указания адреса ведущий записывает адрес регистра, который необходимо прочитать. Далее следует сигнал Restart (или Stop, затем Start). Ведущий снова выводит адрес ведомого, но уже с битом Read (чтения). Ведомый устанавливает бит ACK и во время следующих 8-ти импульсов тактирования выводит данные на линию SDA. На девятом импульсе уже ведущий устанавливает бит ACK (или NACK, если данные не удалось прочитать) и завершает обмен сигналом Stop.
Видео:Arduino I2C связь между контроллерамиСкачать
Скорость
Первоначальный стандарт I²C был реализован на скорости 100 кГц. С тех пор появились и другие реализации шины, но большинство устройств работают на этой скорости. Так же известны случаи когда скорость шины специально снижена, чтобы увеличить расстояние передачи и уменьшить чувствительность к помехам. Не все модули могут работать на сниженной скорости.
🌟 Видео
Установщик адресов Flash-i2cСкачать
Программирование МК STM32. УРОК 8. HAL. Шина I2C. Подключаем микросхему RTC DS3231Скачать
FLprog урок №2 шины данных Uart\I2C\ICSP\OneWireСкачать
25 Шина I2CСкачать
Как узнать адрес устройства подключенного к шине I2CСкачать
Подключение дисплея OLED SSD1309 по шине I2CСкачать