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

Хотя один Arduino может выполнять множество задач, в некоторых проектах может потребоваться использование более одной платы для выполнения различных функций. Таким образом, для обеспечения передачи данных между двумя микроконтроллерами необходимо настроить протокол связи, такой как CAN, SPI, I2C или UART.

В этом руководстве мы рассмотрим основы работы I2C, аппаратные соединения и программную реализацию, необходимую для настройки двух плат Arduino в качестве ведущего и ведомого устройств I2C.

Что такое I2C?

Inter-Integrated Circuit (I2C) — широко используемый протокол связи во встроенных системах и микроконтроллерах для обеспечения передачи данных между электронными устройствами. В отличие от SPI (последовательный периферийный интерфейс), I2C позволяет подключать более одного ведущего устройства к шине с одним или несколькими ведомыми устройствами. Впервые он был использован Philips и также известен как протокол связи Two Wire Interface (TWI).

instagram viewer

Как работает связь I2C?

I2C использует две двунаправленные линии: последовательные данные (SDA) и последовательные часы (SCL) для передачи данных и синхронизации связи между устройствами. Каждое устройство, подключенное к шине I2C, имеет уникальный адрес, который идентифицирует его во время связи. Протокол I2C позволяет нескольким устройствам использовать одну и ту же шину, и каждое устройство может выступать в качестве ведущего или ведомого.

Связь инициируется ведущим устройством, и неправильная адресация подчиненных устройств может вызвать ошибки при передаче. Ознакомьтесь с нашим подробным руководством по как работает последовательная связь UART, SPI и I2C чтобы дать вам некоторый контекст.

Следует отметить важное преимущество связи I2C — гибкость, которую она предлагает, когда речь идет об управлении питанием. Устройства, работающие при разных уровнях напряжения, могут по-прежнему эффективно взаимодействовать с помощью переключателей напряжения. Это означает, что устройствам, работающим при напряжении 3,3 В, необходимы стабилизаторы напряжения для подключения к шине I2C 5 В.

Библиотека проводов

Библиотека Wire — это встроенная библиотека Arduino, которая предоставляет функции для связи по I2C. Он использует два контакта — SDA и SCL — на плате Arduino для связи I2C.

Контакты I2C на Arduino Uno:

Контакты Arduino Nano I2C:

Для использования библиотеки необходимо включить Провод.ч заголовочный файл в начале скетча Arduino.

#включать

Библиотека Wire предоставляет функции для инициирования связи с устройством I2C, отправки и получения данных. Некоторые важные функции, которые вы должны знать, включают в себя:

  • Wire.begin(): используется для подключения к шине I2C и инициирования связи.
  • Wire.beginTransmission(): используется для указания адреса ведомого устройства и начала передачи.
  • Wire.write(): используется для отправки данных на устройство I2C.
  • Wire.endTransmission(): используется для завершения передачи и проверки на наличие ошибок.
  • Wire.requestFrom(): используется для запроса данных с устройства I2C.
  • Wire.доступен(): используется для проверки доступности данных для чтения с устройства I2C.
  • Wire.read(): используется для чтения данных с устройства I2C.

Использовать Wire.beginTransmission() функция для установки адреса датчика, который вставляется в качестве аргумента. Например, если адрес датчика 0x68, вы бы использовали:

Проволока.начатьпередачу(0x68);

Настройка оборудования Arduino I2C

Чтобы соединить две платы Arduino с помощью I2C, вам потребуются следующие аппаратные компоненты:

  • Две платы Arduino (ведущая и подчиненная)
  • Макет
  • Перемычки
  • Два подтягивающих резистора 4,7 кОм

Подключить ПДД и СКЛ контакты обеих плат Arduino к макетной плате. Подключите подтягивающие резисторы между ПДД и СКЛ булавки и шина питания на макетной плате. Наконец, соедините две макетные платы вместе с помощью перемычек.

Схема ардуино уно

Схема Arduino Nano

Кредит изображения: Документация I2C Arduino

Настройка плат Arduino в качестве ведущего и ведомого устройств I2C

Использовать Wire.requestFrom() функция для указания адреса ведомого устройства, с которым мы хотим связаться. Затем используйте Wire.read() функция для получения данных от ведомого устройства.

Код главного устройства:

#включать
пустотанастраивать(){
Проволока.начинать(); // присоединяемся к шине i2c
Серийный.начинать(9600); // запускаем сериал для вывода
}
пустотаполучать данные(){
инт адрес = 8;
инт байты для чтения = 6;
Проволока.запрос от(адрес, байты для чтения);
пока (Проволока.доступный()) {
уголь данные = Проволока.читать();
Серийный.Распечатать(данные);
}
задерживать(500);
}
пустотапетля(){
получитьданные();
}

Wire.onReceive() Функция используется для указания того, что делать, когда ведомое устройство получает данные от ведущего устройства. В приведенном выше коде Wire.доступен() функция проверяет, доступны ли данные, и Wire.read() Функция считывает данные, отправленные ведущим устройством.

Код ведомого устройства:

#включать
пустотанастраивать(){
Проволока.начинать(8); // присоединяемся к шине I2C с адресом 8
Проволока.при получении(получить событие); // вызовите receiveEvent при получении данных
}
пустотапетля(){
задерживать(100);
}
пустотаполучитьсобытие(инт байты){
Проволока.писать("привет "); // отвечаем сообщением из 6 байт, как и ожидал мастер
}

Отправка и получение данных с использованием I2C

В этом примере давайте прочитаем температуру с датчика температуры DHT11, подключенного к ведомому Arduino, и распечатаем его на последовательном мониторе ведущего Arduino.

Давайте изменим код, который мы написали ранее, чтобы включить измерение температуры, которое мы затем отправим на главную плату по шине I2C. Затем главная плата может прочитать отправленное нами значение, а затем отобразить его на последовательном мониторе.

Код главного устройства:

#включать
пустотанастраивать(){
Проволока.начинать();
Серийный.начинать(9600);
Серийный.печать("Мастер инициализирован!");
}
пустотапетля(){
Проволока.запрос от(8, 1); // Запросить данные о температуре у ведомого
если (Проволока.доступный()) {
байт температура = Проволока.читать(); // Чтение данных температуры от ведомого устройства
Серийный.Распечатать(«Температура:»);
Серийный.Распечатать(температура);
Серийный.печать("°С");
}
задерживать(2000); // Подождите 2 секунды перед повторным запросом температуры
}

Код ведомого устройства:

#включать
#включать

#определять DHTP-код 4 // Контакт, подключенный к датчику DHT
#определять ТИП DHT DHT11 // Тип датчика DHT
ДГТ дхт(ПИН-код DHT, ТИП DHT);
байт температура;

пустотанастраивать(){
Проволока.начинать(8); // Адрес подчиненного устройства равен 8
Проволока.по запросу(событие запроса);
дхт.начинать();
}

пустотапетля(){
задерживать(2000); // Подождите 2 секунды, пока DHT стабилизируется
температура = двт.чтениеТемпература(); // Чтение температуры с датчика DHT
}

пустотазапроссобытие(){
Проволока.писать(температура); // Отправляем данные о температуре мастеру
}

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

Ведомая адресация с помощью I2C на Arduino

Для чтения значений из компонентов, добавленных к шине I2C в таком проекте, важно указать правильный адрес подчиненного устройства при кодировании. К счастью, Arduino предлагает библиотеку сканера, которая упрощает процесс идентификации ведомого устройства. адресов, избавляя от необходимости просеивать длинные листы данных датчиков и запутывать онлайн документация.

Используйте следующий код, чтобы определить адрес любого ведомого устройства, присутствующего на шине I2C.

#включать // Включить библиотеку Wire для связи I2C

пустотанастраивать(){
Проволока.начинать(); // Инициализируем связь I2C
Серийный.начинать(9600); // Инициализируем последовательную связь со скоростью 9600 бод
пока (!Серийный); // Подождите, пока установится последовательное соединение
Серийный.печать("\nСканер I2C"); // Выводим сообщение о начале сканирования I2C
}

пустотапетля(){
байт ошибка, адрес; // Объявить переменные для хранения ошибок и адресов устройств
инт nУстройства; // Объявить переменную для хранения количества найденных устройств

Серийный.печать("Сканирование..."); // Выводим сообщение о начале сканирования I2C

nУстройства = 0; // Установить количество найденных устройств равным 0
для (адрес = 1; адрес < 127; адрес++) { // Перебираем все возможные адреса I2C
Проволока.начатьпередачу(адрес); // Начать передачу на текущий адрес
ошибка = Проволока.конец передачи(); // Завершить передачу и сохранить все ошибки

если (ошибка == 0) { // Если ошибок не обнаружено
Серийный.Распечатать(«Устройство I2C найдено по адресу 0x»); // Выводим сообщение о том, что устройство найдено
если (адрес < 16) Серийный.Распечатать("0"); // Если адрес меньше 16, добавьте начальный 0 для целей форматирования
Серийный.Распечатать(адрес, HEX); // Выводим адрес в шестнадцатеричном формате
Серийный.печать(" !"); // Выводим сообщение о том, что устройство найдено

нУстройства++; // Увеличиваем количество найденных устройств
}
ещеесли (ошибка == 4) { // Если была обнаружена ошибка
Серийный.Распечатать("Неизвестная ошибка по адресу 0x"); // Выводим сообщение о том, что обнаружена ошибка
если (адрес < 16) Серийный.Распечатать("0"); // Если адрес меньше 16, добавьте начальный 0 для целей форматирования
Серийный.печать(адрес, HEX); // Выводим адрес в шестнадцатеричном формате
}
}
если (nУстройства == 0) { // Если устройства не найдены
Серийный.печать("Устройства I2C не найдены\n"); // Вывести сообщение о том, что устройства не найдены
}
еще { // Если устройства были найдены
Серийный.печать("сделано\n"); // Выводим сообщение об окончании сканирования I2C
}
задерживать(5000); // Задержка на 5 секунд перед началом следующего сканирования
}

Расширьте свой проект сегодня

Взаимодействие двух плат Arduino с использованием протокола связи I2C предлагает гибкий и эффективный способ решения сложных задач, которые не могут быть решены одной платой. С помощью библиотеки Wire связь между двумя платами по I2C упрощается, что позволяет добавлять в проект дополнительные компоненты.