Реализация Dshot на Arduino (протокол ESC)

Кто-нибудь знает, можно ли реализовать Dshot на Arduino? Я хочу связать Arduino с ESC (электрическими регуляторами скорости). Эти регуляторы используют Dshot, (https://oscarliang.com/dshot/) цифровой протокол. Из того, что я прочитал в Интернете, вы можете заставить ШИМ следовать рабочему циклу. Однако я хочу изменить рабочий цикл после каждого импульса, а не просто повторять один и тот же рабочий цикл. Я понимаю, что для этого требуется DMA (прямой доступ к памяти), но это немного выше моего понимания.

, 👍3

Обсуждение

По вашей ссылке нет технической характеристики "dshot", только реклама, @Chris Stratton

Однако более важный вопрос заключается в том, как вы получите реальную выгоду - это высокопроизводительный протокол для быстрых контуров управления, работающих на быстрых современных процессорах, а не на медленных ограниченных ATmega. Практически любой ESC, который поддерживает это, поддерживает и другие вещи, либо автоматически, либо с другой сборкой открытой прошивки, которую он использует для поддержки этого в первую очередь., @Chris Stratton

В основном мне нужен dshot для всего, кроме аспекта производительности (отправка команд, звуковой сигнал, телеметрия, светодиоды, биты четности). Я не возражаю против использования pwm, но поскольку я все равно получаю этот esc, почему бы не использовать функциональность в полной мере. Я думаю, что это лучшая ссылка: https://blog.seidel-philipp.de/dshot-digital-esc-signal/, @Melvin Foo

Я хотел бы использовать контроллеры полета, но я не использую эти esc для использования квадрокоптера. Я могу использовать PWM для взаимодействия с полетным контроллером (или есть другие способы), но в этом случае я мог бы также подключиться напрямую к esc., @Melvin Foo


2 ответа


2

Вы можете заставить PWM следовать рабочему циклу.

одиночный ШИМ было бы трудно сделать на AVR.

Гораздо лучше использовать аппаратный spi. Похоже, вы можете использовать 3 бита spi для каждого бита dshot. Таким образом, 6 байт передачи spi будет достаточно для каждого кадра dshot (16 бит dshot).

запуск аппаратного spi на частоте 3*0,6 МГц = 1,8 МГц или где-то на 16MIPS avr был бы вполне выполним.

,

Звучит многообещающе! Я хочу подключить 4 esc, а у audrino только 1 mosi. Одна идея состоит в том, чтобы использовать демультиплексор. Есть предположения?, @Melvin Foo

это будет зависеть от того, как прошивка esc реагирует на длительные периоды отсутствия (входного) сигнала. если для этого требуется постоянное присутствие входного сигнала, это не будет жизнеспособным решением., @dannyf

«пауза между кадрами не менее 2 микросекунд для обозначения сброса кадра» и «петля PID, эта пауза на самом деле значительно длиннее». Как упоминалось здесь: https://blck.mn/2016/11/dshot-the-new-kid-on-the-block/. Это действительно может сработать!, @Melvin Foo

Как мне подключить SPI? У моего ESC только ОДИН порт данных... Я не могу найти информацию об этом., @IceFire


7

Короче говоря, я создал библиотеку, способную управлять несколькими регуляторами DShot600: DShot-Arduino Это все еще нуждается в гораздо большей полировке, но бит-удары работают очень хорошо.


Метод SPI

Я попробовал метод, упомянутый @dannyf, который включал объединение 3 байтов SPI для формирования 1 бита dShot, и он действительно работает.

Но есть несколько проблем с SPI:

  • Он занимает ценный порт SPI, теоретически вы можете подключать другие устройства SPI, но;
  • можно подключить не более 1 регулятора скорости dShot
  • Во время передачи пакета ЦП должен ожидать выполнения всей задачи, предположим, что мы отправляем DShot300, каждый пакет имеет длину около 54 мкс, поэтому ЦП останавливается на это время. Если вы делаете это на частоте 1000 Гц, это составляет 5% процессорного времени.
  • Время не очень точно соответствует стандарту протокола DShot.

например, для DShot300 каждый бит равен

1,25 мкс (высокий уровень) — 1,25 мкс (высокий/низкий уровень) — 0,83 мкс (низкий уровень)

для Arduino с частотой 16 МГц 1,25 мкс будет составлять 20 тактов ЦП, что неточно для передачи с помощью байта SPI

В итоге я получаю следующие коды для отправки бита:

inline void dshot_0(){
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;  
  SPDR = 0x60;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;  
  SPDR = 0x00;
  NOP8;
  while (!(SPSR & _BV(SPIF))) ;
}

inline void dshot_1(){
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;  
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;  
  SPDR = 0xF0;
  NOP8;
  while (!(SPSR & _BV(SPIF))) ;  
}

Вышеприведенный код предназначен для DShot150, SPI был установлен на 4 Мбит/с, чтобы придерживаться правильной синхронизации, я не могу передать полный байт DShot, так как все включено или все выключено, вот как выполняется расчет:

4 Мбит SPI, каждый бит 0,25 мкс. Таким образом, для 16M часов Arduino:

  • Последовательность DShot 0: 10 бит 1, 14 бит 0
  • Последовательность DShot 1: 20 битов 1, 4 бита 0

Эти NOPn являются просто макросом для количества NOP. Я избегал использования кода библиотеки SPI здесь, поскольку вызов библиотеки требует значительных затрат.

Чистый программный взлом

Это метод, приведенный в моей библиотеке, поскольку использование аппаратного SPI не даст мне никаких преимуществ при освобождении ЦП. время, и некоторые математические расчеты показывают, что для DShot600 требуется всего 27 циклов ЦП на 16 МГц UNO. Какой шаблон следующий:

10 циклов High -> 10 циклов H/L (в зависимости от бита 1/0) -> 7 циклов low

Что дает в сумме 1,6875 мкс на бит или 27 мкс на пакет. Чтобы обеспечить очень точное время, они кодируются на ассемблере.

Кроме того, применяя битовую маскировку, библиотека способна управлять не более чем 8 ESC на одном и том же аппаратном порту (на UNO, цифровые контакты 0-7, PORTD).

Цикл обновления

Последнее замечание по поводу DShot. Во время тестирования я обнаружил, что оно довольно строго относится к частоте обновлений. Он должен обновляться с точным интервалом времени, и я обнаружил, что самая медленная частота обновления будет около 500 Гц. Чтобы обеспечить правильное время для этого, библиотека использовала Таймер 1 и по умолчанию обновлялась с частотой 1000 Гц.

,

Вы пробовали STM на базе Arduino и двунаправленный D-Shot? Ваша библиотека выглядит великолепно, я скоро попробую. Спасибо за ваше участие., @M lab

для двунаправленного, вы имеете в виду получение сигнала D-shot с помощью Arduino? Если это так, я считаю, что это невозможно для этих 8-битных процессоров., @xandy

Не уверен, почему, но это не работает. Мой ESC подает звуковой сигнал, чтобы сообщить мне, что сигнал поступает, но двигатель не работает. Любые идеи о том, как устранить неполадки? Я действительно не уверен, что прерывание работает на этой частоте. Я использую Arduino Nano, который по спецификации должен иметь 16 МГц., @IceFire

@xandy действительно получить ответ двунаправленного пакета DShot очень сложно для 8-битных AVR! Недавно у меня заработал прототип. Это немного сложно, но я старался хорошо это прокомментировать. [Посмотрите!](https://github.com/cinderblock/AVR/blob/master/AVR++/BDShot.hpp), @Cameron Tacklind