Протоколы обмена данными
Когда Arduino общается с дисплеем, датчиком или модулем связи, одного провода «данные» недостаточно. Устройства должны одинаково понимать, где начинается сообщение, с какой скоростью идут биты, кто имеет право отвечать и как выбирается нужный адресат. Эти правила образуют протокол обмена.

UART обычно соединяет два устройства перекрёстными линиями TX и RX. I2C объединяет несколько устройств общей парой SDA и SCL с подтягивающими резисторами и адресами. SPI использует общие линии такта и данных, а для выбора каждого периферийного устройства — отдельный CS.
Зачем это нужно
На столе три модуля могут выглядеть похоже: питание, земля и несколько сигнальных контактов. Но неверно выбранный интерфейс не исправить другой библиотекой. UART-модулю нужен согласованный формат последовательных кадров, I2C-датчику — адрес и подтяжки, SPI-памяти — тактовая линия, режим и собственный сигнал выбора.
Знание протоколов помогает:
- прочитать распиновку и не смешать питание с данными;
- заранее оценить, сколько контактов Arduino потребуется;
- соединить несколько датчиков без конфликта адресов;
- выбрать подходящую скорость и логические уровни;
- локализовать ошибку между проводкой, транспортом и форматом команды;
- объяснить, почему код «не видит» физически подключённый модуль.
Главная идея
Протокол — договор между участниками обмена. Он включает несколько уровней:
электрические уровни -> линии и синхронизация -> байты -> команды устройства
Совпадение разъёма не гарантирует совпадение всех уровней. Например, два устройства могут иметь контакты TX и RX, но работать с разным напряжением или скоростью. I2C-дисплей может отвечать по адресу, однако требовать библиотеку для другого контроллера экрана.

Сравнение UART, I2C и SPI
| Свойство | UART | I2C | SPI |
|---|---|---|---|
| Основные сигналы | TX, RX | SDA, SCL | SCK, COPI, CIPO, CS |
| Синхронизация | асинхронная, участники заранее задают скорость | такт передаёт контроллер по SCL | такт передаёт контроллер по SCK |
| Несколько устройств | обычно отдельное соединение или дополнительный протокол поверх UART | общая шина, выбор по адресу | общие такт/данные и отдельный CS для каждого устройства |
| Направление данных | отдельная передача и приём | двунаправленная линия SDA | обычно отдельные линии в обе стороны |
| Дополнительные элементы | общая земля, иногда преобразование уровней | подтяжки SDA и SCL, общая земля | отдельные CS, общая земля |
| Типичный учебный пример | GPS или UART-радиомодуль | несколько датчиков и дисплей | память, быстрый АЦП, графический дисплей |
Скорость нельзя выбирать только по названию интерфейса. Её ограничивают контроллер Arduino, конкретное устройство, длина и качество соединений, ёмкость шины и электрическая схема.
UART: два независимых направления
UART передаёт биты без отдельной линии такта. Передатчик и приёмник заранее настраивают одинаковую скорость и формат кадра. В простом соединении нужны:
TX устройства A -> RX устройства B
RX устройства A <- TX устройства B
GND устройства A --- GND устройства B
TX соединяют с противоположным RX, а не с одноимённым контактом. Если обмен нужен только в одну сторону, одна сигнальная линия может отсутствовать, но общий провод всё равно нужен.
| Параметр UART | Почему должен совпасть |
|---|---|
| скорость в бодах | приёмник определяет границы битов по времени |
| число битов данных | задаёт размер полезной части кадра |
| контроль чётности | меняет наличие и смысл проверочного бита |
| стоповые биты | определяют конец кадра |
| логические уровни | слишком высокое напряжение может повредить вход |
Arduino Serial скрывает формирование кадров, но не угадывает настройки второго устройства. Значение Serial.begin(9600) должно соответствовать настройке партнёра. Термин «UART» также не означает классические уровни интерфейса RS-232: у RS-232 другие электрические уровни, и его нельзя подключать напрямую к GPIO без преобразователя.
I2C: общая адресная шина
В I2C контроллер формирует такт SCL, а данные передаются по SDA. Обе линии обычно имеют выходы с открытым стоком: участники могут тянуть линию вниз, а высокий уровень создают подтягивающие резисторы.
Несколько устройств подключают параллельно:
SDA контроллера --- SDA всех устройств
SCL контроллера --- SCL всех устройств
GND контроллера --- GND всех устройств
У каждого периферийного устройства есть адрес. Контроллер начинает транзакцию с адреса, и отвечает только выбранный участник. Адрес может быть фиксированным, изменяться контактами конфигурации или задаваться программно. Два одинаковых датчика с одним неизменяемым адресом конфликтуют: они отвечают одновременно. Тогда нужен адресный переключатель, мультиплексор или другой экземпляр устройства.
Документация может приводить 7-битный адрес либо байт адреса с уже добавленным битом чтения/записи. Arduino Wire обычно принимает 7-битное значение. Формат нужно проверить в datasheet, а не исправлять случайным сдвигом до появления ответа.
Номиналы подтяжек зависят от напряжения, ёмкости, скорости и уже установленных резисторов на модулях. Если каждый breakout добавляет свою пару, итоговое параллельное сопротивление может стать слишком малым. Линии нельзя подтягивать к напряжению, небезопасному для входов контроллера или периферии.
SPI: скорость и отдельный выбор устройства
В типичном четырёхпроводном SPI контроллер использует:
SCK— тактовый сигнал;COPI— данные от контроллера к периферии; в старых datasheet часто используется названиеMOSI;CIPO— данные от периферии к контроллеру; старое распространённое название —MISO;CSилиSS— выбор конкретного устройства.
SCK, COPI и CIPO можно разделить между несколькими устройствами, но каждому обычно выделяют отдельный CS. Неактивное устройство должно освободить линию CIPO. Если два CS активны одновременно, ответы могут конфликтовать. При чтении старой документации сопоставляйте COPI с MOSI, а CIPO — с MISO.
| Настройка SPI | Что случится при ошибке |
|---|---|
частота SCK | устройство пропускает биты или не отвечает |
| порядок битов | байты интерпретируются зеркально по разрядам |
режим CPOL/CPHA | данные считываются на неверном фронте такта |
активный уровень CS | периферия не выбирается либо остаётся выбранной |
Библиотека SPI предлагает транзакции с настройками. Драйвер устройства должен активировать нужный CS, выполнить обмен и вернуть линию в неактивное состояние. Не следует вручную менять режим общей шины посреди чужой транзакции.
Инициализация интерфейсов в Arduino
Этот скетч показывает только запуск трёх аппаратных API и периодическую отправку диагностического байта в USB/Serial. Он не делает подключённые устройства взаимозаменяемыми.
#include <Wire.h>
#include <SPI.h>
unsigned long lastReport = 0;
void setup() {
Serial.begin(115200);
Wire.begin();
SPI.begin();
}
void loop() {
const unsigned long now = millis();
if (now - lastReport >= 1000) {
lastReport = now;
Serial.println("controller running");
}
}
Wire.begin() настраивает плату как I2C-контроллер в обычном учебном сценарии. SPI.begin() запускает аппаратный SPI-блок. Для реального устройства затем нужны его адрес, регистры, команды и параметры из документации.
Точные аппаратные пины интерфейсов зависят от платы. На некоторых Arduino они продублированы на отдельном разъёме, на других назначаются периферийной матрицей. Проверяйте pinout выбранной платы.
Как выбрать протокол для узла робота
Начинают не с любимой библиотеки, а с документации периферии. Если модуль поддерживает несколько интерфейсов, оценивают:
- требуемую скорость и объём данных;
- число свободных пинов;
- количество устройств на шине;
- длину проводов и уровень помех;
- доступность аппаратного блока на плате;
- поддержку библиотекой и необходимость разделять ресурс.
| Узел робота | Разумный кандидат | Что проверить |
|---|---|---|
| конфигурационный радиомодуль | UART | уровни, скорость, формат команд |
| набор медленных датчиков на одной плате | I2C | адреса, подтяжки, ёмкость шины |
| быстрый дисплей или память рядом с контроллером | SPI | режим, максимальный SCK, отдельный CS |
| связь между удалёнными платами | не выбирать автоматически ни один | допустимую длину и помехоустойчивый физический уровень |
UART, I2C и SPI обычно предназначены для соединений внутри устройства или на коротком стенде. Для длинного кабеля и шумной среды применяют физические интерфейсы, рассчитанные на такие условия, например дифференциальные трансиверы. Программный протокол и электрический уровень — разные решения.
Уровни напряжения
Надпись 3.3 V или 5 V рядом с питанием не всегда сообщает допустимый уровень сигнального входа. Плата-модуль может иметь стабилизатор на VCC, но не иметь преобразователя на RX, SDA или SCK.
Перед соединением найдите в документации:
- напряжение питания модуля;
- абсолютный максимум сигнальных входов;
- пороги высокого и низкого уровней;
- наличие и направление level shifter;
- напряжение, к которому подключены I2C-подтяжки.
Двунаправленная I2C-линия требует подходящего двунаправленного преобразования. Обычный односторонний делитель напряжения не является универсальной заменой.
Диагностика по уровням
Ошибку удобнее искать слоями:
| Слой | Проверка |
|---|---|
| питание | правильное напряжение, полярность, общий GND, потребление |
| проводка | соответствие TX/RX, SDA/SCL, SCK/COPI/CIPO/CS и старым обозначениям в datasheet |
| электрические уровни | совместимость GPIO и подтяжек |
| транспорт | скорость UART, адрес I2C, режим и частота SPI |
| команда устройства | правильный регистр, формат пакета, паузы |
| программа | выбранная библиотека, версия, обработка ошибки |
Логический анализатор показывает форму и последовательность цифровых сигналов, но подключать его тоже нужно с общей землёй и допустимым входным напряжением. Сначала проверяют мультиметром питание, затем наблюдают обмен.
Что запомнить о протоколах
- Протокол задаёт правила, а распиновка и электрические уровни задают физическую возможность обмена.
- UART соединяют
TXс противоположнымRXи согласуют формат кадра. - I2C использует общие
SDA/SCL, адреса и подтяжки; совпавшие адреса создают конфликт. - SPI разделяет такт и линии данных, но обычно требует отдельный
CSдля каждого устройства. - У всех соединённых логических устройств должна быть корректная общая точка отсчёта.
- Настройки берут из документации конкретного модуля и платы.
Практика
Задание 1. Распознай интерфейс
Возьмите datasheet трёх доступных модулей. Для каждого найдите контакты данных, тип интерфейса, напряжение логики и обязательные внешние элементы. Представьте результат таблицей без подключения оборудования.
Задание 2. Схема трёх шин
Нарисуйте UART-соединение двух плат, I2C-шину с двумя датчиками и SPI-шину с двумя периферийными устройствами. Отметьте направления, общий провод, подтяжки и отдельные CS.
Задание 3. Выбор для робота
Роботу нужны радиомодуль, два одинаковых датчика и быстрая память. Предложите интерфейс для каждого узла. Укажите, какие сведения ещё нужно узнать, прежде чем схема станет готовой.
Задание 4. План диагностики
Составьте последовательность проверок для I2C-модуля, который не отвечает после подключения. Начните с действий без изменения кода и закончите анализом транзакций.
Проверьте себя
- Какие правила кроме проводов входят в понятие протокола?
- Почему в UART соединяют
TXиRXперекрёстно? - Для чего I2C нужны подтягивающие резисторы?
- Как выбирается устройство на общей I2C-шине?
- Зачем каждому SPI-устройству отдельный
CS? - Какие параметры SPI должны соответствовать datasheet?
- Почему маркировка питания модуля не гарантирует допустимый уровень входов?
- В каком порядке искать ошибку обмена?
Сначала ответьте без подсказки. Ответ можно считать полным, если вы:
- формулируете основную мысль своими словами;
- называете важные условия, ограничения или меры безопасности;
- для схемы, кода или расчёта показываете ход решения и ожидаемый результат.
Если один из пунктов объяснить не получается, найдите соответствующую главу статьи, перечитайте её и повторите ответ.
Словарь статьи
- Протокол — согласованный набор правил обмена данными.
- UART — асинхронный последовательный интерфейс с отдельными передачей и приёмом.
- I2C — синхронная адресная шина на линиях
SDAиSCL. - SPI — синхронный интерфейс с тактом, линиями данных и выбором периферии.
- Бод — число символьных состояний сигнала в секунду; в обычном UART часто соответствует битам в секунду.
- Адрес — число, выбирающее устройство на общей шине.
- Подтяжка — резистор, формирующий неактивный высокий уровень линии.
- Chip Select — сигнал выбора конкретного SPI-устройства.
- Логический уровень — диапазон напряжения, распознаваемый как
LOWилиHIGH. - Транзакция — законченная последовательность обмена по правилам интерфейса.
Связанные темы
- Монитор порта Serial — первый практический интерфейс UART в скетче.
- I2C-дисплей — поиск адреса и запуск конкретной периферии.
- UART Bluetooth-модуль — обмен командами через последовательный радиомост.
- Библиотеки Arduino — как API скрывает транзакции, не меняя электрические требования.