Перейти к содержимому

Урок 7 из 18 · Модуль 3. I²C: шина датчиков

23 августа 2026
Пилоту БПЛА | Технику БПЛА | Хобби | Разработчику

Протоколы в БАС: полный курс · Урок 7 из 18 · Модуль 3. Шины датчиков: I²C, SPI, CAN

Всего два сигнальных проводника на всю шину: подтягивающие резисторы, адресация, подтверждения. Компасы, барометры, OLED-дисплеи и лидары — их типовые неисправности.

Без подтягивающих резисторов шина I²C не работает, а два устройства с одинаковым адресом не могут работать одновременно. Типичный случай: после подключения второго однотипного GPS/GNSS-модуля со встроенным компасом оба компаса перестают работать.

Содержание

1. Цели урока

После этого урока вы сможете:

  • объяснить устройство шины I²C: линии SDA и SCL, подтягивающие резисторы, 7-битная адресация;
  • описать полный цикл обмена: условие «старт», кадр адреса, байты данных с подтверждениями, условие «стоп»;
  • назвать адреса типовых микросхем: 0x76 — барометр, 0x0D — компас QMC5883L;
  • диагностировать зависание шины и конфликты адресов.
↑ К оглавлению

2. Шина I²C

I²C (произносится «ай-скве́рд-си», от англ. Inter-Integrated Circuit) — шина, разработанная компанией Philips (ныне — NXP Semiconductors) для обмена данными между микросхемами в пределах одной печатной платы. В БпЛА она применяется там, где скорость передачи не критична, а важна простота подключения: барометры, внешние компасы (магнитометры), компактные OLED-дисплеи, лазерные дальномеры, датчики тока и напряжения. Для обмена достаточно двух сигнальных линий: SDA (данные) и SCL (тактирование); дополнительно требуются общий провод (GND) и питание.

Как устроена шина

i2c_master_slave_style01_353d3.png

Ключевая особенность I²C: обе линии выполнены по схеме с открытым стоком или открытым коллектором (open-drain / open-collector). Устройства могут только притягивать линию к логическому нулю; высокий уровень создаётся подтягивающим резистором, соединённым с шиной питания. Благодаря этому:

  • шину могут одновременно использовать несколько устройств — это не вызывает короткого замыкания. У обычного двухтактного выхода (push-pull) активны оба уровня: если бы два таких устройства одновременно подали на одну линию «единицу» и «ноль», между ними возник бы ток короткого замыкания. Выход I²C устроен иначе: микросхема может только притянуть линию к нулю или «отпустить» её; «единицу» формирует подтягивающий резистор, который заодно ограничивает ток до безопасного значения. Поэтому конфликт передатчиков электрически безопасен (такое соединение называют «монтажным И», wired-AND);
  • подтверждение приёма передаётся по уже имеющейся линии SDA, без дополнительных проводов. Каждый байт занимает девять тактовых импульсов: восемь — биты данных, девятый — подтверждение. К девятому такту передатчик освобождает линию, а приёмник, получивший байт, притягивает SDA к низкому уровню — это и есть сигнал «байт принят». Передатчик проверяет линию в девятом такте: низкий уровень — подтверждение есть (ACK), высокий — подтверждения нет (NACK), то есть устройство не отвечает или завершает обмен.

Схема подключения

Внимание: Без подтягивающих резисторов шина I²C не работает. На готовых модулях и платах полётных контроллеров (FC) резисторы уже установлены — не добавляйте параллельные без необходимости: суммарное сопротивление уменьшится, ток через выходы микросхем превысит допустимый, и устройства не смогут уверенно притягивать линии к низкому уровню. Дополнительные подтягивающие резисторы требуются только на протяжённых линиях (длиной в несколько метров); их номинал подбирается так, чтобы суммарное сопротивление оставалось в пределах, рекомендованных производителем микросхемы.

Как проходит обмен по I²C

Обменом на шине управляет ведущее устройство (master). Шина I²C допускает несколько ведущих (multi-master), однако в каждый момент времени конкретную транзакцию ведёт ровно одно из них. В БпЛА ведущим обычно выступает полётный контроллер; барометр, компас, OLED-дисплей и дальномер — ведомые (slave): они передают данные только после обращения к ним по адресу. Вся передача состоит из транзакций: ведущее устройство формирует условие «старт», передаёт кадр адреса, обменивается байтами данных и завершает обмен условием «стоп».

Чтобы понимать обмен и осциллограммы I²C, достаточно трёх правил:

  • такты формирует ведущее устройство. Каждый бит передаётся ровно за один тактовый импульс на линии SCL;
  • линию SDA разрешено менять только при низком уровне SCL. Пока SCL высокий, уровень на SDA остаётся стабильным — именно в этот момент приёмник считывает очередной бит;
  • каждый байт подтверждается девятым тактом: ACK — «байт принят», NACK — «не принят» либо «данных больше не требуется».

Условия «старт» и «стоп» — единственные события, которым позволено нарушать второе правило, поэтому приёмник распознаёт их однозначно:

  • условие СТАРТ (S) — SDA переходит из высокого уровня в низкий, пока SCL высокий;
  • условие СТОП (P) — SDA переходит из низкого уровня в высокий, пока SCL высокий; после этого шина считается свободной.

Транзакция по шагам:

  1. Ведущее устройство формирует условие «старт».
  2. Передаёт кадр адреса: 7 бит адреса ведомого устройства и бит направления — 0 («запись») или 1 («чтение»).
  3. Все ведомые устройства слушают шину; то, чей адрес совпал, отвечает ACK. Остальные в обмене не участвуют.
  4. Передаются байты данных: номера регистров, команды настройки либо измеренные значения. Каждый байт завершается тактом подтверждения.
  5. При чтении ведущее устройство подтверждает каждый принятый байт (ACK), но последний — не подтверждает (NACK): так ведомое устройство понимает, что данные больше не требуются.
  6. Ведущее устройство формирует условие «стоп» — транзакция завершена.

 

Реальный пример — полётный контроллер читает измерения барометра BMP280 (адрес 0x76). Датчик хранит результаты в регистрах, начиная с 0xF7, поэтому транзакция выглядит так:

  1. условие «старт»;
  2. байт 0xEC — адрес 0x76 с битом «запись»; барометр отвечает ACK;
  3. байт 0xF7 — «данные будешь передавать с этого регистра»; ACK;
  4. повторный старт (repeated START) — смена направления на чтение без освобождения шины;
  5. байт 0xED — тот же адрес 0x76 с битом «чтение»; ACK;
  6. барометр выдаёт байты результата; ведущее устройство отвечает ACK на каждый, последний — NACK;
  7. условие «стоп».

 

Ниже — ASCII-осциллограмма той же транзакции по фазам. Для примера предположим, что барометр возвращает два байта: 0x5A и 0x3C.

Как читать диаграммы: HIGH (логическая единица) — линия вверху; LOW (логический ноль) — линия внизу. Бит считывается в момент, когда SCL HIGH (фронт). Если несколько подряд идущих битов одинаковы — SDA не меняет уровень, перехода нет.

Фаза 1 — START + адрес 0xEC (запись) + ACK (обращение мастера к барометру по его адресу)

0xEC = 1 1 1 0 1 1 0 0. Перед стартом обе линии подтянуты к HIGH. START: SDA падает, пока SCL ещё HIGH. Затем мастер тактирует 8 бит + 9-й такт для ACK.

              S   b7  b6  b5  b4  b3  b2  b1  b0  ACK
                   1   1   1   0   1   1   0   0   0
                 ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐
SCL ─────────┐   │  ││  ││  ││  ││  ││  ││  ││  ││  │
             └───┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └──
                 ▲
SDA ─────┐   ┌──────────────┐   ┌───────┐
         └───┘   1   1   1  └─0─┘  1  1 └──0───0───0──
           ▲                                       ▲
        START:                                 ACK от
        SDA↓ при                              барометра
        SCL=HIGH

Мастер выдал 0xEC — это 0x76 << 1 | 0 (запись). Барометр узнал свой адрес и прижал SDA к LOW на 9-м такте → ACK. Два «горба» HIGH на SDA соответствуют двум группам единиц в 0xEC: 1 1 1 0 1 1 0 0.

Фаза 2 — байт данных 0xF7 (адрес регистра) + ACK (запрос данных из конкретного регистра)

0xF7 = 1 1 1 1 0 1 1 1

              b7  b6  b5  b4  b3  b2  b1  b0  ACK
               1   1   1   1   0   1   1   1   0
             ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐
SCL ─────────┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └──

SDA ────────────────────────┐   ┌───────────┐
             1   1   1   1  └─0─┘  1  1  1  └──0──
                                               ▲
                                           ACK от
                                          барометра

Мастер сказал барометру: «выдавай данные, начиная с регистра 0xF7». Барометр ответил ACK. Два «горба» HIGH: 1 1 1 1 0 1 1 1.

Фаза 3 — Repeated START + адрес 0xED (чтение) + ACK

0xED = 1 1 1 0 1 1 0 1. Мастер не отпускает шину (нет STOP), а формирует ещё один START — repeated START (Sr). Адрес тот же 0x76, но младший бит теперь 10xED (чтение).

              Sr  b7  b6  b5  b4  b3  b2  b1  b0  ACK
                  1   1   1   0   1   1   0   1   0
         ┌───┐   ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐
SCL ─────┘   │   │  ││  ││  ││  ││  ││  ││  ││  ││  │
             └───┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └──
        ▲  ▲
        │  └── SDA падает при SCL=HIGH → Sr (repeated START)
        │
       SDA сначала отпущена в HIGH

SDA ─────    ┌──────────────┐   ┌───────┐   ┌─┐
(данные) └───┘    1   1   1 └─0─┘ 1   1 └─0─┘1└──0──
                                                   ▲
                                               ACK от
                                              барометра

Три HIGH: 1 1 1 0 1 1 0 1. Барометр снова ответил ACK и готов выдавать данные.

Фаза 4 — барометр выдаёт первый байт данных (0x5A) + мастер отвечает ACK

0x5A = 0 1 0 1 1 0 1 0. Теперь каналом SDA управляет барометр, а мастер только тактирует SCL и подтверждает. Обратите внимание: биты b4 и b3 — обе единицы, поэтому SDA остаётся HIGH два такта подряд (один широкий «импульс», перехода внутри нет).

              b7  b6  b5  b4  b3  b2  b1  b0  ACK
               0   1   0   1   1   0   1   0   0
             ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐
SCL ─────────┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └──

SDA ────────┐   ┌───┐   ┌───────┐   ┌───┐
            └───┘   └───┘       └───┘   └──────────
               0   1   0   1   1   0   1   0   0
               b7  b6 b5   b4  b3  b2  b1  b0  ACK
                      ▲                        ▲
                 SDA остаётся HIGH            ACK от
                  два такта подряд           мастера
                  (b4+b3=1,1)              «давай ещё»

Три HIGH на SDA — ровно три группы единиц в 0x5A: 0 1 0 1 1 0 1 0

Фаза 5 — второй (последний) байт данных (0x3C) + NACK + STOP

0x3C = 0 0 1 1 1 1 0 0. Мастер знает, что этот байт последний, поэтому на 9-м такте не подтверждает (NACK = SDA HIGH). Затем формирует STOP: притягивает SDA к LOW (пока SCL ещё низкий), отпускает SCL, а затем отпускает SDA — переход LOW→HIGH при SCL = HIGH.

              b7  b6  b5  b4  b3  b2  b1  b0 NACK    P
               0   0   1   1   1   1   0   0   1
             ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐  ┌─────
SCL ─────────┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └┘  └──┘

                    ┌───────────────┐       ┌───┐  ┌──────
SDA ────────────────┘               └───────┘   └──┘
              0    0   1   1   1   1   0   0   1     ▲
              b7   b6  b5  b4  b3  b2  b1  b0        │
▲  │                                           NACK │ STOP: (SDA │ SDA↑ при HIGH)│ SCL=HIGH │ «хватит, данных не надо»

Один широкий HIGH (четыре такта подряд, b5–b2): 0 0 1 1 1 1 0 0. После NACK мастер кратковременно притягивает SDA к LOW и затем отпускает — этот переход LOW→HIGH при SCL = HIGH и есть условие STOP.

Вся транзакция одной строкой — так она выглядит в окне логического анализатора:

┌─────────┬─────────────┬───────────────┬────────┬─────────────┬───────────────┬────────────────┬──────┐
│  START  │  0xEC (W)   │  0xF7 (reg)   │   Sr   │  0xED (R)   │  0x5A + ACK   │  0x3C + NACK   │ STOP │
│         │  ACK        │  ACK          │        │  ACK        │  (мастер)     │  (мастер)      │      │
└─────────┴─────────────┴───────────────┴────────┴─────────────┴───────────────┴────────────────┴──────┘
  мастер     мастер →       мастер →      мастер    мастер →      ← барометр     ← барометр     мастер
             барометру      барометру               барометру     мастеру        мастеру
             «я к тебе,     «начни с                «теперь       «вот первый    «вот второй
              пишу»         регистра                читаю»         байт»          байт»
                            0xF7»

Соответствие полей в декодере логического анализатора (Saleae Logic, PulseView):

Поле в декодереЗначениеПояснение
Address 0x76 7-битный адрес барометра
Write 0xEC 0x76 << 1 | 0
Data (W) 0xF7 адрес начального регистра
Repeated Start Sr смена направления без освобождения шины
Read 0xED 0x76 << 1 | 1
Data (R) 0x5A 0x3C … байты из регистров датчика
NACK на последнем байте мастер завершает чтение
Stop P шина свободна
Обратите внимание: в кадре адреса 7-битный адрес сдвигается влево, а самый младший бит занимает признак направления (R/W). Поэтому сканер адресов показывает 0x76, а логический анализатор — байты 0xEC (запись) и 0xED (чтение). Это одна и та же микросхема: 0x76 — её адрес, 0xEC и 0xED — готовые кадры обращения к ней.

Две тонкости, о которых полезно знать:

  • повторный старт (repeated START) — новое условие «старт» без предварительного «стопа». Нужен, когда в одной транзакции требуется сначала записать (выбрать регистр), а затем прочитать (получить данные). Большинство датчиков, включая BMP280, обычно используют именно такой порядок (хотя по техническому описанию BMP280 допускает и промежуточный «стоп»);
  • растяжение такта (clock stretching) — медленное ведомое устройство вправе удерживать SCL в низком уровне, и ведущее устройство обязано ждать. Если на осциллограмме SCL «залип» в нуле — это не обязательно неисправность. В большинстве распространённых датчиков для БпЛА clock stretching не используется, но по протоколу он возможен.

Скорости и адреса

Стандартные режимы: 100 кбит/с (standard), 400 кбит/с (fast — типовой режим для БпЛА), 1 Мбит/с (fast+). Для сравнения: UART на скорости 115200 бод обеспечивает около 11,5 Кбайт/с полезных данных, I²C на 400 кГц — до ~40 Кбайт/с. Адреса типовых микросхем, которые необходимо знать наизусть:

МикросхемаНазначениеАдрес (7-битный)
BMP280 / BMP388 / SPL06 / DPS310 барометр 0x76 или 0x77 (выбирается перемычкой)
QMC5883L компас (в модулях Matek M8Q-5883 и др.) 0x0D
HMC5883L компас (устаревший, встречается в недорогих модулях) 0x1E
IST8310 компас (типовой внешний компас в экосистеме ArduPilot) 0x0E
SSD1306 OLED-дисплей 0,96″ 0x3C (иногда 0x3D)
VL53L0X / VL53L1X лазерный дальномер 0x29
INA226 / INA228 датчик тока и напряжения 0x40–0x4F (назначается конфигурацией)
Совет техника: Два устройства с одинаковым адресом на одной шине не могут работать одновременно — между ними возникает конфликт. Типичный случай: после подключения второго однотипного GPS/GNSS-модуля со встроенным компасом оба компаса перестают работать. У ряда микросхем адрес изменяется перемычкой (например, 0x76↔0x77 у барометров) — см. техническое описание (datasheet) конкретной микросхемы.

Где I²C встречается в БпЛА

  • Барометр на плате полётного контроллера — исторически подключался почти всегда по I²C; в настоящее время производители всё чаще применяют SPI.
  • Внешний компас — GPS/GNSS-модули со встроенным компасом (Matek M8Q-5883, Holybro M9N/M10): по UART передаются координаты, по I²C — данные магнитометра. На самолетах и крупных мультироторных БпЛА компас выносят на максимальное удаление от силовых проводов — на штангу или в хвостовую часть — и подключают именно по I²C.
  • OLED-дисплеи — на самодельных аппаратах и самолетах: компактный экран отображает режим полёта, напряжение аккумуляторной батареи, уровень принимаемого сигнала (RSSI).
  • Лидары для автоматической точной посадки — модули на VL53L0X и другие; лидары серии TFmini чаще применяются в исполнении с интерфейсом UART.
  • Цифровые датчики тока и напряжения (INA226/INA228) — в самодельных индикаторах состояния аккумуляторной батареи и в отдельных системах контроля аккумуляторов (BMS).
i2c_compass_4eb5b.png

Классический модуль I²C: компас GY-273 на микросхеме QMC5883L. Четыре контакта: VCC, GND, SCL, SDA. Именно такие компасы (или компасы, встроенные в GPS/GNSS-модули) подключают к шине I²C полётного контроллера. После установки на борт обязательна калибровка: без неё показания компаса недостоверны и представляют опасность в полёте.

Типовые неисправности I²C и способы устранения

СимптомВероятная причинаСпособ устранения
Устройство не обнаруживается (сканер адресов не находит устройств) отсутствуют подтягивающие резисторы, обрыв SDA/SCL, отсутствует питание проверить +3,3 В на линиях в состоянии покоя, проверить целостность проводников
Устройство обнаруживается, но периодически пропадает длинные провода, паразитная ёмкость линии, помехи от электродвигателей укоротить провода, сформировать витую пару из SDA и GND, снизить скорость до 100 кГц
Шина «зависла»: SDA удерживается на низком уровне ведомое устройство прервало транзакцию и удерживает линию восстановить шину: сформировать девять тактовых импульсов на SCL (стандартный алгоритм ведущего устройства), перезагрузить полётный контроллер
Два однотипных устройства конфликтуют совпали адреса изменить адрес перемычкой или прошивкой либо установить разные модели
Компас выдаёт недостоверные (хаотичные) показания электромагнитные наводки от силовых проводов, не выполнена калибровка вынести компас на большее удаление от силовых проводов, перевить провода, выполнить калибровку

💻 Для программиста

Первое программное средство, которое разрабатывают для работы с I²C, — сканер адресов. Он перебирает все возможные адреса и по наличию ACK в кадре адреса определяет, какие устройства реально подключены к шине (см. раздел «Как проходит обмен по I²C»). На платформе Arduino он занимает около двадцати строк и незаменим при диагностике:

#include <Wire.h>
void setup() {
  Wire.begin();
  Serial.begin(115200);
  for (byte a = 8; a < 120; a++) {
    Wire.beginTransmission(a);
    if (Wire.endTransmission() == 0) {
      Serial.print("Найден: 0x");
      Serial.println(a, HEX);
    }
  }
}
void loop() {}

В прошивках полётных контроллеров драйвер I²C реализован с защитой от сбоев: Betaflight и ArduPilot автоматически восстанавливают работу зависшей шины и повторно опрашивают устройства. Поэтому при нестабильной работе барометра или компаса первое действие — перезагрузка полётного контроллера, второе — проверка целостности соединений.

↑ К оглавлению

3. Чек-лист самопроверки

Урок освоен, если каждый пункт выполнен на практике:

  • Сканер адресов обнаруживает все подключённые устройства
  • Понятно назначение подтягивающих резисторов и причина, по которой их не следует дублировать
  • Понятно, почему внешний компас выносят на удаление от силовых проводов
Результат: все пункты выполнены — переходите к следующему уроку.
↑ К оглавлению

4. Что дальше

  • Предыдущий урок: Урок 6. UART: диагностика и логический анализатор
  • Следующий урок: Урок 8. SPI: скоростной конвейер
  • Полный перечень тем — в статье «Содержание курса».
↑ К оглавлению
11