Расширитель I2C (хаб)

Описание

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

Подключать расширитель к контроллеру будет удобно через Sensor Shield - на нем уже предусмотрен готовый разъем I2C - просто подсоедините к шилду разъем «I2C IN» модуля посредством четырехпроводного шлейфа.

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

Технические характеристики

  • Интерфейс подключения к контроллеру: I2C
  • Максимальное количество подключаемых устройств: 6

Физические размеры

  • Модуль Д х Ш х В (мм): 30 х 20 х 10

Плюсы использования

  • Удобное подключение к Sensor shield
  • Возможность увеличить количество подключенных устройств к контроллеру
  • Удобное подключение к расширителю с помощью 4-ёх проводных шлейфов

Минусы использования

  • Модуль немного дороже, чем подключение проводами через макетную плату

Примеры использования и подключения

Пример 1: В примере демонстрируется подключение нескольких устройств к расширителю. Далее, с помощью скетча ниже, определяются адреса устройств, которые подключены к модулю.

Схема подключения: Подключение расширителя и устройств к нему происходит напрямую, для этого удобно использовать 4-ёх проводной шлейф. Если на устройстве выводы расположены в другом порядке, подключите к расширителю с помощью обычных проводов мама-мама (или тех, которые подходят к Вашему устройству).

Скетч для загрузки:

#include <Wire.h> //подключение библиотеки
 
 
void setup()
{
  Wire.begin(); //инициализация шины
  Serial.begin(9600); //инициализация монитора Serial-порта
  while (!Serial); //ожидание доступности порта
  Serial.println("I2C Scanner");
}
 
 
void loop()
{
  //вспомогательные переменные
  byte error; //хранение кода ошибки
  byte address; //хранение адреса устройства
  int nDevices = 0; //счётчик устройств
 
  Serial.println("Scanning..."); //вывод надписи
 
  for (address = 1; address < 127; address++ )
  {
    /* Для поиска устройств воспользуемся функцией коммуникации и
     *  окончания коммуникации с устройством на адресе от 1 до 127. 
     *  При окончании коммуникации возвращается код ошибки.
     *  Если он не равен нулю, то коммуникация прошла успешно,
     *  и устройство на данном адресе найдено.
     *  В противном случае выводится информация об ошибке.
     */
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0) { //ошибки не обнаружено
 
      //вывод адреса найденного устройства
      Serial.print("I2C device found at address 0x");
      if (address < 16) {
        Serial.print("0");
      }  
      Serial.print(address, HEX);
      Serial.println("  !");
 
      nDevices++; //увеличение счётчика найденных устройств
 
    } else if (error == 4) { //если код ошибки равен 4 - устройство неопознано
      //вывод информации об ошибке
      Serial.print("Unknown error at address 0x");
      if (address < 16) {
        Serial.print("0");
      }  
      Serial.println(address, HEX);
    }
  }
 
  //вывод результата по окончании сканирования
  if (nDevices == 0) {
    Serial.println("No I2C devices found");
  } else {
    Serial.print("Found ");
    Serial.print(nDevices);
    Serial.println(" devices");
  }
 
  delay(5000);  //пауза в 5 секунд между сканированием
}

Результат:

Scanning...
I2C device found at address 0x27  !
I2C device found at address 0x51  !
Found 2 devices

В результате подключения, в мониторе Serial-порта видно два подключенных устройства. И тут возникает логичный вопрос:

Было подключено три устройства, куда одно пропало?

Мы специально добавили такие устройства, чтобы продемонстрировать одну особенность шины I2C. Дело в том, что если устройства имеют одинаковый адрес, то шиной они определяются как одно. Так как плата модуля I2C, которая имеется на дисплеях, имеет один и тот же адрес (0x27), то оба дисплея определяются как одно и то же устройство.

Как понять, какое из устройств какой адрес имеет?

Здесь не существует универсального способа, но самое простое что приходит в голову, это отсоединить от Расширителя I2C все устройства кроме одного, и проверить именно его адрес. Так Вы сможете определить адреса требуемых устройств. Помните, что даже разные устройства могут иметь один и тот же адрес I2C, имейте это ввиду в своих проектах и избегайте подключения на одну шину устройств с одинаковым адресом! В нашем примере Дисплеи имеют адрес 0x27, а часы имеют адрес 0x51.

Пример 2: В примере демонстрируется подключение часов и дисплея к Расширителю I2C. Далее происходит вывод времени, дня недели и даты на дисплей.

Схема подключения: Подключение расширителя и устройств к нему происходит напрямую, для этого удобно использовать 4-ёх проводной шлейф. Если на устройстве выводы расположены в другом порядке, подключите к расширителю с помощью обычных проводов мама-мама (или тех, которые подходят к Вашему устройству.

Скетч для загрузки:

#include <LiquidCrystal_I2C.h> //подключение библиотеки для работы с дисплеем
#include <Wire.h>  //библиотека для работы с I2C
#include <Rtc_Pcf8563.h> //библиотека для работы с часами
 
LiquidCrystal_I2C lcd(0x27, 16, 2); //создание объекта дисплея с адресом и количеством символов/строк
Rtc_Pcf8563 rtc; //создание объекта для работы с часами
 
void setup() {
  lcd.init(); //инициализация дисплея
  /* Следующие строки кода нужны только один раз,
   *  для установки времени на часах. 
   *  Поэтому закомментируйте эти строки, вызывая их повторно.
   *  И не забудьте при первом включении,
   *  подставить свои значения, соответствующие
   *  текущей дате и времени.
   */
  //очистка регистров часов
  //rtc.initClock();
  //установка даты:
  //день месяца, день недели, месяц, век(1=1900, 0=2000), год(0-99)
  //в следующей строке установлена дата 20 ноября 2018 года (вторник)
  //rtc.setDate(20, 2, 11, 0, 18);
  //Установка времени
  //часы, минуты, секунды
  //rtc.setTime(14, 55, 0);
}
 
void loop() {
  lcd.home(); //установка курсора в верхний левый угол
  lcd.print(rtc.formatTime()); //вывод текущего времени на дисплее
  lcd.setCursor(0, 1); //установка курсора на вторую строку
  lcd.print(rtc.getWeekday()); //вывод текущего дня недели
  lcd.setCursor(2, 1); //установка курсора на третью ячейку
  lcd.print(rtc.formatDate()); //вывод даты
}