RisalDash RisalDash

Гайд · I²C · Отладка

Датчик I²C не определяется? Вот решение — по порядку

Подключил BME280 (или OLED, или MPU6050), прошил скетч, а в ответ — тишина. Плата не видит датчик. В девяти случаях из десяти виновата одна из четырёх вещей, и все они проверяются за минуту, если идти в правильном порядке. Одинаково работает на ESP32, ESP8266 и Arduino.

I²CОтладкаПодтяжкиESP32ESP8266Arduino

Если хочешь понять физику того, что I²C делает на проводе — START, ACK, растягивание такта — смотри интерактивный разбор «один байт — шесть шин». Этот пост — его практическая половина: шина молчит, что дальше?

ESP32 подключён к BME280 и OLED SSD1306 на одной шине I²C — SDA к GPIO21, SCL к GPIO22, общие 3V3 и GND
Исправная шина I²C: BME280 (0x76) и SSD1306 (0x3C) делят одну пару SDA/SCL — разные адреса, два провода. Собрано в BoardLab: протяни пины сам и экспортни PNG.

Шаг 1 — всегда сначала сканируй шину

Никогда не отлаживай вслепую. Каждое устройство I²C отвечает на своём 7-битном адресе, и у шины можно прямо спросить, кто на связи. Прошей это и открой Serial Monitor на 115200:

#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin();               // ESP8266: D2/D1  ·  ESP32: 21/22  ·  Uno: A4/A5
}

void loop() {
  byte found = 0;
  Serial.println("Scanning I2C bus...");
  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {          // 0 = устройство ответило ACK
      Serial.printf("  found device at 0x%02X\n", addr);
      found++;
    }
  }
  Serial.println(found ? "done." : "No devices found — check wiring & pull-ups.");
  delay(3000);
}

Три исхода — три диагноза:

Хочешь сканер на веб-странице, а не через serial-кабель? Пример RisalDash I2C-Scanner выводит каждый адрес с догадкой о чипе, живьём в браузере.

Шаг 2 — подтягивающие резисторы (причина №1 молчащей шины)

Выходы I²C — с открытым стоком: устройство умеет только притягивать линию к нулю. Обратно вверх, к логической единице, её тянут подтягивающие резисторы — один на SDA, один на SCL, к 3V3. Без них линии «болтаются», ничего не читается как высокий уровень, и сканер не находит вообще ничего.

Номинал — это компромисс: меньше сопротивление = чётче фронты, но больше ток; предел по даташиту — ёмкость шины (≤400 пФ), и это подводит нас к следующей ловушке.

Шаг 3 — длинные провода убивают I²C

I²C придумали для микросхем на одной плате — сантиметры, не метры. Каждый лишний сантиметр провода добавляет ёмкость, фронт заваливается, и после ~400 пФ ведущий уже не отличает 1 от 0. Симптом: на столе работает, а стоит протянуть датчик через комнату — начинает сбоить.

Шаг 4 — два датчика, один адрес

Сканер видит устройство, а второй такой же датчик невидим — потому что у них один фиксированный адрес. Два BME280 отвечают на 0x76 и глушат друг друга. Решения:

Всё ещё тишина? Последние подозреваемые

Иди по списку сверху вниз — сканер, подтяжки, длина проводов, адреса, потом мелочи — и мёртвая шина I²C почти всегда оживает за пару минут.

Собери схему со своим датчиком и экспортни картинку — прямо в браузере, без Fritzing.