Связь · разбор
Шина I2C в Arduino: SDA, SCL, Wire.h и адреса устройств
Два провода, на которых висят экран, часы и десяток датчиков сразу. Разбираем, где SDA и SCL на вашей плате, почему библиотеку I2C негде скачать, как найти адрес модуля и что делать, когда сканер молчит или программа зависает намертво.
Если вы пришли за конкретным экраном — подключение символьного дисплея разобрано на странице LCD 1602 по I²C, а маленького OLED — на странице OLED-дисплей SSD1306. Здесь речь о самой шине: она общая для всех устройств.
Что такое шина и почему устройств много, а проводов два
I²C (читается «и-квадрат-цэ», пишут и просто I2C) — это шина: одна пара проводов, к которой все устройства подключаются параллельно. SDA — данные, SCL — такт, который задаёт ведущий, то есть плата. Чтобы устройства не путались, у каждого есть свой адрес.
- SDA — вывод A4 (данные, идут в обе стороны)
- SCL — вывод A5 (такт, его задаёт ведущий)
- GND (общий ноль)
- подтяжка — 4,7 кОм на питание (без неё линия не поднимается)
Главная особенность, из которой растёт всё остальное: устройства на шине умеют только притягивать линию к нулю. Выдать единицу не может никто — линию просто отпускают, и её подтягивает вверх резистор. Так и получается общий провод без конфликтов: если хоть кто-то тянет вниз, на линии ноль; единица бывает, только когда линию отпустили все.
Отсюда же и все болезни шины: без подтягивающих резисторов линия не поднимается вовсе, а если подтяжка слишком слабая — поднимается слишком медленно. К этому мы вернёмся с числами ниже.
SDA и SCL: где они на вашей плате
| Плата | SDA | SCL | Что стоит знать |
|---|---|---|---|
| Uno, Nano, Pro Mini | A4 | A5 | Отдельные штырьки SDA и SCL у края Uno — те же самые выводы |
| Mega 2560 | 20 | 21 | Продублированы у края рядом с AREF |
| Leonardo, Pro Micro | 2 | 3 | Не A4 и A5: скетч с Uno сюда не переносится |
| ESP32 | 21 | 22 | Можно переназначить: Wire.begin(SDA, SCL) |
| ESP8266 | D2 | D1 | Шина программная, переносится на любую пару |
Первая строка таблицы содержит ловушку, на которой спотыкаются даже опытные. У Uno на дальнем конце цифровой гребёнки, сразу за AREF, есть отдельные штырьки, подписанные SDA и SCL, — и кажется, что это дополнительная шина. Это не так: они соединены с A4 и A5 внутри платы. Практический вывод: пока работает I²C, два аналоговых входа заняты — это одни и те же выводы. Есть платы, где шину развели отдельной парой, и тогда A4 и A5 остаются свободными.
Вторая ловушка — Leonardo и Pro Micro: у них шина на выводах 2 и 3. Скетч, честно переписанный с Uno, там просто не найдёт устройств.
Библиотеку I2C скачивать негде — и не нужно
Больше тысячи раз в месяц люди ищут «библиотеку I2C», «Wire.h скачать», «библиотека wire arduino». Ответ короткий: такой библиотеки в каталогах нет, потому что она приходит вместе с поддержкой платы. Достаточно строки #include <Wire.h> — файл уже лежит внутри установленного ядра.
Проверить это легко по нашей же статистике ошибок сборки. За два месяца в отчётах не встретилось ни одного случая «Wire.h: No such file or directory». Зато встречается другое, и постоянно:
LiquidCrystal_I2C.h: No such file or directory— один из самых частых пропавших заголовков. Это не шина, а библиотека конкретного экрана, и вот её действительно надо ставить.Adafruit_I2CDevice.h: No such file or directory— тоже не шина: файл принадлежит библиотеке Adafruit BusIO, которую тянут за собой библиотеки датчиков и экранов. Trema IDE подсказывает это прямо в окне ошибки.'Wire' does not name a type— а вот это вообще не про библиотеку: обычно выше по тексту потеряна строкаvoid setup() {, и команды оказались вне функции.
Разбор того, какой файл какой библиотеке принадлежит, и таблица «файл .h → что ставить» — на странице Библиотеки Arduino: найти по файлу и установить.
Адрес устройства: 0x27, 0x3F и почему в даташите 0x4E
Адрес на этой шине семибитный: возможных значений 128, из них реально используются от 8 до 119, остальные зарезервированы. Адрес задаёт производитель микросхемы, у части модулей его можно менять перемычками или программно.
Отсюда классическая путаница: в скетче адрес один, а в документации на ту же микросхему — вдвое больший.
Адрес зависит от микросхемы: в карточке конвертера для LCD на PCF8574 указано «Адрес на шине I2C: 0x3F или 0x27 (зависит от модификации чипа)». Поэтому единственный надёжный способ узнать адрес — не гадать, а спросить у шины.
Сканер адресов: узнать, кто на шине, за одну прошивку
Сканер перебирает адреса подряд и смотрит, кто отзовётся. Библиотек для этого не нужно — только Wire, которая уже есть:
#include <Wire.h> // библиотека шины I2C — она уже внутри ядра
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial) {} // нужно только Leonardo и Micro: ждём открытия монитора
Serial.println(F("Ищу устройства на шине I2C..."));
int found = 0;
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
// endTransmission вернёт 0, если по этому адресу кто-то ответил.
if (Wire.endTransmission() == 0) {
Serial.print(F("Найдено устройство по адресу 0x"));
if (address < 16) Serial.print(F("0")); // адрес всегда из двух цифр
Serial.println(address, HEX);
found++;
}
}
if (found == 0) {
Serial.println(F("Никто не ответил — проверьте провода SDA и SCL"));
}
}
void loop() {
}
Залейте скетч и откройте монитор порта на скорости 9 600 — в нём появится строка вида «Найдено устройство по адресу 0x27». Пришло «Никто не ответил» — переходите к пяти причинам ниже. Как открыть монитор, разобрано на странице Монитор порта.
В Trema IDE тот же скетч лежит готовым: Примеры → 09. Полезное → I2C_Scanner, с русскими комментариями, распиновкой для четырёх семейств плат и подсказками по типовым адресам. Ничего не надо ни искать, ни устанавливать.
Почему перебор идёт с первого адреса по 126-й, хотя по спецификации «честный» диапазон — с 8-го по 119-й? Потому что реальные устройства садятся и за его пределами: об этом прямо сказано в комментариях к штатному примеру Arduino, где диапазон сначала сузили до честного, а потом вернули обратно из-за найденного датчика с адресом 120. Сканер намеренно смотрит шире правил.
Сканер ничего не нашёл: пять причин по порядку
- Перепутаны SDA и SCL. Самое частое. Провода одинаковые, подписи мелкие — переставьте их местами и запустите сканер снова.
- Нет общей земли. Если модуль питается от отдельного источника, а земля не соединена, шина не работает вовсе.
- На модуль не подано питание. И это не просто «он не отвечает»: обесточенное устройство, оставленное на шине, мешает работать всей шине целиком — так прямо написано в даташите контроллера.
- Модуль трёхвольтовый, а плата пятивольтовая. Библиотека подтягивает линии к питанию платы, то есть к 5 В. Некоторым модулям это не нравится — нужен преобразователь уровней.
- Слишком слабая подтяжка или слишком длинные провода. Об этом — следующий раздел.
Подтяжка: почему «и так работает» — временно
Вот факт, который редко встретишь в статьях, хотя он лежит прямо в исходниках библиотеки: команда Wire.begin() сама включает внутреннюю подтяжку контроллера на обеих линиях. Именно поэтому шина на столе часто работает без единого внешнего резистора, и человек делает вывод, что резисторы — выдумка.
Проблема в номинале. Внутренняя подтяжка у ATmega328P — от 20 до 50 кОм. Линию она поднимает через её собственную ёмкость, и время подъёма считается по простой формуле: t ≈ 0,85 · R · C (точный коэффициент 0,847). Спецификация шины разрешает на подъём не больше 1 микросекунды при 100 кГц. Подставим:
| Подтяжка | Ёмкость линии 100 пФ | Успевает при 100 кГц? | При 400 кГц? |
|---|---|---|---|
| 2,2 кОм | 186 нс | Да, с запасом | Да |
| 4,7 кОм | 398 нс | Да, с запасом | Нет |
| 10 кОм | 847 нс | Впритык | Нет |
| 20 кОм (внутренняя) | 1 695 нс | Нет | Нет |
| 50 кОм (внутренняя) | 4 236 нс | Нет | Нет |
Внутренней подтяжки хватает на ёмкость 25–60 пикофарад — это буквально пара микросхем рядом на плате, при том что один только вывод микроконтроллера даёт до 10 пФ. Поэтому правильный ответ такой: внутренняя подтяжка есть, но рассчитывать на неё нельзя. На макетке с проводами ставьте по резистору 4,7 кОм с каждой линии на питание — один комплект на всю шину, а не на каждое устройство.
Обратная сторона: если подтяжки стоят на нескольких модулях сразу, они соединяются параллельно и общее сопротивление падает. Три резистора по 4,7 кОм дают 1,57 кОм — а нижняя граница по даташиту при 5 В около 1,5 кОм, то есть запаса уже нет. Некоторые наши модули умеют подтяжку отключать: у адаптера для LCD серии FLASH-I²C она включена по умолчанию, и в описании модуля сказано прямо — если на шине много модулей с подтяжкой, отключение её у части из них заметно улучшает связь.
Про длину проводов. Спецификация нормирует не метры, а ёмкость линии: не больше 400 пикофарад. Поэтому честный ответ на вопрос «на сколько метров тянется I²C» звучит так: шина рассчитана на связь внутри одного прибора, и чем длиннее провода, тем ниже должна быть и подтяжка, и скорость. Нужны десятки метров — берите RS-485, это другая физика.
Скорость: 100 килогерц по умолчанию, 400 по просьбе
Ядро выставляет 100 кГц. Ускорить шину можно одной строкой — но обязательно после Wire.begin(), иначе настройка будет затёрта:
Wire.begin();
Wire.setClock(400000); // 400 кГц; вызывать только ПОСЛЕ begin()
Быстрее 400 кГц контроллер ATmega328P по паспорту не умеет. Формально шину можно разогнать и выше — до 800 кГц и даже до мегагерца она отработает, но это уже за пределами гарантий даташита. А вот просить больше мегагерца прямо опасно: во внутреннем расчёте происходит переполнение, и шина вместо ускорения падает примерно до 31 кГц — при запросе двух мегагерц получается ровно 30 769 герц. И помните про подтяжку: на 400 кГц требования к времени подъёма втрое строже, 10 кОм там уже не проходят.
Тридцать два байта — и молчаливое обрезание
За одну посылку через Wire проходит не больше 32 байт. Всё, что сверх того, отбрасывается: сама Wire.write() вернёт ноль и поставит признак ошибки, но Wire.endTransmission() всё равно отчитается об успехе — поэтому пропажу и не замечают. И запрос Wire.requestFrom(адрес, 40)тоже тихо превратится в запрос 32 байт.
Ответ команды Wire.endTransmission() — главный диагностический инструмент шины. Вот что означают её числа:
| Ответ | Что произошло | Что делать |
|---|---|---|
| 0 | Устройство ответило | Всё хорошо |
| 1 | Данные не влезли в очередь | Со штатной библиотекой не возвращается никогда — лишнее отбрасывается раньше и молча |
| 2 | По этому адресу никого нет | Не тот адрес, нет питания у модуля, оборван провод |
| 3 | Устройство отказалось принимать данные | Адрес верный, но команда не понята или устройство занято |
| 4 | Другая беда на шине | Например, шину перехватил второй ведущий |
| 5 | Истекло время ожидания | Появляется, только если вы сами включили тайм-аут |
Отдельно стоит знать, что у команды чтения кода ошибки нет вообще: если устройства по адресу нет, requestFrom просто вернёт ноль принятых байтов. Поэтому в скетче всегда стоит проверять, сколько байтов пришло, — как в примере с двумя платами ниже.
Программа зависла намертво: почему и как это лечится
Самая неприятная беда шины выглядит так: плата перестаёт подавать признаки жизни, светодиод не мигает, монитор молчит. Причина в том, что по умолчанию у библиотеки нет тайм-аута: если линию кто-то удерживает — оборван провод, завис модуль, отключилось его питание — программа остаётся ждать внутри библиотеки навсегда.
Лечится это двумя строчками, которые стоит писать всегда:
Wire.begin();
Wire.setWireTimeout(25000, true); // ждать не дольше 25 мс и сбросить шину
// Дальше в программе можно проверить, срывалось ли ожидание:
if (Wire.getWireTimeoutFlag()) {
Wire.clearWireTimeoutFlag();
// шина была занята - показания в этот раз пропускаем
}
Число 25 миллисекунд взято из протокола SMBus — родственника I²C, откуда его и взяли авторы библиотеки. В самом I²C потолка нет: ведомый вправе притормозить обмен, если не успевает, и ведущий обязан ждать. Тайм-аут по мерке SMBus отличает законную задержку от настоящего обрыва.
Несколько устройств и конфликт адресов
Пока адреса разные, устройства просто вешаются на ту же пару проводов, и всё. Беда начинается, когда нужны два одинаковых модуля: адрес у них тоже одинаковый, и шина этого не разрешает — сканер увидит одно устройство вместо двух, а показания будут мешаться.
Выходов три, и они разные по цене и удобству.
- Сменить адрес на самом модуле. У части модулей для этого есть перемычки или переключатель — например, у нашего OLED адрес выбирается между 0x3C и 0x3D, и два одинаковых экрана уживаются на одной шине. У модулей нашей серии FLASH-I²C адрес меняется программно и сохраняется в памяти модуля. Важная тонкость: почти все они приезжают с завода с одинаковым адресом (обычно 0x09), поэтому подключать их к шине надо по одному, меняя адрес каждому, а уже потом собирать всё вместе.
- Поднять вторую шину на других выводах. I²C можно сделать программно на любой паре цифровых выводов — тогда два одинаковых модуля просто живут на разных шинах. Для этого есть готовые библиотеки, в том числе наша iarduino_I2C_Software; ставится из каталога libraries.trema.ru прямо из окна ошибки.
- Поставить мультиплексор — микросхему, которая по очереди подключает к плате одну из нескольких шин. Честно предупредим: сами мы такие модули не продаём.
Чего разветвитель не делает. Наш i2C Hub (Trema-модуль) размножает одну и ту же пару проводов на много разъёмов — это удобно, когда модулей много, но конфликт одинаковых адресов он не решает: шина остаётся одна. В карточке об этом сказано прямо: «Избегайте подключения нескольких устройств с одним адресом!».
Две Arduino по шине I2C
Плата может быть на шине не только ведущим, но и ведомым — то есть работать как датчик для другой платы. Провода: A4 — A4 (SDA), A5 — A5 (SCL), GND — GND. И два резистора 4,7 кОм с каждой линии на питание — один комплект на обе платы, а не на каждую: без них пара работает через раз ровно по той причине, что разобрана выше. Ведущий раз в полсекунды спрашивает значение:
// Ведущая плата. Раз в полсекунды спрашивает у ведомой её показание.
// Провода: A4 - A4 (SDA), A5 - A5 (SCL), GND - GND.
#include <Wire.h>
const byte SLAVE = 8; // адрес ведомой платы
void setup() {
Serial.begin(9600);
Wire.begin(); // ведущий - без адреса в скобках
Wire.setWireTimeout(25000, true); // не ждать дольше 25 мс и сбросить шину
}
void loop() {
byte answered = Wire.requestFrom(SLAVE, (byte)2);
if (answered != 2) {
Serial.println(F("Ведомая плата не ответила"));
} else {
byte lo = Wire.read(); // порядок чтения задаём явно
byte hi = Wire.read();
int value = (int)((uint16_t)lo | ((uint16_t)hi << 8));
Serial.print(F("Получено: "));
Serial.println(value);
}
delay(500);
}
А ведомая плата отвечает по запросу, назвав себе адрес:
// Ведомая плата. Отдаёт показание датчика, когда её спросят.
// Провода: A4 - A4 (SDA), A5 - A5 (SCL), GND - GND.
#include <Wire.h>
volatile int value = 0;
void setup() {
Wire.begin(8); // 8 - свой адрес на шине
Wire.onRequest(onAsk); // что делать, когда ведущий спросит
}
void onAsk() { // пока идёт прерывание, loop() стоит: значение неподвижно
Wire.write(value & 0xFF);
Wire.write((value >> 8) & 0xFF);
}
void loop() {
int fresh = analogRead(A0);
noInterrupts(); // запись двух байтов должна быть неделимой
value = fresh;
interrupts();
delay(50);
}
Три правила, без которых эта пара работает через раз. Функция-обработчик у ведомого вызывается из прерывания, а значит внутри неё нельзя ни delay(), ни печать в монитор порта, ни обращения к шине как ведущий: всё это либо не сработает, либо подвесит обмен. Ответ ведомого ограничен теми же 32 байтами. И запись двухбайтового значения в loop() надо закрыть от прерывания — noInterrupts() перед присваиванием и interrupts() после: иначе запрос ведущего придёт между записью старшего и младшего байта, и ведомый отдаст полуобновлённое число. А в самом обработчике прятаться не от чего: пока он работает, loop() стоит.
Пошаговая сборка двух плат с видео и списком деталей — в уроке «Соединяем две Arduino по шине I2C». Там же — наша библиотека, которая позволяет ведущему читать переменные ведомого как обычный массив.
I2C, UART или SPI: что выбрать
Обычно выбирать не приходится — способ подключения задан модулем. Но когда выбор есть, разница такая.
| Что сравниваем | UART | I²C | SPI |
|---|---|---|---|
| Проводов, кроме земли | 2 | 2 | 3 + по одному на устройство |
| Сколько устройств | 2 | Десятки, по числу адресов | Сколько выводов хватит |
| Кто задаёт такт | Никто, оба считают время сами | Ведущий | Ведущий |
| Типичная скорость | 9 600 … 250 000 бод | 100 или 400 кГц | 8 МГц и выше |
| Расстояние | Метры, с RS-485 — сотни метров | Внутри одного прибора | Внутри одного прибора |
| Занимает ОЗУ на Uno | 175 байт | 216 байт | Единицы байт |
Коротко: UART — это разговор двоих, и он единственный тянется далеко. I²C — когда устройств много, а выводов мало; плата за удобство — скорость и расстояние. SPI — когда нужна скорость: экраны с картинкой и карты памяти живут именно там, но каждому устройству нужен свой отдельный вывод выбора.
Есть и цена в памяти, о которой обычно не думают, пока скетч не перестанет помещаться. Мы собрали одинаковые скетчи-заготовки под Arduino Uno и посмотрели, сколько занимает сама возможность связи:
216 байт — это десятая часть всей оперативной памяти Uno, и уходит она на одну лишь возможность обмена: Wire.begin() плюс первая же посылка. Причина в том, что очередей у шины целых пять по 32 байта: две у самой библиотеки и три у её нижнего слоя. Если в проекте вдобавок стоит экран с копией картинки в памяти, свободного места остаётся совсем мало — как это считать, разобрано на странице Память Arduino.
Что купить для шины
Цены, артикулы и наличие — на 23.08.2026, магазин iarduino.ru. Модули Trema — нашего собственного производства.
Установщик адресов FLASH-I²C
Наш прибор для шины: показывает, сколько устройств на ней сидит, и меняет адреса модулей FLASH-I²C, не отключая их от шины. Диапазон адресов — от 0x08 до 0x7E, шире «честного» диапазона спецификации ровно потому, что реальные модули за него выходят.
Trema Set Shield
Плата-основание на шесть секций: модули вставляются в колодки без единого провода, а шина I²C разведена на верхнюю колодку каждой секции — все шесть модулей могут висеть на одной шине. Быстрый способ собрать схему с несколькими устройствами и не искать, где отвалился контакт.
| Что ещё пригодится | Зачем | Цена |
|---|---|---|
| Провода «папа-мама», 40 шт., 20 см | Штырьком — в гнездо платы, гнездом — на штырёк модуля: SDA, SCL, питание, земля | 161 ₽ |
| Набор резисторов для макетирования | Есть и 4,7 кОм, и 10 кОм — оба типовых номинала подтяжки | 260 ₽ |
| Преобразователь уровней 5 В ↔ 3,3 В | Четыре канала, двусторонний: две линии шины плюс запас | 53 ₽ |
| Расширитель выводов FLASH-I²C, Trema-модуль | Наш модуль: восемь выводов по шине, адрес меняется программно | 351 ₽ |
| Часы реального времени DS3231, Trema-модуль | Классический житель шины с адресом 0x68 — на нём удобно тренироваться | 486 ₽ |
Эта тема в Trema IDE
- Сканер адресов уже внутри. Примеры → 09. Полезное → I2C_Scanner: с русскими комментариями, распиновкой для Uno, Mega, Leonardo и ESP32 и списком типовых адресов.
- Библиотека ставится прямо из окна ошибки. Среда узнаёт файл по имени и предлагает нужную библиотеку из каталога libraries.trema.ru — включая случай, когда просят Adafruit_I2CDevice.h, а ставить надо Adafruit BusIO.
- Каталог работает из России. Официальный сервер библиотек Arduino отвечает из России не всегда, поэтому у нас своё зеркало библиотек и плат.
- Видно, сколько памяти осталось. После сборки среда показывает, сколько флеша и ОЗУ занял скетч, — разницу до и после строки
#include <Wire.h>видно сразу.
Вопросы и ответы
Коротко о главном
Если чего-то не хватает — напишите через форму поддержки, мы дополняем страницы по реальным вопросам.
Где скачать библиотеку I2C для Arduino?
Скачивать нечего: библиотека Wire приходит вместе с поддержкой платы, достаточно строки include в начале скетча. Обычно под «библиотекой I2C» имеют в виду библиотеку конкретного устройства — например, экрана; вот её действительно нужно установить, и Trema IDE предложит нужную прямо в окне ошибки.
Куда подключать SDA и SCL?
На Uno, Nano и Pro Mini это выводы A4 и A5, на Mega — 20 и 21, на Leonardo и Pro Micro — 2 и 3, на ESP32 — 21 и 22. Отдельные штырьки SDA и SCL у края платы Uno соединены с A4 и A5 внутри платы, то есть это не вторая шина: пока работает I2C, эти два аналоговых входа заняты.
Как узнать адрес устройства на шине I2C?
Запустить сканер: он перебирает адреса подряд и печатает те, по которым кто-то отозвался. Ставить для этого ничего не надо — готовый скетч лежит в Trema IDE в разделе примеров «09. Полезное», с русскими комментариями и подсказками по типовым адресам.
Почему в скетче адрес 0x27, а в документации 0x4E?
Это одно и то же число, записанное по-разному. Адрес на шине семибитный, а по проводу едет целый байт: библиотека сдвигает адрес влево и дописывает младшим битом направление — читаю или пишу. Поэтому 0x27 превращается в 0x4E. Увидели в даташите чётное число вроде 0x78 или 0xD0 — поделите на два.
Сколько устройств можно подключить к одной шине I2C?
Столько, сколько разных адресов, — все они висят на одной и той же паре проводов параллельно. Ограничение не в числе, а в совпадениях: два одинаковых модуля с одинаковым адресом шина не разрешит. Тогда адрес меняют перемычкой или программно, либо поднимают вторую шину на других выводах.
Нужны ли резисторы подтяжки для I2C?
Команда Wire.begin сама включает внутреннюю подтяжку контроллера, поэтому на столе шина часто работает и без резисторов. Но её номинал 20–50 килоом, а этого по расчёту хватает лишь на пару сантиметров дорожки. На макетке с проводами ставьте по резистору 4,7 килоом с каждой линии на питание — один комплект на всю шину.
Программа зависает при работе с датчиком по I2C — что делать?
У библиотеки по умолчанию нет ограничения по времени: если линию кто-то удерживает — оборван провод, завис или обесточен модуль, — программа ждёт внутри библиотеки бесконечно. Добавьте после Wire.begin строку Wire.setWireTimeout(25000, true): ожидание прервётся через 25 миллисекунд, а шина будет сброшена.
Сколько памяти занимает шина I2C на Arduino Uno?
Мы измерили сборкой: 2 118 байт флеша и 216 байт оперативной памяти сверх пустого скетча — это десятая часть всего ОЗУ платы. Столько получается потому, что очередей у шины пять по 32 байта: две у самой библиотеки и три у её нижнего слоя. За одну посылку при этом проходит не больше 32 байт.
Дальше по теме
Вторая связь, без которой не обходится ни один проект, — UART: RX, TX и связь двух плат. Какие бывают модули и как их подключают — Модули для Arduino и Датчики для Arduino. Экраны на этой же шине — LCD 1602 и OLED.
