Интерфейс i2c Ардуино, сканер i2c шины (scl sda)

I2C Arduino (i2c — Inter-Integrated Circuits) — это протокол последовательной связи по двум линиям связи. Эти линии также называются: шина SDA (последовательные данные) и шина SCL (последовательный тактовый генератор). Порты SDA и SCL Ардуино подтягиваются к шине питания микроконтроллера через резисторы. Рассмотрим, что такое шина i2c Arduino Nano и как подключить к плате Ардуино несколько устройств по интерфейсу i2c.
Необходимые компоненты:
- Arduino Uno / Arduino Nano / Arduino Mega
- lcd 1602 i2c дисплей
- модуль rtc ds1307 i2c
- коннекторы
- библиотека LiquidCrystal_I2C.h и iarduino_RTC.h
- Подключение устройств по шине SPI к Arduino
- Порты коммуникации на Arduino Uno, Nano, Mega
- Язык программирования Ардуино C++
Микроконтроллеры Arduino используют два контакта для работы i2c. В Arduino Uno и Nano линия SDA соответствует аналоговому порту A4, а SCL — аналоговому порту A5. В Ardunio Mega линия SDA — это 20 вывод, а линия SCL — 21 вывод. Чтобы облегчить работу с шиной i2c и обмен данными между устройствами, для IDE Arduino написана стандартная библиотека Wire (скачивать и устанавливать библиотеку не требуется).
Протокол интерфейс i2c Ардуино: описание

Каждому устройству при подключении к микроконтроллеру по протоколу i2c присваивается уникальный адрес (можно подключить до 127 устройств). Изменить адрес устройства на шине невозможно, так как он встроен в микросхему. Часто производители модулей предлагают возможность изменения адреса устройства в небольшом диапазоне, что позволяет подключить к шине iic Arduino несколько одинаковых устройств одновременно.
I2C scanner Arduino (сканер шины i2c)

| LCD 1602 i2c | Arduino Uno | Arduino Nano | Arduino Mega |
| GND | GND | GND | GND |
| VCC | 5V | 5V | 5V |
| SDA | A4 | A4 | 20 |
| SCL | A5 | A5 | 21 |
Следующая программа позволяет узнать адреса всех устройств, подключенных к шине i2c. Если устройство не было подключено или подключено неправильно, на мониторе порта появится сообщение о том, что устройство не найдено. Вместо дисплея можно подключить любое устройство, поддерживающее связь с микроконтроллером по протоколу iic — модуль часов реального времени DS1302, датчик атмосферного давления BMP180 и т.д.
Скетч для сканирования шины I2C Arduino
#include "Wire.h" void setup() < Wire.begin(); Serial.begin(9600); >void loop() < byte error, address; int nDevices; Serial.println("Scanning. "); nDevices = 0; for(address = 8; address < 127; address++ )< 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) < Serial.print("Unknow error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address,HEX); >> if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); >
Подключение несколько устройств к шине i2c Ардуино

| DS1307 i2c | Arduino Uno | Arduino Nano | Arduino Mega |
| GND | GND | GND | GND |
| VCC | 5V | 5V | 5V |
| SDA | A4 | A4 | 20 |
| SCL | A5 | A5 | 21 |
В следующем примере два устройства: дисплей 1602 и модуль часов времени будут подключены к шине IIC. После сборки схемы можно провести предварительное сканирование шины, используя программу, размещенную выше. Адреса всех устройств различны, и можно изменить только iic адрес жк дисплея 1602 i2c. Для остальных устройств адреса «жестко привязаны» и используются в библиотеках по умолчанию.
Скетч несколько устройств на i2c, scanner i2c шины
#include "Wire.h" #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C LCD(0x27,16,2); #include "iarduino_RTC.h" iarduino_RTC time (RTC_DS1307); // DS1307 i2C // iarduino_RTC time (RTC_DS3231); // DS3231 i2C void setup() < Serial.begin(9600); LCD.init(); LCD.backlight(); time.begin(); // 0 sec, 30 min, 18 hour, 2 date, january, 2022, wed time.settime(0, 30, 18, 2, 1, 22, 0); >void loop() < // выводим время 1 раз в секунду if (millis() % 1000 == 0) < Serial.println(time.gettime("d-m-Y, H:i:s, D")); LCD.setCursor(0,0); LCD.print(time.gettime("d M Y, D")); LCD.setCursor(4,1); LCD.print(time.gettime("H:i:s")); >>
Заключение. Мы исследовали возможность подключения нескольких i2c устройств к плате Ардуино, что будет полезно знать при разработке различных DIY проектов. Например, метеостанции на Ардуино с дисплеем и датчиком давления. Если у вас остались вопросы о сканере шины i2c или о подключении нескольких периферийных устройств по этому протоколу, не стесняйтесь оставлять их в комментариях к этой статье.
I2C мультиплексор TCA9548A Arduino
На днях возникла потребность подключить несколько датчиков угла поворота AS5600 к микроконтроллеру. У данных датчиков два интерфейса: аналоговый и I2C. При аналоговом подключении проблем со съемом данных нет, кроме помех, а вот при подключении по I2C интерфейсу возник вопрос! AS5600 имеют одинаковый адрес и изменить его невозможно, как осуществить подключение 4-х подобных датчиков? Немного разобравшись в вопросе, нашли решение: микросхема TCA9548A.
TCA9548A это переключатель I2C интерфейсов. На выходных линиях могут располагаться устройства с одинаковыми адресами, а их переключение производится управляющими командами по адресу самой микросхемы TCA9548A. Адрес TCA9548A для I2C интерфейса выбирается подачей на адресные контакты A0-A2 опрелеленных уровней: 000, это шестнадцатеричный адрес 0x70; 111 — 0х77. Если мы используем распаянную на плате микросхему как показано на рисунке ниже, то адресные контакты уже подтянуты к земле через резисторы и их можно не подключать, адрес устройства при этом будет 0х70.
RST — инвертированный сброс, подтянут через резистор к питанию, и если не собираетесь сбрасывать настроки устройства, то допустимо его не подключать.

Теперь технически можно подключить до 8 I2C устройств с одинаковыми адресами. Для примера подключим два гироприбора MPU6050 к ESP32 .

А теперь опишем этапы программной обработки данного решения.
Следующая программа опрашивает два гироприбора MPU6050, которые подключены согласно схемы изображенной выше. Перед обращением к гироприбору следует вызвать функцию void tcaselect ( uint8_t i ) , которая задает адрес подключения I2C устройства к TCA9548A. TCA9548A производит перекоммутацию, а дальше можно производить обмен, с прибором согласно его описанию.
Подключение нескольких дисплеев к Arduino по I2C: изменяем адрес PCF8574AT
В данной статье мы рассмотрим I2C модуль на основе микросхемы PCF8574AT, используемый для подключения дисплеев LCD1602 и LCD2004.
Бывает такое что нужно подключить сразу несколько дисплеев к одному микроконтроллеру, но адрес у всех модулей одинаковый ( в нашем случае это: 0x3F). Из этой ситуации мы можем выйти изменением адреса на уникальный в нашей I2C шине. Делается это следующим способом: на нашем модуле есть площадки A0, A1, A2, запаивая на них перемычки, мы притягиваем выводы микросхемы к земле (GND), тем самым изменяя адрес I2C модуля.
Таблица адресов (единица соответствует запаянной перемычке):
Запаиваем перемычку на A0 (как на фото) и получаем адрес модуля 0x3E:
Затем параллельно подключаем к выводам i2c и питания нашей Arduino дисплей с изменённым адресом (0x3E) и стоковый (0x3F).
Загружаем следующий листинг кода и получаем два работающих i2c дисплея, подключенных к одному микроконтроллеру:
Пользуясь данным способом мы можем подключить к нашему микроконтроллеру до 8 дисплеев.
Originally published at cheapchip.ru on September 18, 2018.
Несколько i2c устроиств на одной шине
столкнулся с проблемой. есть несколько датчиков и lcd экран подключенный к одной i2c шине (одним контактам esp). по отдельности все работают отлично. как только инициализирую больше одного ведомого, то начинатся глюки , зависания и перезагрузки. покопавшись в интернете, обнаружил что я не одинок. оказывается, что проблема в библиотеках — каждая из них заново инициализирует i2c шину вызывая wire.begin() в своем теле. переписывать библиотеки не вариант, 99% библиотек в инете так написанны (замучаешся их править). созрели два вопроса:
есть ли более элегантный способ решить проблему?
почему так происходит?
Юрий Ботов
Moderator
Команда форума
Закомментировать во всех библиотеках вызов wire.begin() и вызвать его самому. ДО инициализации библиотек. Или это и есть «переписывать библиотеки»?
Почему так происходит?
Из за желания использовать чужие библиотеки написанные для «помигать светодиодом».