Что такое I2C? SDA, SCL, подтягивающие резисторы и сканер на Arduino
Что такое I2C и как он работает? SDA и SCL, 7-битные адреса, расчёт подтягивающих резисторов, скетч I2C-сканера, конфликты адресов и пины Uno, ESP32 и Pico.
I2C (Inter-Integrated Circuit) — протокол последовательной связи, с помощью которого микроконтроллер общается с десятками датчиков, дисплеев и модулей всего по двум сигнальным проводам (SDA и SCL). Читается он как «и-два-си» (по-английски «I-squared-C»), а в некоторых даташитах называется IIC или TWI (Two Wire Interface). I2C LCD, OLED-дисплей, акселерометр MPU6050, датчик давления BMP280 и модуль часов DS1307 из проектов на Arduino — все говорят на этом протоколе; их можно параллельно подключить к одним и тем же двум проводам и обращаться к каждому по его собственному адресу.
В этом руководстве разберём, как I2C работает с точки зрения электрики, что означают адреса, почему без подтягивающих резисторов не обойтись и как рассчитать их номинал. Затем шаг за шагом пройдём таблицу пинов для Arduino Uno, ESP32 и Raspberry Pi Pico, скетч I2C-сканера, который находит все устройства на шине, пример чтения регистров без библиотеки и решения частых проблем вроде конфликта адресов.

Что такое I2C и как он работает?
I2C разработала компания Philips (сегодня NXP) в 1982 году, чтобы микросхемы на одной плате могли общаться по небольшому числу проводов. На шине две роли: контроллер (раньше его называли master, ведущий), который начинает каждую передачу и формирует тактовый сигнал, и целевые устройства (раньше slave, ведомые), которые ему отвечают. В проектах на Arduino контроллером почти всегда выступает Arduino, ESP32 или Pico, а датчики и дисплеи — целевые устройства.
- SDA (Serial Data): линия, по которой данные идут в обе стороны. Контроллер отправляет адреса и команды, а датчик по той же линии возвращает показания.
- SCL (Serial Clock): линия тактового сигнала. На каждом тактовом импульсе считывается один бит на SDA, а такты формирует контроллер.
- GND (общая земля): опорный уровень для сигналов. Даже у модулей с отдельным питанием GND должна быть общей.
Линии работают по схеме открытый сток (open-drain): ни одно устройство не выставляет на линии высокий уровень, оно может только прижать её к земле. Уровень 1 на линии держат подтягивающие резисторы, которые соединяют SDA и SCL с напряжением питания. Поэтому короткого замыкания не бывает, даже если два устройства пытаются говорить одновременно: если хоть одно прижимает линию, все видят 0. Сообщение I2C выглядит так:
- START: пока SCL в высоком уровне, контроллер переводит SDA из 1 в 0, и все устройства на шине начинают слушать.
- Адрес и бит направления: отправляется 7-битный адрес, а за ним бит чтения (1) или записи (0).
- ACK: устройство с этим адресом прижимает SDA во время 9-го тактового импульса и тем самым сообщает «я здесь». Если не отвечает никто, это называется NACK.
- Байты данных: каждый байт передаётся 8 битами, и приёмник отвечает на каждый подтверждением ACK. У большинства датчиков первый байт — номер регистра, который нужно прочитать или записать.
- STOP: пока SCL в высоком уровне, SDA поднимается из 0 в 1, и шина снова свободна. При чтении вместо STOP используется повторный START, чтобы сменить направление, не освобождая шину.
Если сравнить I2C с двумя другими популярными в мире Arduino протоколами, сразу видно, когда его выбирать:
| Параметр | I2C | SPI | UART (Serial) |
|---|---|---|---|
| Сигнальные провода | 2 (SDA, SCL) | 3 общих (MOSI, MISO, SCK) + по одному CS на устройство | 2 (TX, RX) |
| Число устройств | Больше 100 адресов на одной шине | Сколько свободных пинов CS | Обычно 2 устройства |
| Типичная скорость | 100 kHz, 400 kHz, 1 MHz | 10 MHz и выше | 9600 – 115200 бод |
| Выбор устройства | По адресу | Пином CS | Не нужен, точка-точка |
| Типичное применение | Датчики, часы, небольшие дисплеи, EEPROM | SD-карты, TFT-дисплеи, RFID | GPS, Bluetooth, связь с компьютером |
Скорости I2C и технические ограничения
| Режим | Максимальная скорость | Максимальное время нарастания | Где применяется? |
|---|---|---|---|
| Стандартный режим (Sm) | 100 kHz | 1000 нс | По умолчанию, длинные провода |
| Быстрый режим (Fm) | 400 kHz | 300 нс | OLED, MPU6050, BMP280 |
| Быстрый режим плюс (Fm+) | 1 MHz | 120 нс | Pico и некоторые новые датчики |
| Высокоскоростной режим (Hs) | 3,4 MHz | 80 нс (400 pF), нужны специальные драйверы | В хобби-проектах встречается редко |
Библиотека Wire в Arduino по умолчанию запускается на 100 kHz; большинство датчиков поддерживают и 400 kHz, переключиться на эту частоту можно командой Wire.setClock(400000). На более высокой скорости дисплеи обновляются плавнее, но шина становится чувствительнее к длине проводов и номиналу подтяжки. По стандарту общая ёмкость шины (провода плюс выводы устройств) не должна превышать 400 pF. Обычные перемычки и шлейфы добавляют 50–100 pF на метр, а каждый вывод устройства — до 10 pF, поэтому I2C задумывался для работы в пределах одной платы или с проводами длиной в несколько десятков сантиметров. Дальше 1 метра придётся снизить скорость, поставить подтяжку посильнее или добавить расширители шины вроде P82B715.
Адреса I2C: 7-битные, 8-битные и зарезервированные
У каждого устройства на шине есть 7-битный адрес, что теоретически даёт 128 адресов. Диапазоны 0x00–0x07 и 0x78–0x7F зарезервированы для особых целей, поэтому для использования остаются 112 адресов от 0x08 до 0x77. Обычно адрес задаёт производитель микросхемы, но на многих модулях последние биты можно изменить паяными перемычками или пинами A0, A1, A2 или AD0.
Теперь запутанная часть: в некоторых даташитах и на наклейках на обратной стороне модулей адрес указан 8-битным, вместе с битом направления. Например, на обороте OLED-платы написано «0x78», а в коде адрес — 0x3C; если на LCD-модуле указано 0x4E, то в коде адрес 0x27. Правило простое: раздели 8-битное значение на 2 (сдвинь вправо на один бит) и получишь 7-битный адрес. Библиотеки для Arduino, ESP32 и MicroPython ожидают именно 7-битные адреса.
| Модуль | Микросхема | Адрес по умолчанию | Можно изменить? |
|---|---|---|---|
| I2C-модуль для LCD (16x2, 20x4) | PCF8574 / PCF8574A | 0x27 / 0x3F | Перемычками A0–A2: 0x20–0x27 или 0x38–0x3F |
| OLED 0,96″ | SSD1306 | 0x3C | 0x3D резистором на обороте |
| Акселерометр и гироскоп | MPU6050 | 0x68 | 0x69 при AD0 = 1 |
| Часы реального времени | DS1307 / DS3231 | 0x68 | Нет |
| Давление и температура | BMP280 / BME280 | 0x76 или 0x77 | Зависит от пина SDO |
| Освещённость | BH1750 | 0x23 | 0x5C при ADDR = 1 |
| 16-битный АЦП | ADS1115 | 0x48 | 0x48–0x4B пином ADDR |
| 16-канальный драйвер сервоприводов и PWM | PCA9685 | 0x40 | Десятки адресов от 0x40 перемычками A0–A5 |
| Память EEPROM | AT24C32 / AT24C256 | 0x50 | 0x50–0x57 через A0–A2 |
| I2C-мультиплексор | TCA9548A | 0x70 | 0x70–0x77 через A0–A2 |
Подтягивающие резисторы: зачем они нужны и как выбрать номинал
Устройства на шине I2C умеют только прижимать линии к земле, поэтому высокий уровень обеспечивают подтягивающие резисторы. Если резистор слишком большой, ёмкость шины замедляет переход из 0 в 1, фронты сигнала скругляются, и на высоких скоростях биты читаются с ошибками. Если он слишком маленький, растёт ток, который устройство должно пропустить через себя, прижимая линию; стандарт требует от устройства лишь не меньше 3 mA при 0,4 V, так что подтяжка должна держать ток ниже этого значения.
Две границы дают такие формулы: минимальное сопротивление R(min) = (VCC − 0,4 V) / 3 mA, а максимальное R(max) = t(нарастания) / (0,8473 × C(шины)). Для 5 V R(min) = 4,6 V / 0,003 A ≈ 1,53 kΩ, а для 3,3 V ≈ 0,97 kΩ. На короткой шине с ёмкостью 100 pF R(max) ≈ 11,8 kΩ на 100 kHz и ≈ 3,5 kΩ на 400 kHz. Поэтому на практике чаще всего ставят 4,7 kΩ для 100 kHz и 2,2 kΩ для 400 kHz и нагруженных шин. Прочитать полосы резистора поможет утилита Цветовая маркировка резисторов, а задержку, которую создают сопротивление и ёмкость, покажет утилита Постоянная времени RC.
| Ситуация | Рекомендуемая подтяжка | Примечание |
|---|---|---|
| Один модуль, короткие провода, 100 kHz | 4,7 kΩ – 10 kΩ | На большинстве модулей они уже есть |
| Несколько модулей, 400 kHz | 2,2 kΩ – 4,7 kΩ | Резисторы на модулях оказываются включены параллельно |
| Провода длиннее 50 см | 2,2 kΩ и 100 kHz | Не скручивай SDA с SCL; каждый скручивай с GND |
| Шина 3,3 V (ESP32, Pico) | 2,2 kΩ – 4,7 kΩ | Подключай резисторы к 3,3 V, а не к 5 V |
На Arduino Uno вызов Wire.begin() заодно включает встроенные подтягивающие резисторы ATmega328P на 20–50 kΩ. С одним модулем и проводами 10–20 см их часто хватает, но надёжными их не назовёшь; внешние резисторы всегда лучше. Если используется голая плата датчика без подтяжки, не забудь поставить резисторы 4,7 kΩ от SDA и от SCL к VCC.
Пины I2C: Arduino Uno, Mega, ESP32, ESP8266 и Pico
| Плата | SDA | SCL | Примечание |
|---|---|---|---|
| Arduino Uno / Nano | A4 | A5 | На Uno R3 пины SDA и SCL рядом с AREF — это та же шина, что и A4/A5 |
| Arduino Mega 2560 | 20 | 21 | На Mega A4 и A5 не относятся к I2C |
| Arduino Leonardo / Micro | D2 | D3 | Это цифровые пины |
| ESP32 (DevKit) | GPIO 21 | GPIO 22 | Другие пины задаются через Wire.begin(SDA, SCL); вторая шина — Wire1 |
| ESP8266 NodeMCU | D2 (GPIO 4) | D1 (GPIO 5) | Программный I2C, пины можно менять |
| Raspberry Pi Pico | GP4 (I2C0) | GP5 (I2C0) | I2C0 и I2C1 доступны на многих парах пинов |
Шаг за шагом: ищем адреса скетчем I2C-сканера
Когда в руках новый модуль, первое дело — узнать адреса устройств на шине. I2C-сканер отправляет пустое сообщение на каждый адрес от 0x08 до 0x77 и выводит список тех, кто ответил ACK. Так сразу становится ясно и то, что модуль подключён правильно, и то, какой адрес нужно указать в коде.
- Подключи GND модуля к GND Arduino, а VCC — к 5V (к 3.3V для модулей, которые поддерживают только 3,3 V).
- Подключи SDA к A4, а SCL к A5. Если модулей несколько, соедини все их пины SDA и SCL на макетной плате.
- Загрузи скетч ниже и открой монитор порта на скорости 115200 бод.
- Запиши найденные адреса. Если ничего не появилось, проверь подключение, общую GND и подтягивающие резисторы.
- Отключай и снова подключай модули по одному, чтобы убедиться, какой адрес какому устройству принадлежит; сканер повторяет поиск каждые 5 секунд.
1#include <Wire.h>
2
3void printHex(byte addr) {
4 Serial.print(F("0x"));
5 if (addr < 16) Serial.print('0'); // tek haneliye sıfır ekle / pad single digit
6 Serial.print(addr, HEX);
7}
8
9void setup() {
10 Serial.begin(115200);
11 Wire.begin(); // Uno: A4 = SDA, A5 = SCL
12#if defined(ARDUINO_ARCH_AVR)
13 Wire.setWireTimeout(3000, true); // AVR (Uno, Nano, Mega): hat kilitlenirse 3 ms sonra kurtar / recover a stuck bus after 3 ms
14#endif
15 Serial.println(F("I2C tarayici / I2C scanner"));
16}
17
18void loop() {
19 byte found = 0;
20 for (byte addr = 0x08; addr <= 0x77; addr++) { // geçerli 7 bit adresler / valid 7-bit addresses
21 Wire.beginTransmission(addr);
22 byte err = Wire.endTransmission(); // 0 = cihaz ACK verdi / device acknowledged
23 if (err == 0) {
24 Serial.print(F("Bulundu / found: "));
25 printHex(addr);
26 Serial.println();
27 found++;
28 } else if (err == 4 || err == 5) {
29 Serial.print(F("Hat hatasi / bus error at "));
30 printHex(addr);
31 Serial.println();
32 }
33 }
34 if (found == 0) {
35 Serial.println(F("Cihaz yok: kablolari ve pull-up'lari kontrol et / no devices: check wiring and pull-ups"));
36 } else {
37 Serial.print(found);
38 Serial.println(F(" cihaz bulundu / device(s) found"));
39 }
40 Serial.println();
41 delay(5000); // 5 sn sonra yeniden tara / rescan after 5 s
42}| Результат endTransmission() | Значение | Что делать |
|---|---|---|
| 0 | Устройство подтвердило свой адрес (ACK) | Используй этот адрес в коде |
| 1 | Данные не помещаются в буфер | В сканере не встречается; на Uno не записывай больше 32 байт за раз |
| 2 | NACK на адрес | По этому адресу устройства нет, при сканировании это нормально |
| 3 | NACK на данные | Устройство отклонило команду; проверь номер регистра |
| 4 | Другая ошибка шины | Короткое замыкание, нет подтяжки или помехи |
| 5 | Тайм-аут | Шина зависла; проверь подключение и питание |
Строка setWireTimeout в скетче важна: если SDA или SCL замкнуты или какое-то устройство зависло, прижав линию, библиотека Wire на Uno с настройками по умолчанию может ждать бесконечно, и программа зависнет. С включённым тайм-аутом библиотека сдаётся через 3 мс, сбрасывает аппаратный блок I2C, а сканер сообщает о проблеме кодом ошибки. Строка обёрнута в #if, поэтому компилируется только на платах AVR (Uno, Nano, Mega); у библиотек Wire для ESP32 и ESP8266 уже есть своя защита по тайм-ауту, так что один и тот же скетч без изменений компилируется и работает на всех трёх платформах.
I2C без библиотеки: чтение и запись регистров
Библиотеки упрощают жизнь, но внутри все они делают одно и то же: отправляют устройству номер регистра, а затем читают байты из этого регистра или записывают в него. Если хотя бы раз проделать это вручную, можно разобраться в даташите нового датчика и пользоваться им даже без библиотеки. Пример ниже выводит датчик MPU6050 из спящего режима, читает его регистр идентификации (WHO_AM_I), а затем по сырым значениям вычисляет температуру и ускорение по оси Z.

1#include <Wire.h>
2
3const byte MPU_ADDR = 0x68; // AD0 GND'de; AD0 = 3.3V ise 0x69 / AD0 low; 0x69 if AD0 high
4
5void writeReg(byte reg, byte value) {
6 Wire.beginTransmission(MPU_ADDR);
7 Wire.write(reg); // önce yazmaç adresi / register address first
8 Wire.write(value); // sonra veri / then the data
9 Wire.endTransmission(); // STOP gönder / send STOP
10}
11
12int16_t readWord(byte reg) {
13 Wire.beginTransmission(MPU_ADDR);
14 Wire.write(reg);
15 Wire.endTransmission(false); // STOP yok, tekrarlı START / no STOP, repeated START
16 Wire.requestFrom(MPU_ADDR, (byte)2); // 2 bayt iste / request 2 bytes
17 uint8_t hi = Wire.read();
18 uint8_t lo = Wire.read();
19 return (int16_t)(((uint16_t)hi << 8) | lo);
20}
21
22void setup() {
23 Serial.begin(115200);
24 Wire.begin();
25 Wire.setClock(400000); // hızlı mod 400 kHz / fast mode 400 kHz
26 writeReg(0x6B, 0x00); // PWR_MGMT_1: uykudan uyandır / wake up from sleep
27 Wire.beginTransmission(MPU_ADDR);
28 Wire.write(0x75); // WHO_AM_I yazmacı / WHO_AM_I register
29 Wire.endTransmission(false);
30 Wire.requestFrom(MPU_ADDR, (byte)1);
31 Serial.print(F("WHO_AM_I = 0x"));
32 Serial.println(Wire.read(), HEX); // 68 beklenir / expect 68
33}
34
35void loop() {
36 int16_t raw = readWord(0x41); // TEMP_OUT_H ve TEMP_OUT_L / TEMP_OUT_H and TEMP_OUT_L
37 float tempC = raw / 340.0 + 36.53; // veri sayfasındaki formül / datasheet formula
38 int16_t az = readWord(0x3F); // Z ekseni ivmesi / Z-axis acceleration
39 Serial.print(F("Sicaklik / temp: "));
40 Serial.print(tempC, 1);
41 Serial.print(F(" C AccZ: "));
42 Serial.println(az / 16384.0, 2); // +-2g aralığında 16384 = 1 g / 16384 = 1 g at +-2g
43 delay(500);
44}Обрати внимание на строку endTransmission(false) в функции чтения: она меняет направление повторным START вместо STOP, поэтому никакое другое устройство не может вклиниться, а датчик не забывает, какой регистр запрошен. Если WHO_AM_I возвращает 0x68, связь в полном порядке. На дешёвых модулях-клонах значение может быть 0x70 или другим числом; это значит, что стоит совместимая, но другая микросхема, например MPU6500, и именно из-за этого некоторые готовые библиотеки пишут «sensor not found» (датчик не найден). Формула температуры (сырое значение / 340 + 36.53) взята прямо из даташита MPU6050; для ускорения в диапазоне ±2 g сырое значение 16384 соответствует 1 g, поэтому у датчика, лежащего ровно на столе, по оси Z будет около 1.00.
Несколько устройств на одной шине и конфликты адресов
Главное преимущество I2C в том, что устройства можно подключать к тем же двум проводам параллельно, пока их адреса различаются. Например, LCD (0x27), OLED (0x3C), BMP280 (0x76) и часы DS3231 (0x68) спокойно делят одни и те же пины A4 и A5: каждая библиотека говорит со своим адресом, а остальные устройства молча слушают. Проблемы начинаются, когда у двух устройств одинаковый адрес: оба отвечают ACK, их данные сталкиваются, и обычно не работает ни одно. Вот способы это исправить:
- Смени адрес пином: если подключить пин AD0 у MPU6050 к 3,3 V, адрес станет 0x69, и конфликт с DS3231 (0x68) исчезнет.
- Используй паяные перемычки: перемычки A0–A2 на LCD-модулях дают 8 адресов, а пин ADDR у ADS1115 — 4.
- Заведи вторую шину I2C: перенеси конфликтующее устройство на отдельные пины через Wire1 на ESP32 или I2C1 на Pico.
- Добавь I2C-мультиплексор: TCA9548A открывает восемь отдельных подшин с одного адреса (0x70); так можно подключить даже восемь OLED с одинаковым адресом.
- Устройства с фиксированным адресом: у некоторых микросхем, например DS1307 или HTU21D, адрес изменить вообще нельзя; им поможет только отдельная шина или мультиплексор.
I2C на ESP32: любые пины и две отдельные шины
На ESP32 аппаратный блок I2C можно гибко вывести на разные пины. По умолчанию это GPIO 21 (SDA) и GPIO 22 (SCL), но с Wire.begin(SDA, SCL) можно выбрать почти любые два GPIO. У классического ESP32 и ESP32-S3 два контроллера I2C, поэтому два датчика с одинаковым адресом можно запустить на двух отдельных шинах; у ESP32-C3 контроллер только один. GPIO 34–39 работают только на вход и для I2C не подходят. Полную карту пинов платы смотри в утилите Распиновка, а общее введение — в статье Что такое ESP32?.
1#include <Wire.h>
2
3// Klasik ESP32'de iki I2C denetleyicisi vardır: Wire ve Wire1 / the classic ESP32 has two I2C controllers: Wire and Wire1
4
5void scan(TwoWire &bus, const char *name) {
6 Serial.printf("%s:\n", name);
7 for (uint8_t addr = 0x08; addr <= 0x77; addr++) {
8 bus.beginTransmission(addr);
9 if (bus.endTransmission() == 0) {
10 Serial.printf(" bulundu / found 0x%02X\n", addr);
11 }
12 }
13}
14
15void setup() {
16 Serial.begin(115200);
17 Wire.begin(21, 22); // SDA, SCL: varsayılan pinler / default pins
18 Wire1.begin(32, 33, 400000); // SDA, SCL, hız: başka iki GPIO / SDA, SCL, speed: any two other GPIOs
19 scan(Wire, "Wire (SDA 21, SCL 22)");
20 scan(Wire1, "Wire1 (SDA 32, SCL 33)");
21}
22
23void loop() {
24}I2C на Raspberry Pi Pico (MicroPython)
У микросхемы RP2040 в Pico два контроллера — I2C0 и I2C1, и каждый можно вывести на несколько разных пар пинов. Для I2C0 подходят GP0/GP1, GP4/GP5, GP8/GP9, GP12/GP13, GP16/GP17 и GP20/GP21; для I2C1 — GP2/GP3, GP6/GP7, GP10/GP11, GP14/GP15, GP18/GP19 и GP26/GP27. В каждой паре чётный пин — SDA, а нечётный — SCL. В MicroPython сканер умещается в одну строку: i2c.scan() возвращает список адресов, ответивших ACK. Pico работает от 3,3 V, поэтому питать модули от пина 3V3(OUT) безопаснее всего; RP2040 поддерживает и режим Fast mode plus на 1 MHz, но на макетной плате с 400 kHz сюрпризов меньше. Первые шаги с Pico описаны в статье Что такое Raspberry Pi Pico?.
1from machine import Pin, I2C
2
3i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000) # I2C0: GP4 = SDA, GP5 = SCL
4devices = i2c.scan() # ACK veren adresler / addresses that ACK
5
6if devices:
7 for addr in devices:
8 print("Bulundu / found:", hex(addr))
9else:
10 print("Cihaz yok / no devices")
11
12# MPU6050 varsa WHO_AM_I yazmacını oku / if an MPU6050 is present, read WHO_AM_I
13if 0x68 in devices:
14 i2c.writeto_mem(0x68, 0x6B, b"\x00") # uykudan uyandır / wake up
15 who = i2c.readfrom_mem(0x68, 0x75, 1)[0]
16 print("WHO_AM_I:", hex(who)) # 0x68 beklenir / expect 0x68Идеи проектов с I2C
- Мини-метеостанция: измеряй давление и температуру с BMP280 и выводи их на OLED-дисплей; оба модуля делят одни и те же два провода.
- Цифровые часы: читай время из модуля часов DS3231 и выводи его на I2C LCD-дисплей.
- Индикатор наклона: вычисляй угол с помощью MPU6050 и рисуй результат на OLED, как на электронном уровне.
- Wi-Fi-узел с датчиком: следи с телефона за датчиком, подключённым к пинам D1 и D2 платы ESP8266 NodeMCU.
- Роборука на 16 сервоприводов: управляй 16 сервоприводами всего с двух пинов через драйвер PCA9685.
- Регистратор данных: записывай показание в EEPROM AT24C256 каждую минуту, чтобы данные пережили отключение питания.
Частые ошибки и как их исправить
| Признак | Вероятная причина | Решение |
|---|---|---|
| Сканер не находит ни одного устройства | Перепутаны SDA и SCL, нет общей GND или модуль без питания | Проверь подключение; на Uno A4 = SDA, A5 = SCL |
| Сканер зависает или выдаёт ошибки на каждом адресе | Замыкание на шине или нет подтяжки | Добавь setWireTimeout; измерь напряжение питания на SDA и SCL в покое |
| Скетч компилируется, но дисплей пустой | Неверный адрес в коде (0x27 вместо 0x3F) | Используй адрес, найденный сканером |
| На обороте платы написано 0x78, и код не работает | Использован 8-битный адрес | Раздели на 2: 0x78 → 0x3C |
| Два датчика не работают вместе | Конфликт адресов | Смени адрес пином, используй вторую шину или TCA9548A |
| Случайные зависания, сбои при работе мотора | Длинные провода, помехи или слабое питание | Укороти провода, снизь частоту до 100 kHz, поставь на модули конденсаторы 100 nF |
| Повреждён пин ESP32 или Pico | К пину 3,3 V подключена подтяжка к 5 V | Питай модуль от 3,3 V или используй преобразователь уровней |
I2C — самый практичный способ добавить в проект дисплеи, часы, датчики и память всего по двум проводам; когда понятны адреса, подтягивающие резисторы и скетч-сканер, большинство проблем решается за несколько минут. В приложении BlueGrays есть проекты на I2C: I2C LCD-дисплей, игра Pong на OLED-дисплее, цифровые часы с DS1307 и погодный дисплей на ESP32 — у каждого пошаговые схемы подключения и код.
Частые вопросы
Чем I2C отличается от SPI?
I2C благодаря адресации позволяет посадить больше сотни устройств на одни и те же два провода, но обычно ограничен 100–400 kHz. SPI нужны три общих провода плюс отдельный пин выбора микросхемы (CS) для каждого устройства; зато он достигает 10 MHz и выше. I2C выбирают для датчиков и небольших дисплеев, SPI — для SD-карт и цветных TFT-дисплеев.
Сколько устройств можно подключить к шине I2C?
7-битная адресация даёт 112 доступных адресов. На практике предел задаёт не столько число адресов, сколько ёмкость шины (максимум 400 pF) и параллельно включённые подтягивающие резисторы; на макетной плате нормально работают 5–10 устройств. Для большего числа используй мультиплексор TCA9548A или вторую шину I2C.
Какого номинала должны быть подтягивающие резисторы I2C?
Чаще всего ставят 4,7 kΩ для 100 kHz и коротких проводов и 2,2 kΩ для 400 kHz или шин с большим числом устройств. Не опускайся ниже 1,5 kΩ на шине 5 V и ниже 1 kΩ на шине 3,3 V. И помни, что резисторы на модулях оказываются включены параллельно.
Какие пины на Arduino Uno относятся к I2C?
На Arduino Uno и Nano SDA — это пин A4, а SCL — пин A5. У Uno R3 рядом с AREF есть ещё два пина с подписями SDA и SCL, но на плате они соединены с A4 и A5 и отдельной шиной не являются. На Mega пины I2C — 20 (SDA) и 21 (SCL).
Какой максимальной длины может быть кабель I2C?
I2C задумывался для коротких расстояний в пределах платы; на 100 kHz и с подходящей подтяжкой он обычно работает примерно до 1 метра. Для больших расстояний нужно снизить скорость, взять кабель «витая пара» или перейти на драйверы шины вроде P82B715. Для нескольких метров лучше выбрать RS-485 или беспроводную связь.
Что делать, если I2C-сканер не находит устройство?
Сначала проверь, что SDA и SCL стоят на правильных пинах, общая GND подключена, а модуль получает питание. Затем проверь подтяжку, измерив напряжение питания на SDA и SCL в покое. Если устройство всё равно не находится, попробуй модуль отдельно, с короткими проводами и на 100 kHz, а на ESP32 убедись, что в Wire.begin переданы правильные пины.
Что собрать после прочтения
Все проекты
LCD-экран с I2C
Дай своему Arduino собственный экран и заставь его написать первое сообщение. Двухстрочный LCD-экран подключается всего несколькими проводами; в верхней строке появляется приветствие, затем второе соо

I2C LCD-дисплей (16x2) на ESP32
В этом проекте символьный LCD-экран 16x2 подключается к ESP32 по протоколу I2C и выводит текст. Благодаря I2C экраном можно управлять всего двумя пинами данных (SDA и SCL), не тратя 6+ пинов, как при классическом параллельном подключении. Код печатает постоянное сообщение в первой строке и счётчик, растущий каждую секунду, во второй. Кроме того, при запуске работает сканер I2C, который выводит адрес дисплея в монитор порта.

Цифровые часы на ESP32 и DS1307 RTC (I2C + LCD)
В этом проекте время и дата из модуля часов реального времени (RTC) DS1307 выводятся на I2C LCD-экран 16x2. DS1307 — RTC с резервной батарейкой, который хранит время даже при выключенной ESP32. Оба модуля делят одну шину I2C (SDA/SCL), и ты узнаёшь, как управлять несколькими устройствами всего по двум сигнальным проводам. Проект даёт практические знания о протоколе I2C, работе модуля RTC и динамическом выводе данных на LCD-экран.

Калькулятор на Arduino с I2C
Калькулятор на Arduino, который выполняет сложение, вычитание, умножение и деление с помощью плёночной клавиатуры 4x4 и LCD-дисплея 16x2 с I2C. Благодаря I2C дисплей подключается всего 2 проводами, поэтому проводов меньше, а свободных пинов больше. Поддерживаются ввод дробных чисел и отрицательные числа.

Игра в пинг-понг — SSD1306
Мяч, две ракетки и ты: на маленьком OLED-экране ты играешь в настольный теннис — одну из самых первых видеоигр. Две кнопки двигают твою ракетку справа вверх и вниз, а левой ракеткой управляет компьюте

ESP32 HTTPClient + API погоды (с OLED-дисплеем SSD1306)
В этом проекте ESP32 через HTTPClient.h делает вызов REST API к сервису погоды (wttr.in). В отличие от прошлой версии с I2C LCD, здесь используется OLED SSD1306 (128×64), который позволяет крупные шрифты, векторные значки и богатую картинку на одном экране. Семь векторных значков погоды (солнечно, переменная облачность, облачно, дождь, снег, гроза, туман) рисуются во время работы (растровые файлы не нужны). Температура выводится крупными цифрами.

Часы и календарь на матрице (MAX7219, DS1307)
Светящееся табло для стола или стены, которое показывает время и дату бегущей строкой. На светодиодном дисплее 8x32 крупные цифры часов, а две точки между ними мигают каждую секунду; в начале каждой м

Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Собери на ESP32 регистратор температуры с отметками времени! Каждую минуту читай температуру и влажность с DHT22, бери реальное время из DS1307 RTC и записывай всё на карту microSD в формате CSV. OLED показывает текущую температуру (крупным шрифтом), влажность в процентах, время и счётчик записей. Файл /temp_log.csv на SD-карте открывается в Excel, Google Sheets или Python pandas — идеально для теплиц, комнат, лабораторий и хранения продуктов.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

