Расширитель I2C (хаб)
Описание
Расширитель I2C - представляет из себя плату, на которой имеется несколько выводов для подключения устройств по интерфейсу I2C. Данный модуль позволит подключить до 6 устройств, работающих по I2C одновременно, задействовав для этого только один интерфейс контроллера.
Подключать расширитель к контроллеру будет удобно через Sensor Shield - на нем уже предусмотрен готовый разъем I2C - просто подсоедините к шилду разъем «I2C IN» модуля посредством четырехпроводного шлейфа.
Избегайте подключения нескольких устройств с одинаковыми адресами - это может привести к конфликту устройств и их некорректной работе.
Технические характеристики
- Интерфейс подключения к контроллеру: I2C
- Максимальное количество подключаемых устройств: 6
Физические размеры
- Модуль Д х Ш х В (мм): 30 х 20 х 10
Плюсы использования
- Удобное подключение к Sensor shield
- Возможность увеличить количество подключенных устройств к контроллеру
- Удобное подключение к расширителю с помощью 4-ёх проводных шлейфов
Минусы использования
- Модуль немного дороже, чем подключение проводами через макетную плату
Примеры использования и подключения
Пример 1: В примере демонстрируется подключение нескольких устройств к расширителю. Далее, с помощью скетча ниже, определяются адреса устройств, которые подключены к модулю.
Что нужно | Кол-во, шт |
---|---|
Контроллер Smart UNO | 1 |
Sensor Shield | 1 |
Расширитель I2C | 1 |
Модуль часов PCF8563 | 1 |
Дисплей 2-строчный с I2C модулем | 1 |
Дисплей 4-строчный с I2C модулем | 1 |
Шлейф "мама-мама" х4 | 4 |
Схема подключения: Подключение расширителя и устройств к нему происходит напрямую, для этого удобно использовать 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. Далее происходит вывод времени, дня недели и даты на дисплей.
Что нужно | Кол-во, шт |
---|---|
Контроллер Smart UNO | 1 |
Sensor Shield | 1 |
Расширитель I2C | 1 |
Модуль часов PCF8563 | 1 |
Дисплей 2-строчный с I2C модулем | 1 |
Шлейф "мама-мама" х4 | 3 |
Схема подключения: Подключение расширителя и устройств к нему происходит напрямую, для этого удобно использовать 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()); //вывод даты
}