Урок 9 из 18 · Модуль 3. CAN: физика шины и арбитраж
Протоколы в БАС: полный курс · Урок 9 из 18 · Модуль 3. Шины датчиков: I²C, SPI, CAN
Витая пара с терминаторами: почему CAN переживает десятки метров и горячее подключение устройств, и что такое арбитраж без мастера.
Тест за десять секунд: на обесточенной шине между CAN_H и CAN_L должно быть 60 Ом — два терминатора по 120 Ом в параллель. Показания 120 Ом означают потерю одного терминатора, 40 Ом — лишний терминатор.
Содержание
1. Цели урока
После этого урока вы сможете:
- объяснять, зачем нужны терминаторы и почему именно 120 Ом;
- объяснять, как дифференциальная пара гасит помехи;
- различать доминантный и рецессивный биты и читать диаграмму CAN-сигнала;
- объяснять арбитраж: почему CAN обходится без мастера;
- называть типовые устройства на CAN в БпЛА и диагностировать неисправности шины.
2. Физика шины и арбитраж
CAN (Controller Area Network) разработан компанией Bosch в 1983 году и официально представлен в 1986-м — изначально для автомобильной электроники, где десятки ЭБУ должны обмениваться данными по одной шине в условиях сильных электромагнитных помех от двигателя и зажигания. В мире БпЛА поверх CAN работает протокол DroneCAN (бывший UAVCAN) — открытый стандарт, поддерживаемый ArduPilot и PX4. Встречается на больших коптерах, VTOL, агродронах и аппаратах промышленного класса: по одной витой паре подключают ESC, GPS, датчик воздушной скорости, модуль питания и сервы.
Ключевые особенности CAN, которые делают его незаменимым на крупных БпЛА:
- помехоустойчивая дифференциальная пара — сигнал передаётся не как абсолютное напряжение, а как разность между двумя проводами;
- длина шины до 40 м на скорости 1 Мбит/с, до 1000 м на 50 кбит/с;
- равноправные узлы — нет мастера, любой узел может начать передачу;
- встроенная диагностика ошибок — CRC, подсчёт ошибок, автоматический перевод «сбойного» узла в пассивный режим.
Физика шины: два провода и два резистора
CAN-шина состоит из двух проводов — CAN_H (High) и CAN_L (Low) — и двух терминирующих резисторов по 120 Ом, установленных на каждом конце шины.
Зачем витая пара. Провода CAN_H и CAN_L скручены вместе. Любая внешняя помеха (от электродвигателей, силовых проводов, радиопередатчика) наводит одинаковое напряжение на оба провода одновременно. Приёмник CAN смотрит не на абсолютный уровень каждого провода, а на разность CAN_H − CAN_L. Помеха, одинаково добавленная к обоим проводам, в разности исчезает — это и есть принцип дифференциальной передачи.
Зачем терминаторы по 120 Ом. Шина — это длинная линия передачи. Если её конец «не нагружен», электромагнитная волна отражается обратно и создаёт помехи, искажающие сигнал. Терминирующий резистор поглощает волну: его сопротивление подобрано равным волновому сопротивлению витой пары (~120 Ом). Ставят два резистора — по одному на каждом конце шины.
Почему 60 Ом при измерении. Два резистора по 120 Ом включены параллельно относительно точек CAN_H и CAN_L:

Доминантный и рецессивный бит
В CAN существует два логических состояния шины — рецессивное (recessive) и доминантное (dominant). Это ключевое понятие: именно на нём строится и арбитраж, и диагностика ошибок.
| Состояние | Логика | CAN_H | CAN_L | Разность CAN_H − CAN_L | Кто формирует |
|---|---|---|---|---|---|
| Рецессивное | 1 | ~2,5 В | ~2,5 В | ~0 В | никто не «тянет» шину — оба провода подтянуты терминаторами к 2,5 В |
| Доминантное | 0 | ~3,5 В | ~1,5 В | ~2 В | передатчик активно «раздвигает» провода: CAN_H тянет вверх, CAN_L — вниз |
Важнейшее свойство: если хотя бы один узел на шине выставляет доминантный бит, шина переходит в доминантное состояние — независимо от того, что выставляют остальные узлы. Рецессивный бит «подавляется» доминантным. Это называется «монтажное И» (wired-AND) — точно так же, как open-drain в I²C.
Как читать диаграмму CAN-сигнала. На осциллограмме всегда показывают три линии: CAN_H, CAN_L и их разность (дифференциальный сигнал). Приёмник смотрит только на разность. Запомните главное: при доминантном бите шина «раздвигается» — CAN_H идёт вверх, CAN_L вниз. При рецессивном — оба провода стоят на одном уровне 2,5 В.

Как помеха от мотора исчезает в разности. Предположим, помеха добавляет +0,5 В к обоим проводам в момент доминантного бита:

Приёмник читает только разность — поэтому CAN работает в сантиметрах от силовых проводов и моторов, где одиночный провод PWM уже даёт сбои.
Структура кадра CAN
Каждое сообщение на шине передаётся в виде кадра данных (Data Frame). Кадр состоит из нескольких полей; техник должен понимать назначение каждого — особенно при работе с логическим анализатором.

| Поле | Размер | Назначение |
|---|---|---|
| SOF (Start of Frame) | 1 бит | всегда доминантный бит (0) — сигнализирует всем узлам о начале кадра; одновременно синхронизирует тактовые генераторы узлов |
| ID (Identifier) | 11 бит (CAN 2.0A) 29 бит (CAN 2.0B Extended) |
идентификатор сообщения. Чем меньше число — тем выше приоритет. В DroneCAN ID кодирует тип данных и адрес узла |
| RTR (Remote Transmission Request) | 1 бит | 0 — кадр данных (передаём данные); 1 — запрос на передачу (просим другой узел прислать данные). В DroneCAN RTR не используется |
| IDE (Identifier Extension) | 1 бит | 0 — стандартный 11-битный ID; 1 — расширенный 29-битный ID (CAN 2.0B) |
| DLC (Data Length Code) | 4 бита | количество байт данных в кадре: от 0 до 8 |
| DATA | 0–8 байт | полезные данные: показания датчика, команда ESC, телеметрия GPS и т.д. |
| CRC | 15 бит + 1 делимитер | контрольная сумма. Все узлы независимо считают CRC принятого кадра и сравнивают с переданным — ошибки данных обнаруживаются автоматически |
| ACK | 1 бит + 1 делимитер | подтверждение. Передатчик выставляет рецессивный бит (1); любой принявший кадр без ошибок узел перебивает его доминантным (0). Если ACK остался рецессивным — никто не принял кадр |
| EOF (End of Frame) | 7 бит | семь рецессивных бит — признак конца кадра; после этого шина считается свободной |
Пример реального кадра в логическом анализаторе (DroneCAN, ESC-телеметрия, ID = 0x110):

Арбитраж — почему все узлы равны
У CAN нет мастера: любой узел может начать передачу, когда шина свободна. «Свободная шина» — это когда на обоих проводах рецессивный уровень (разность ≈ 0 В). Если два узла начали передачу одновременно, включается арбитраж без разрушения кадра.
Принцип арбитража. Каждый передающий узел одновременно читает шину и сравнивает то, что выставил, с тем, что видит. Если узел выставил рецессивный бит (1), но шина показывает доминантный (0) — значит, другой узел передаёт доминантный бит и имеет более высокий приоритет. «Проигравший» узел немедленно замолкает и ждёт следующей свободной шины. «Победитель» продолжает передачу, даже не зная о конфликте.
Рассмотрим пример: GPS-модуль (ID = 0x100) и ESC (ID = 0x110) начали передачу одновременно:

Почему выигрывает меньший ID. Доминантный бит (0) всегда «перебивает» рецессивный (1). Меньший числовой ID содержит больше нулей в старших битах — именно там происходит разрешение конфликта. Поэтому ID 0x000 имеет наивысший приоритет, ID 0x7FF — наименьший.
Вся процедура арбитража занимает несколько микросекунд, происходит на уровне железа (CAN-контроллер в микросхеме) и не требует участия программного обеспечения. Именно поэтому CAN устойчив к «горячему» подключению устройств и работе большого числа узлов на одной шине.
DroneCAN в БпЛА
DroneCAN — прикладной протокол поверх CAN. Каждый узел получает Node ID — уникальный адрес от 1 до 127. Node ID назначается либо вручную (через параметры ArduPilot/PX4), либо автоматически (dynamic node ID allocation). Полётный контроллер при этом является одним из узлов на равных правах — не «мастером» шины.
| Устройство | Примеры | Что передаёт по CAN |
|---|---|---|
| ESC / регуляторы | Zubax Myxa, Flame, Kotleta20, T-Motor Flame, VESC с CAN | команды газа (от ФК), обратно — RPM, ток, напряжение, температура |
| GPS / GNSS | Zubax GNSS 2, Holybro DroneCAN M9N, Here3 | координаты, скорость, время, HDOP; компас — по тому же CAN-кабелю |
| Датчик воздушной скорости | Matek ASPD-4525, Zubax Airspeed | дифференциальное давление → воздушная скорость |
| Модуль питания / мониторинг АКБ | Zubax Babel, CUAV CAN PMU | напряжение, ток, заряд батареи, состояние ячеек |
| Сервоприводы | Himark CAN servo, Volz DA 22 | команды положения (от ФК), обратно — фактическое положение, нагрузка |
| Световое оборудование | DroneCAN LED-модули | команды цвета и яркости навигационных огней |
Почему CAN, а не PWM/UART для ESC на большом дроне:
- обратная связь — ESC сообщает реальные RPM, ток и температуру каждого мотора; при PWM полётный контроллер «слепой»;
- один кабель на все ESC — витая пара CAN_H/CAN_L проходит через весь аппарат вместо пучка PWM-проводов к каждому регулятору;
- диагностика отказов — если ESC перестал отвечать на шине, ФК немедленно это видит и может среагировать;
- помехоустойчивость — рядом с силовыми проводами дифференциальная пара значительно надёжнее одиночных сигнальных линий PWM.
Типовые неисправности и диагностика
| Симптом | Вероятная причина | Способ диагностики и устранения |
|---|---|---|
| Ни один CAN-узел не обнаруживается в ФК | оба терминатора отсутствуют или обрыв шины | замерить сопротивление CAN_H–CAN_L при отключённом питании: должно быть 60 Ом; проверить целостность CAN_H и CAN_L мультиметром |
| Узлы обнаруживаются, но периодически пропадают | один терминатор отсутствует (120 Ом вместо 60 Ом), длинная шина, плохой контакт | проверить наличие обоих терминаторов на концах шины; укоротить или переобжать кабель; проверить качество разъёмов |
| Шина «перегружена» (bus-off у узла) | неисправный узел генерирует ошибки; лишний терминатор; CAN_H и CAN_L перепутаны | замерить сопротивление (40 Ом — лишний терминатор); отключать узлы по одному до исчезновения ошибок; проверить полярность CAN_H/CAN_L |
| Конфликт Node ID | двум устройствам назначен одинаковый Node ID | в ArduPilot: Mission Planner → UAVCAN → просмотр узлов; назначить уникальные ID каждому устройству |
| ESC не реагирует на команды | не настроен Node ID ESC; неверная маска ESC в параметрах ФК | проверить параметр CAN_D1_UC_ESC_BM (маска ESC) и Node ID в конфигураторе ESC |
| GPS виден на шине, но данные не поступают в ФК | неверный тип GPS в параметрах | установить GPS_TYPE = 9 (DroneCAN) в ArduPilot; проверить Node ID GPS-модуля |
💻 Для программиста
В отличие от I²C и SPI, CAN-контроллер не работает в режиме «байт за байтом» — он оперирует готовыми кадрами. Прикладной код помещает данные в структуру кадра (ID + DLC + данные), передаёт её CAN-периферии микроконтроллера, а та самостоятельно проводит арбитраж, считает CRC и добавляет ACK. При работе с DroneCAN используют библиотеку libcanard (C99, минимальный footprint) или pyuavcan (Python, для наземных инструментов). Для диагностики шины на ПК удобен адаптер SLCAN (Serial-Line CAN) — недорогой USB-CAN переходник, работающий с can-utils в Linux или с DroneCAN GUI Tool.
3. Чек-лист самопроверки
Урок освоен, если каждый пункт выполнен на практике:
- Замерил 60 Ом на обесточенной исправной шине мультиметром
- Могу объяснить, почему помеха от мотора не влияет на дифференциальный сигнал CAN
- Объясняю разницу между доминантным и рецессивным битом и почему доминантный «побеждает»
- Понимаю, почему при конфликте выигрывает кадр с меньшим ID
- Знаю, какие устройства на борту крупного БпЛА подключаются по CAN и зачем
4. Что дальше
- Предыдущий урок: Урок 8. SPI: скоростной конвейер
- Следующий урок: Урок 10. DroneCAN на практике: устройства и настройка в ArduPilot
- Полный перечень тем — в статье «Содержание курса».
