Dshot (Digital Shot) — современный цифровой протокол связи
DShot, bidirectional DShot и EDT: техническое разъяснение (форматы кадров, тайминги, кодирование обратного канала, расчёт RPM, диагностика)
Цель: дать инженерно-точное, практичное описание того, как устроены DShot и bidirectional DShot, как декодируется телеметрия (включая расчёт RPM), зачем нужны GCR/NRZI в обратном канале, и как настраивать/диагностировать это в Betaflight.
Содержание
1) Термины и общая архитектура
DShot vs bidirectional DShot vs EDT
DShot — цифровой протокол FC→ESC, где каждый кадр фиксированной длины несёт значение газа и контрольную сумму. Он отправляется по обычному «моторному» сигнальному проводу.
Bidirectional DShot расширяет DShot до обмена FC↔ESC по одному проводу: FC отправляет кадр, затем временно переключает линию на приём, и ESC возвращает телеметрию (в базовом варианте — данные, из которых восстанавливается RPM).
EDT (Extended DShot Telemetry) — расширение поверх bidir DShot: позволяет возвращать не только RPM-производные данные, но и дополнительные телеметрийные значения (в зависимости от ESC/прошивки и режима).
Практический смысл. DShot убирает PWM-джиттер как источник «дрожания газа». Bidirectional DShot добавляет обратную связь по вращению моторов (основа для RPM filtering и связанных механизмов). EDT пытается выжать из этого же канала больше телеметрии без отдельного UART-провода.
Почему это «цифра», хотя используется PWM-железо
В DShot PWM-таймеры/каналы MCU используются как генератор точных временных окон, но смысл кодирования — цифровой: каждый импульс соответствует одному биту.
Бит задаётся не «абсолютной шириной аналогового импульса газа», а отношением длительности уровня high к общей длине бита. Это и делает протокол устойчивее к джиттеру, чем классические PWM-протоколы (Oneshot/Multishot), где газ напрямую закодирован шириной импульса.
Где это живёт в контуре управления (PID loop)
Типичная модель: Betaflight формирует обновления моторов на частоте, связанной с частотой PID loop. Поэтому выбор скорости DShot (150/300/600/1200) и включение bidir часто оценивают через «успеваемость» в рамках loop-time.
Замечание. Теоретическая пропускная способность DShot (по длительности кадра) выше, чем практическая, потому что реальная частота обновлений часто ограничена PID loop и накладными расходами (переключение линии, обратные кадры и т.п.).
2) Тайминги и пропускная способность
Таблица DShot150/300/600/1200
В DShot у каждого бита фиксированная длина, а значение «0/1» определяется длительностью уровня high внутри битового периода.
| Режим | Битрейт | T1H (µs) | T0H (µs) | Bit (µs) | Frame 16-bit (µs) |
|---|---|---|---|---|---|
| DShot150 | 150 kbit/s | 5.00 | 2.50 | 6.67 | 106.72 |
| DShot300 | 300 kbit/s | 2.50 | 1.25 | 3.33 | 53.28 |
| DShot600 | 600 kbit/s | 1.25 | 0.625 | 1.67 | 26.72 |
| DShot1200 | 1200 kbit/s | 0.625 | 0.313 | 0.83 | 13.28 |
Инженерный смысл. Отличие между режимами — масштабирование таймингов. Чем выше режим, тем короче окно бита, тем выше требования к чистоте сигнала, разводке, фронтам и реализации (DMA/таймеры/порт).
Теоретический потолок кадров/с
Если рассматривать только длительность DShot-кадра FC→ESC (16 бит) без пауз и без обратного канала, можно прикинуть верхнюю границу частоты кадров:
$$f_{max} \approx \frac{1}{T_{frame}}$$
Например, для DShot300 при T_frame ≈ 53.28 µs теоретический максимум порядка 18.8 кГц. На практике частота обновления моторов обычно привязана к PID loop.
Сколько «стоит» bidir по времени
В bidirectional DShot после кадра FC→ESC добавляется пауза на разворот линии (порядка 30 µs), затем обратный кадр ESC→FC, и затем требуется готовность к следующему кадру.
Итог: эффективная «скорость обмена» падает. Поэтому режим DShot, который без bidir был «с запасом», с bidir может стать пограничным для высоких loop-rate.
Практический риск. Если суммарное время «кадр туда + разворот + кадр обратно + разворот» приближается к периоду PID loop, телеметрия начинает теряться, а RPM-фильтры и связанные механизмы становятся нестабильными.
3) Кадр DShot: биты, CRC, спецкоманды
Структура 16-битного кадра
DShot передаёт 16 бит за кадр: 11 бит значения, 1 бит телеметрии, 4 бита CRC.
Формат кадра: SSSSSSSSSSSTCCCC
- S — 11 бит throttle/command (0…2047).
- T — запрос телеметрии (1 бит).
- C — CRC (4 бита).

Принято резервировать начальные значения: 0 — disarmed; 1…47 — спецкоманды; 48…2047 — газ (2000 шагов).
CRC: вычисление и интерпретация
CRC вычисляется по 12 битам (11 throttle + 1 telemetry-bit) через XOR свёртку по нибблам.
Почему это важно. В отличие от «аналогового PWM», где небольшая ошибка времени напрямую превращается в ошибку газа, DShot даёт ESC возможность отбрасывать повреждённые кадры (по CRC), вместо того чтобы «верить» неверной длительности импульса.
Диапазон 1…47: special commands
Значения 1…47 часто используются как «команды» (beep, направление вращения, сохранение настроек, запросы телеметрийных полей и т.п.). Многие команды требуют повторения (например, “Need 6x”) и/или выдержки паузы между командами.
Практический смысл. Резерв команд делает протокол не только «газом», но и транспортом простых сервисных действий без отдельного интерфейса. Цена — необходимость аккуратного тайминга и повторов, иначе ESC может игнорировать команды.
4) Bidirectional DShot: инверсия и обратный канал
Инверсия уровней и смысл «idle = 1»
Bidirectional DShot использует инвертированные уровни сигнала (в простое линия держится в 1). Это служит признаком для ESC: после приёма кадра нужно отправить ответную телеметрию по тому же проводу.
После отправки кадра FC ждёт порядка 30us, переключает GPIO на вход, и принимает телеметрийный кадр от ESC.
Отличие checksum в uplink кадре
В uplink (FC→ESC) кадре bidir DShot нижние 4 бита содержат «дополненный» XOR по нибблам: в отличие от обычного DShot, XOR-сумма дополнительно инвертируется (complement).
ESC отличает «bidir-режим» по инверсии уровней и понимает, что нужно отправлять телеметрию.
GCR (0,2) + NRZI-подобное кодирование в 21 бит
Ответ ESC логически является 16-битным значением (данные + CRC), но перед передачей он перекодируется, чтобы уменьшить вероятность ошибок в шумной среде и ограничить серии нулей.
Шаг 1: GCR. 16 бит превращаются в 20 бит по маппингу «ниббл → 5 бит» (чтобы не было более двух подряд нулей):
Шаг 2: 20 бит → 21 бит. Далее строится 21-битное значение: начинаем с 0 и «переключаем» следующий бит, если входной бит равен 1, иначе повторяем предыдущее значение. Пример преобразования:
1 0 1 1 1 0 0 1 1 0 → 0 1 1 0 1 0 0 0 1 0 0
Итоговый 21-битный поток передаётся uninverted на скорости 5/4 от битрейта DShot (например, при DShot600 обратный канал использует 750 kbit/s). ESC должен быть готов примерно через 40us + длина кадра DShot, чтобы принять следующий пакет.
Практический смысл. Обратный канал специально «укреплён» кодированием (ограничение серий нулей + переключения), потому что приём телеметрии по тому же силово-шумному проводу — более сложная задача, чем передача FC→ESC.
5) Телеметрия: eperiod/eRPM/RPM и EDT
Формат eperiod в 12 битах
В базовой bidir-телеметрии верхние 12 бит данных содержат eperiod (период, обратно пропорциональный электрической скорости), закодированный как:
e e e m m m m m m m m m
Здесь E — 3-битный показатель, M — 9-битная мантисса. Чтобы получить период в микросекундах:
$$eperiod_{\mu s} = M \ll E$$
Это даёт диапазон периода от 1us до 65408us.
Формулы: eRPS/eRPM и механические RPM
Разделим термины:
- Электрическая скорость (eRPS/eRPM): скорость коммутации/электрического цикла.
- Механическая скорость (RPM): физические обороты ротора.
- motor_poles: число магнитов (полюсов) на колоколе. Число пар полюсов = motor_poles/2.
Если eperiod выражен в микросекундах:
$$eRPS = \frac{10^6}{eperiod_{\mu s}}$$
$$eRPM = 60 \cdot eRPS = \frac{60 \cdot 10^6}{eperiod_{\mu s}}$$
$$RPM_{mech} = \frac{eRPM}{motor\_poles/2} = \frac{60 \cdot 10^6}{eperiod_{\mu s}\cdot(motor\_poles/2)}$$
Пример. Пусть motor_poles = 14 (7 пар полюсов) и eperiod = 250 µs.
- eRPM = 60e6 / 250 = 240000
- RPM_mech = 240000 / 7 ≈ 34285
EDT: как упаковываются расширенные данные
EDT (Extended DShot Telemetry) использует тот факт, что часть комбинаций в пространстве кодов может быть выделена под «не-RPM» сообщения. Тогда вместо интерпретации «eee + M» как eperiod, кадр читается как «тип + значение».
В описанной схеме признак EDT задаётся особым паттерном в старших битах, после чего данные трактуются как:
pppp mmmmmmmm (тип телеметрии + значение 0…255)
Практический смысл. EDT пытается передать дополнительные параметры (например, температура/напряжение/ток/состояния) по тем же моторным проводам, когда отдельный телеметрийный UART не используется.
6) Практика: настройка, диагностика, типовые сбои
CLI-настройки: dshot_bidir, dshot_edt, motor_poles
Минимальный набор настроек для включения bidir и корректной интерпретации RPM зависит от вашей сборки, но по сути включает:
Режим EDT включается отдельной настройкой dshot_edt (значения вроде OFF/ON/FORCE), но он имеет смысл только если ESC/прошивка реально поддерживают соответствующую телеметрию.
Важно. Неверное значение motor_poles не «ломает» протокол, но ломает математику пересчёта eRPM → механические RPM. Это приводит к неправильным частотам RPM filtering и странному поведению связанных механизмов.
Motors tab: как читать ошибки телеметрии
В Motors tab обычно смотрят два базовых признака:
- по каждому мотору есть осмысленные RPM при вращении;
- ошибки телеметрии должны быть низкими (порядка единиц процентов и ниже).
Характерный кейс: при подключении только USB без LiPo ESC не инициализируются полностью, и можно увидеть «100% ошибок»; после подачи питания (LiPo) и запуска ESC ситуация меняется.
Blackbox/debug: что логировать
Если нужна диагностика не «на глаз», а по данным, используют Blackbox debug режимы, связанные с RPM и DShot-телеметрией. Это помогает отделить:
- потерю обратных пакетов (ошибка приёма),
- неправильную интерпретацию (неверные motor_poles или масштаб),
- проблемы планировщика (нестабильный loop-time).
DMA/bitbang/burst: почему «не заводится»
DShot требователен к таймингам, поэтому реализация использует DMA/таймеры или bitbang (в зависимости от таргета/платы). Типовые причины отказов:
- конфликты ресурсов (таймеры/DMA-стримы заняты другими функциями);
- режимы DMA (например, burst) могут ухудшать совместимость в некоторых конфигурациях;
- разводка/помехи: более быстрые режимы (600/1200) чаще «ломаются» на физическом уровне.
Практический смысл. «Не работает bidir» часто означает не одну проблему, а комбинацию: time budget (туда-обратно) + нестабильный loop-time + ошибки приёма на обратном канале. Поэтому диагностика почти всегда начинается с контроля ошибок телеметрии и стабильности задач.
Чеклист «железобетонно рабочий bidir»
- Выберите скорость DShot, соответствующую вашему loop-rate и запасу по времени.
- Включите dshot_bidir и обеспечьте стабильность планировщика через scheduler_optimize_rate.
- Выставьте корректный motor_poles (по фактическому числу магнитов).
- Проверьте в Motors tab, что RPM осмысленные, а ошибки телеметрии низкие.
- Если нужно EDT — включайте dshot_edt только при уверенной поддержке со стороны ESC/прошивки.
- При странных сбоях учитывайте ресурсные конфликты DMA/таймеров и влияние высоких скоростей DShot на качество сигнала.
Dynamic Idle: что меняется с RPM телеметрией
Dynamic Idle использует RPM (через bidir DShot) как обратную связь, чтобы поддерживать минимальные обороты и снизить склонность к «провалам» и срывам на малом газе. Вместо фиксированного минимума драйва, логика ориентируется на фактические обороты и заданный минимум.
Практический смысл. С появлением устойчивых RPM данных управление «низом» становится менее зависимым от грубой подстройки минимального газа и больше — от реального состояния мотора.
