I²C (IIC, англ. Inter-Integrated Circuit) — последовательная асимметричная шина для связи между интегральными схемами внутри электронных приборов.
Шина I2C также известна как двухпроводной интерфейс (Two Wire Interface, TWI) — простое и удобное устройство, используемое для обмена данными. Сам протокол был предложен фирмой Philips, но во избежание проблем с авторскими правами иногда протокол называют «двухпроводным».
Передача данных между устройствами и Arduino осуществляется по двум линиям, которые называют линией данных (Serial Data Line, SDA) и тактовой линией синхронизации сигнала (Serial Clock Line, SCL). В Arduino Uno вывод SDA находится на A4, а линия SCL — на контакте A5. Некоторые новейшие платы R3 имеют отдельные контакты, соединённые с шиной I2C и расположенные в верхнем левом углу для удобства доступа к ним. При подключении требуется установка подтягивающих резисторов. Обычно используют резисторы номиналом 4.7 кОм.
Будучи подключённой к шине I2C, плата Arduino считается ведущим устройством, а все остальные устройства — ведомыми. Каждое ведомое устройство имеет свой адрес (идентификационный номер) — шестнадцатеричное число, — позволяющий плате Arduino обращаться и взаимодействовать с каждым устройством по отдельности. Обычно устройство имеет на выбор диапазон адресов I2C, который указан в документации к нему. Конкретные доступные адреса определяются подключением контактов IC тем или иным образом.
Ведущее устройство (Uno) отвечает за инициирование обмена. Ведомые устройства не могут инициировать обмен данных, а только отвечают на запросы от ведущего устройства.
- Библиотека Wire
- Методы библиотеки
- begin()
- Параметры
- Возвращаемое значение
- requestFrom()
- Параметры
- Возвращаемое значение
- beginTransmission()
- Параметры
- Возвращаемое значение
- endTransmission()
- Параметры
- Возвращаемое значение
- write()
- Примеры
- Параметры
- Возвращаемое значение
- available()
- Параметры
- Возвращаемое значение
- Параметры
- Возвращаемое значение
- Параметры
- Возвращаемое значение
- onRequest()
- Параметры
- Возвращаемое значение
- Узнать адрес
- Как настроить I2C-связь на Arduino
- Что такое I2C?
- Сеть I2C
- Ведомое устройство (наследник)
- Ведущее устройство (мастер)
- Логические уровни
- Использование I2C
- Пины I2C Arduino
- Компоненты оборудования
- Схема соединения
- Скетч для мастера
- Объяснение скетча для мастера
- Библиотека Wire
- Отправка данных
- Wire.beginTransmission()
- Wire.write()
- Wire.endTransmission()
- Wire.requestFrom()
- Write.available()
- Wire.read();
- Скетч для наследника (ведомого)
- Объяснение скетча для ведомого
- Обработчики событий
- Wire.onReceive()
- Wire.onRequest()
- Тестирование Arduino I2C
- 📹 Видео
Видео:Лекция 308. Шина I2CСкачать
Библиотека Wire
Библиотека Wire входит в состав Arduino и используется для работы с шиной I2C.
В скетче сначала необходимо активировать библиотеку, затем в setup() активировать шину.
Поскольку как правило плата Arduino действует как ведущее устройство, ей не нужно присваивать адрес. Если бы плата настраивалась на работу в режиме ведомого устройства, нам пришлось бы присвоить адрес в диапазоне от 0 до 127, передав его как параметр, чтобы уникально идентифицировать плату на шине I2C.
Передача данных по шине осуществляется по одному байту. Чтобы послать байт из платы Arduino в устройство на шине, необходимо вызвать три функции:
- Первая функция инициализирует связь, как показано ниже (где аргумент address — это адрес ведомого устройства на шине в шестнадцатеричном виде, например 0x50):
- Вторая функция посылает 1 байт данных из Arduino в устройство с адресом, указанным в предыдущем вызове функции. Здесь аргумент data — это переменная, содержащая 1 байт данных; вы можете послать несколько байтов, но для каждого байта придётся вызвать Wire.write():
- По завершении передачи данных определённому устройству следует разорвать связь:
Чтобы запросить данные из устройства на шине I2C, инициализируйте связь вызовом Wire.beginTransmission(address) и отправьте запрос Wire.requestFrom(address, x), (где x — количество запрашиваемых байтов данных). Затем с помощью следующей функции нужно сохранить принятый байт в переменной:
По окончании приёма следует разорвать связь вызовом Wire.endTransmission().
Видео:Что такое I2C ??? Подключаем GY-521 и Oled 96*16 к STM 32Скачать
Методы библиотеки
begin()
Инициализация библиотеки Wire и подключение к шине I2C в качестве ведущего или ведомого устройства. Как правило, вызывается только один раз.
Параметры
address: 7-битный адрес устройства (если работаем в режиме ведомого). Если не указано, то контроллер подключается к шине в роли ведущего (master).
Возвращаемое значение
requestFrom()
Используется ведущим устройством для запроса байта от ведомого устройства. Байты могут быть получены с помощью методов available() и read().
Параметры
Возвращаемое значение
Возвращает число считанных байт.
beginTransmission()
Начало передачи I2C для ведомого устройства с заданным адресом. Затем, нужно вызвать метод write() для добавления последовательности байт в очередь предназначенных для передачи, и выполнить саму передачу данных методом endTransmission().
Параметры
address: 7-битный адрес устройства для передачи.
Возвращаемое значение
endTransmission()
Завершает передачу данных для ведомого устройства, которое было начато beginTransmission() и, фактически, осуществляет передачу байт, которые были поставлены в очередь методом write().
Параметры
Возвращаемое значение
Возвращает байт, который указывает статус передачи:
- 0: успех
- 1: данных слишком много и они не помещается в буфер передачи/размер буфера задаётся определением #define BUFFER_LENGTH 32
- 2: получили NACK на передачу адреса
- 3: получили NACK на передачу данных
- 4: другая ошибка
Читайте также: Шины для ваз 21124 рекомендации автоваза
write()
Записывает данные от ведомого устройства в ответ на запрос мастера, или записывает очередь байт для передачи от мастера к ведомому устройству (в промежутках между вызовами beginTransmission() и endTransmission()).
Примеры
Параметры
- value: значение для отправления как единичный байт
- string: строка для отправления как последовательность байт
- data: массив байт для отправления
- length: число байт для передачи
Возвращаемое значение
Возвращает число записанных байт.
available()
Метод available() наследуется от класса Stream. Возвращает количество байт, доступных для получения. Этот метод должно быть вызван на мастере, после вызова requestFrom() или ведомым внутри обработчика onReceive().
Параметры
Возвращаемое значение
Число байт, доступных для чтения.
Метод read() наследуется от класса Stream. Считывает байт, который был передан от ведомого устройства к мастеру, после вызова requestFrom() или был передан от мастера к ведомому.
Параметры
Возвращаемое значение
Следующий полученный байт.
Регистрирует функцию, которая вызывается, когда ведомое устройство получает данные от мастера.
Параметры
- function: функция, которая вызывается, когда ведомый получает данные; обработчик должен принимать один параметр — int (число байт, считанных от мастера) и ничего не возвращать. Например:
void MyHandler (int numBytes);
Возвращаемое значение
onRequest()
Регистрирует функцию, которая вызывается, когда мастер запрашивает данные из этого ведомого устройства.
Параметры
- function: функция, которая будет вызываться; не имеет параметров и ничего не возвращает. например:
void MyHandler();
Возвращаемое значение
Видео:Введение в шину I2CСкачать
Узнать адрес
В примерах, где используется I2C, важно использовать правильный адрес. Если у вас устройство, чей адрес вы не знаете, то можете воспользоваться библиотекой i2cdetect, доступный через менеджер библиотек. После установки библиотеки запустите прилагаемый к нему пример и через последовательный монитор увидите нужный адрес.
Также можно запустить собственный скетч.
Проверил на ЖК-экране, чей адрес обычно 0х27.
Видео:Шина I2C.Скачать
Как настроить I2C-связь на Arduino
В этом уроке мы обсудим, что такое протокол связи I2C, как он работает и как его использовать на Arduino. Для демонстрации мы построим проект, использующий I2C-соединение для обмена данными между двумя микроконтроллерами Arduino.
Видео:Урок 24. Узнаём адреса устройств на шине I2CСкачать
Что такое I2C?
c — это аббревиатура от Inter-Integrated Circuit (меж-интеграционная цепь или последовательная асимметричная шина).
I2C — низкоскоростной последовательный протокол связи, подходящий для передачи данных на короткие расстояния. Если вам необходимо передавать данные на большие расстояния, этот протокол не рекомендуется. Пример простой сети I2C показан ниже.
Как видно на диаграмме, преимущество использования I2C состоит в том, что для связи с несколькими устройствами требуется всего два провода.
Вся связь проходит по двум проводам к ведущему и ведомым устройствам и от них. Это очень полезно при выполнении проектов Arduino, так как Arduino имеет ограниченное количество входных/выходных контактов.
Многие датчики и модули, предназначенные для Arduino используют I2C для связи.
Видео:Урок 9. Адреса модулей на шине I2C. Arduino (что такое I2C, адресация, как изменить адрес модуля)Скачать
Сеть I2C
Сеть I2C состоит из ведущего и ведомого устройств, соединенных шиной. В сети I2C может быть несколько ведущих и ведомых устройств — мастеров и наследников.
Ведомое устройство (наследник)
Все ведомые устройства имеют I2C-адрес, который используется для идентификации устройства в сети. I2C-адрес позволяет ведущему устройству передавать данные конкретному ведомому устройству на шине.
Ведущее устройство (мастер)
Ведущие устройства могут отправлять и получать данные. Ведомые устройства реагируют на все, что посылает ведущее устройство. При отправке данных на шину только одно устройство может отправлять данные одновременно.
Шина в I2C — это просто два провода, которые соединяют все I2C-устройства в сети.
Эти два провода называются SDA и SCL. Провод SDA используется для связи между ведущим и ведомым устройствами.
Линия SCL несет тактовый сигнал, используемый для правильной синхронизации связи. Для поддержания обоих проводов в состоянии HIGH необходимы импульсные или подтягивающие (pull-up) резисторы.
Читайте также: За рулем выбираем зимние шины
Логические уровни
Будьте внимательны при подключении I2C устройств к Arduino.
Arduino выводит I2C-сигналы на 5В логическом уровне, но I2C-устройства работают с различными напряжениями логического уровня.
Таким образом, I2C устройство, которое работает на 3,3 В может быть повреждено при подключении к Arduino. В паспорте устройства должно быть указано напряжение логического уровня.
Если подтягивающие резисторы подключены к +5В, все устройства должны быть совместимы для работы с логическим уровнем +5В.
Видео:Видеоуроки по Arduino. I2C и processing (7-я серия, ч1)Скачать
Использование I2C
Чтобы продемонстрировать, как использовать I2C в Arduino, давайте создадим проект, который посылает данные туда и обратно между двумя ардуинами.
Мы будем использовать I2C связи для изменения скорости мигания светодиода контакта 13 на одном Arduino, в зависимости от положения потенциометра, подключенного к другому Arduino.
Один Arduino будет выступать в качестве мастера, а другой Arduino будет выступать в качестве ведомого.
Пины I2C Arduino
Arduino имеет специальные контакты для I2C, которые имеют встроенные подтягивающие резисторы в соответствии с требованиями протокола I2C.
Для плат Arduino Uno это контакты A4 и A5. Пин A4 — это контакт SDA, а пин A5 — это контакт SCL. В версии Arduino Uno R3 есть еще один набор контактов I2C рядом с USB-разъемом:
Компоненты оборудования
Чтобы создать этот проект, вам понадобятся следующие компоненты:
Схема соединения
После того, как вы соберете все детали, пришло время собрать проект. Следуйте нижеприведенной электрической схеме, чтобы все подключить:
Вы могли заметить, что у нас нет подтягивающих резисторов на линиях SDA и SCL. Подтягивающие резисторы уже встроены в I2C контакты Arduino, так что они нам не нужны.
Видео:Подключение нескольких устройств, датчиков по I2C (АйТуСи) шинеСкачать
Скетч для мастера
У нас есть два Ардуино в нашей сети I2C, так что у нас есть два набора скетчей. Один для мастера Ардуино, а другой для наследника Ардуино. Между двумя эскизами нет большой разницы, как вы увидите позже.
Теперь откройте Arduino IDE и загрузите код ниже на мастер Arduino:
Видео:Подключение нескольких устройств по шине i2cСкачать
Объяснение скетча для мастера
Основная часть кода как для ведущего, так и для ведомых устройств — это то, что я называю логическим кодом мигания. Чтобы мигнуть светодиодом 13 на Ардуино, мы должны сделать следующее:
- Добавим глобальные переменные byte i2c_rcv , int time_start , stat_LED и byte value_pot в верхней части нашего скетча
- Инициализируйте значения глобальных переменных внутри функции setup()
- Инициализируйте контакт 13 Arduino как выходной контакт внутри setup() с помощью pinMode()
- Добавим код логики мигания внутри функции loop()
Библиотека Wire
Для использования встроенного интерфейса I2C Arduino мы будем использовать библиотеку Wire.
Эта библиотека поставляется в стандартной комплектации с Arduino IDE. Как и в других библиотеках Arduino, библиотека Wire имеет готовые I2C функции, чтобы сделать кодирование проще для нас.
Чтобы использовать функции библиотеки Wire, мы должны добавить его сначала в наш эскиз. В эскизе выше, у нас есть следующая строка в верхней части:
После включения библиотеки мы можем использовать встроенные функции библиотеки.
Первое, что нужно сделать, это подключить устройство к шине I2C. Синтаксис для этого — Wire.begin(address) . Адрес является необязательным для мастер-устройств. Итак, для эскиза мастера Arduino, мы просто добавляем код Wire.begin(); внутри setup() .
Теперь мы переходим к циклу loop() . Наш код заставит Arduino прочитать значение потенциометра, подключенного к контакту A0, и сохранить его в переменной value_pot .
Отправка данных
После сохранения значения с пина A0 в переменную value_pot , мы можем отправить значение по I2C. Отправка данных по I2C включает в себя три функции:
- Wire.beginTransmission()
- Wire.write()
- Wire.endTransmission()
Wire.beginTransmission()
Мы инициируем команду отправки, сначала информируя устройства на шине о том, что мы будем отправлять данные.
Для этого мы вызываем функцию Wire.beginTransmission(address) . Адрес — это I2C-адрес ведомого прибора, который будет принимать данные. Эта функция делает две вещи:
- Она информирует шину о том, что мы будем посылать данные.
- Он информирует предполагаемого получателя о том, что данные готовы к получению.
Читайте также: Падение давления в шинах фольксваген поло лифтбек
Wire.write()
А затем мы отправим значение переменной value_to_send с помощью функции Wire.write(value) .
Wire.endTransmission()
После отправки данных нам необходимо освободить сеть, чтобы позволить другим устройствам общаться по сети. Это делается с помощью функции Wire.endTransmission() .
Наше ведущее устройство также должно получить положение потенциометра от ведомого устройства. Мы делаем это с помощью Wire.requestFrom() , Wire.available() и Wire.read() .
Wire.requestFrom()
Полным синтаксисом запроса данных от ведомого устройства является Wire.requestFrom(адрес, количество).
Адрес — это I2C-адрес ведомого устройства, от которого мы должны получить данные, а количество — это количество байтов, которое нам нужно. Для нашего проекта, адрес ведомого устройства 0x08 и нам нужен один байт.
Внутри loop() мы используем Wire.requestFrom(0x08, 1); для запроса одного байта данных от ведомого устройства 0x08.
После выдачи команды Wire.requestFrom(0x08, 1) , за ней должна следовать команда чтения для получения ответа от шины I2C.
Write.available()
Сначала мы проверяем, есть ли данные на шине. Это делается с помощью функции Write.available() внутри условного оператора if() . Функция Write.available() возвращает количество байт, ожидающих чтения.
Wire.read();
Для получения доступных данных мы используем функцию Wire.read() и сохраняем возвращаемое значение в переменную i2c_rcv . Каждый вызов функции Wire.read() получает только один байт данных из шины I2C.
Видео:Arduino I2C связь между контроллерамиСкачать
Скетч для наследника (ведомого)
Теперь загрузите этот код ведомому Ардуино:
Видео:Урок 26.3 Соединяем две arduino по шине I2C #iarduinoСкачать
Объяснение скетча для ведомого
Для ведомого устройства существует небольшая разница в кодировании I2C-связи. Первая разница заключается в адресе Wire.begin(address) .
Для ведомых устройств адрес является обязательным. Для нашего проекта адрес для ведомого устройства будет 0x08. Это может быть любой адрес, но убедитесь, что он уникален в сети I2C.
Некоторые I2C ведомые устройства также имеют определенные I2C-адреса, поэтому сначала проверьте спецификацию.
Мы присоединим I2C сеть в качестве ведомого устройства, добавив код Wire.begin(0x08); внутри setup() .
Обработчики событий
Следующая задача — добавить в наш код обработчики событий для управления данными, полученными с других устройств в I2C сети.
Обработчики событий — это части кода, которые управляют событиями, с которыми наше устройство, скорее всего, столкнется во время работы.
Wire.onReceive()
В части скетча setup() мы добавляем функцию Wire.onReceive(handler) для регистрации функции (обработчика), которая будет управлять полученными данными.
Мы вызываем нашу функцию-обработчик dataRcv() . Обратите внимание, что имя функции может быть любым. В приведенном выше эскизе Wire.onReceive(dataRcv); вызывается в секции setup() .
В конце эскиза находится код функции-обработчика. Он инициализируется как void dataRcv(int numBytes) . Параметр int numBytes содержит количество байт полученных данных.
Wire.onRequest()
Следующий обработчик события, который мы будем использовать — Wire.onRequest(handler) . Эта функция используется на подчиненных устройствах и работает аналогично Wire.onReceive() .
Единственное отличие заключается в том, что она обрабатывает события запроса данных. Запросы данных поступают от основных устройств.
В функцию setup() мы добавляем код Wire.onRequest(dataRqst); . А в конце нашего эскиза добавляем функцию void dataRqst() . Обратите внимание, что обработчики Wire.onRequest() не принимают никаких параметров. Функция dataRqst() содержит только Wire.write() .
Нам не нужны Wire.beginTransmission() и Wire.endTransmission() , потому что библиотека Wire уже обрабатывает ответы от ведомых устройств.
Видео:Теория и практика UART, I2C (TWI), SPI на arduino.Скачать
Тестирование Arduino I2C
А вот и самая захватывающая часть — включение питания и тестирование!
Используя Arduino IDE, загрузите эскиз мастера Arduino в одну из Ардуино. Затем загрузите скетч наследника в другую Arduino.
- Отрегулируйте потенциометр на ведущем устройстве, чтобы регулировать частоту мигания светодиода ведомого устройства.
- Отрегулируйте потенциометр на ведомом устройстве, чтобы контролировать частоту мигания светодиода ведущего устройства.
Наш код принимает положение потенциометра мастера и посылает его ведомому устройству через I2C. Затем ведомое устройство использует полученное значение для настройки времени задержки мигания светодиода. То же самое происходит и с положением потенциометра ведомого.
- Свежие записи
- Нужно ли менять пружины при замене амортизаторов
- Скрипят амортизаторы на машине что делать
- Из чего состоит стойка амортизатора передняя
- Чем стянуть пружину амортизатора без стяжек
- Для чего нужны амортизаторы в автомобиле
- Правообладателям
- Политика конфиденциальности
📹 Видео
Как подключить несколько I²C с одинаковыми адресами. Железки АмперкиСкачать
Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED I2C, TJA 1020Скачать
FLprog урок №2 шины данных Uart\I2C\ICSP\OneWireСкачать
Шина I2C. Подключаем LCD дисплей к ArduinoСкачать
1. Мне 5 лет и я изучаю Arduino (дисплей 1604 шина I2C)Скачать
Установщик адресов Flash-i2cСкачать
💡 Arduino - Экраны #1 - LCD1602 и i2c шина - EP6Скачать
Логический анализатор шины i2cСкачать