Хронометраж для горных лыж на Ардуино. Радиоканал на модулях nRF24L01+

Радиоканал для связи одноплатных микрокомпьютеров Ардуино организуется при помощи радиомодулей. Насколько представлял это по обычным вычислительным сетям, микрокомпьютеру присваивается адрес, по которому на определенной частоте его может найти другой микрокомпьютер, находящийся конечно в пределах «радиовидимости». Затем эти компьютеры общаются между собой по некоторому протоколу, в который лезть не нужно. В результате происходит обмен данными при помощи простых команд высокого уровня.

Модуль на основе микросхемы nRF24L01+, довольно старый (более пяти лет без изменений), по современным меркам не самый лучший, но довольно распространенный. Судя по упоминаниям в обзорах, на программно-аппаратном уровне можно организовать «сетку» из 6-и микрокомпьютеров, которые могут (при покупке платы с шумоподавлением и усилителем) связываться на расстоянии до 1 км. Этой информации мне показалось достаточно для проекта «Хронометраж для горных лыж на Ардуино», поскольку мне нужно связывать 3-и микрокомпьютера (Старт, Финиш и базовый блок) и в перспективе еще один (выносное табло), то есть менее шести. И на расстоянии 500 метров, то есть менее километра.

В заметке делюсь опытом реализации. К сожалению, без «танцев с бубнами» не обошлось  🙁

Микросхема nRF24L01+

Придется начать с чипа (микросхемы) nRF24L01+. Производитель Nordic Semicoductor (Норвегия).  На сайте можно скачать описание (даташит), очень подробное, на 78 страницах, но для специалистов. Правда, за пару последних недель модуль nRF24L01+  переместился на сайте в раздел:  nRF24 Series (legacy), что означает «старая версия» с пометкой «Not recommended for new designs». А страницы, на которых я совсем недавно читал про отличие версии с «плюсом» от предыдущей, которая производилась в период «10 лет назад — пять лет назад» с сайта убраны.

Можно сделать вывод, что микросхемы nRF24L01+ более не производятся. Но если в течении полугода модули на этих микросхемах не исчезнут с Али-Экспресс, то придется сделать другой вывод: микросхемы nRF24L01+ не имеют никакого отношения к Nordic Semiconductor, возможно уже сейчас 🙂

На страницах 66-77 описания чипа nRF24L01+ в качестве примеров представлена рекомендуемая схема готового модуля и дано несколько чертежей печатных плат. Например:

В общем, у меня сложилось впечатление что есть прекрасная, проверенная временем (в сумме 10 лет для версий с «плюсом» и без плюса) микросхема nRF24L01+, работа которой гарантирована производителем Nordic Semiconductor и детально документирована. И есть реализации в виде модулей, за работу которых Nordic Semiconductor конечно никак не отвечает. Самая простая реализация — просто взять представленный как пример чертеж печатной платы. К сожалению, вряд ли это будет работать.  Для организации обмена данными к чипу нужно (согласно схеме-примеру) подключить кварц на 16 МГц. Это уже радиочастоты. А на выходе микросхема выдает  2.4 ГГц несущей частоты. Это уже СВЧ, близко к границе сантиметрового диапазона. Есть большой риск, что если «просто» развести плату, будут взаимные наводки. Поэтому желательно следовать конкретным советам интернет-гуру при покупке модулей у конкретного производителя (имеется в виду из представленных на Али-Экспресс). И конечно смотреть на количество заказов и положительных отзывов. Конечно я так и сделал 🙂 Но проблем не избежал. И в «даташит» полез не от хорошей жизни 🙂 И это тоже, как оказалось, типично 🙂

О выборе модуля и вообще 🙂

Вообще, выбор модуля для радиоканала был не простой задачей. Начать с того, что я не специалист, но по моим представлениям частота для связи на расстояние примерно километр должна быть, например из разрешенного диапазона 433 МГц. А 2.4 ГГц это для небольшого радиуса действия, как и реализовано в Wi-Fi и Bluetooth. На 433 Мгц надежного решения не нашел. То есть, видел модули на Али, читал отзывы, потом искал реальный опыт для проектов на Ардуино и отказывался 🙂

Придется остановиться немного на сущности платформы Ардуино. Конечно радиомодули (да и практически все остальные модули) производятся не для Ардуино, а «сами по себе». Ардуино это платформа, объединяющая определенный тип одноплатных компьютеров (то есть микропроцессор с «обвязкой»), среду программирования и накопленный в интернете опыт в виде библиотек, примеров и форумов. Ардуино это не единственная такая платформа, отличается тем, что в нее довольно простой «вход». Ну и действительно выпускаются наборы-конструкторы Ардуино, в которые входят варианты модулей на платах с аппаратной совместимостью на уровне разъемов и  отлаженным программным обеспечением.

Поэтому, например для реализации радиоканала нужно чтобы совпало следующее:

  1. Модуль должен быть аппаратно совместим с Ардуино. Например, микросхема nRF24L01+ и модуль на ее основе управляются по протоколу и «шине» SPI (Serial Peripheral Interface). Из Википедии: последовательный синхронный стандарт передачи данных в режиме полного дуплекса, предназначенный для обеспечения простого и недорогого высокоскоростного сопряжения микроконтроллеров и периферии. SPI также иногда называют четырёхпроводным (англ. four-wire) интерфейсом). У Ардуино есть специальные четыре вывода («шина»), на которых реализован этот протокол.
  2. Для модуля должна быть библиотека. Откуда она берется? Предположим, нашелся некий специалист, который в состоянии осилить описание микросхемы и/или модуля на ее основе (даташит). Кроме этого специалист ориентируется в протоколах, реализованных и в Ардуино и в модуле, то есть может обеспечить надежное сопряжение модулей на низком (аппаратно-программном) уровне. И самое важное. По каким-то причинам этот специалист забесплатно в порыве энтузиазма переводит все это из «птичьего» языка в библиотеку Ардуино, так чтобы появились процедуры на языке программирования Ардуино (Си++). К сожалению, вероятность такого совпадения невелика, поскольку описанный специалист это профессионал (или тот, который им вот-вот станет), а среда Арудино — это для любителей, профессионалу здесь делать нечего. Вообще, в «настоящих» компьютерах этот процесс называется «создание драйвера». Драйверы поставляются в обязательном порядке производителем модуля. Но в среде Ардуино этого нет.
  3. Должны быть примеры реализации  работы модуля и библиотеки. Для одного модуля может быть несколько разных библиотек. Но главное, в интернете должен быть накоплен реальный опыт. Иначе у любителя может не хватить квалификации.


Для модулей на 433 Мгц разделы 1-3 для меня не сложились. Но  вывалилась положительная информация про модули на основе микросхемы nRF24L01+. Окончательный выбор сделал после просмотра ролика от AlexGyver «Arduino and nRF24L01. Wiring and wireless control by Arduino» (на русском языке).

Подключение и настройка nRF24L01 к Arduino (модуль беспроводной связи) — YouTube от AlexGyver. На этом скриншоте верхняя плата — радиомодуль в варианте с двумя усилителями — на передачу и на прием, вторая сверху плата — адаптер питания радиомодуля, состоящий в основном из крупной микросхемы, выдающей 3.3 В, которые преобразовываются из «бортовых» 5 вольт Ардуино, нижняя плата — Ардуино Нано. Правые два провода — питание, левые провода сигналы. Провода припаяны и сделаны как можно короче.

В ролике демонстрируется надежная передача данных на расстоянии более километра. В описании ролика есть ссылка на библиотеку (с примерами). Заказал модули именно у того продавца, которого рекомендовал на основании собственного опыта AlexGyver, правда вспомогательного модуля для питания 3.3 В там не было, пришлось заказать в другом месте (и это, как выяснилось позже, оказалось «попадалово»).

После того, как заказал модули попалась ссылка проект, который один-в-один соответствует теме: «Хронометраж для горных лыж на Ардуино»: OMEGA — Автоматизация подсчета времени на спортивных мероприятиях от Сергея Мельникова. В нем использованы точно такие же радиомодули, которые нормально работают.

Омега Сергея Мельникова

Это укрепило уверенность в правильном выборе 🙂

Сложности

На пришедших модулях (с трудом) можно рассмотреть микросхему nRF24L01+:

Обычно работоспособность и правильность подключения модуля проверяют примером из библиотеки «слушать эфир». Модуль в режиме приемника сканирует частотные каналы и показывает, на каких еще кто-то работает, а какие чистые. Если картина получается именно такая, модуль считается хорошим. Если все каналы чистые, это может вызвать подозрение того, что модуль ничего не принимает. Это тест прошел отлично. А почти все остальные тесты, которые так хорошо показаны в роликах, не проходили вообще. Эти тесты основаны на работе модулей в режиме переключения передатчик-приемник (типа пинг-понг). Тесты не проходили, потому что в режим передатчика модули не переключались.

Пришлось погрузиться в 100 страничный форум со страшным названием: nRF24L01+ : побеждаем модуль. Параллельно пришлось набирать информацию для того, чтобы более менее понимать о чем там пишут. Например, полез в «даташит» на сайте Nordic Semiconductor, чтобы понять как организована адресация модулей, поскольку термин «Канал передачи данных» (Data Pipe) на форумном сленге именовался как «труба», а объяснения что это такое приводили в ступор.

В даташите довольно понятно объяснено, что основной режим микросхемы — приемник. Переключение в режим передатчика должно проходить в виде определенного ритуала, в который входит в частности подача на соответствующую ножку микросхемы высокого уровня длительностью не менее 10 мкс.

(The TX mode is an active mode for transmitting packets. To enter this mode, the nRF24L01+ must have the PWR_UP bit set high, PRIM_RX bit set low, a payload in the TX FIFO and a high pulse on the CE for more than 10µs).

Появились сомнения, что в библиотеке правильно соблюден ритуал, поэтому может работать, может нет. Основный опыт в интернете представлен по работе с библиотекой «RF24». Попробовал на «старой» библиотеке «Mirf», то же самое. Перед этим конечно прошелся по аппаратной части, как советуют: подпаял все провода, пытался навесить конденсаторы, ну и далее по кругу 🙂

Судя по форуму, такие хождения по кругу нередки. Иногда результат выстреливает, а иногда нет. Особенность еще в том, что радио это не цифра. Поэтому бывает так, что нет состояний «работает — не работает». Иногда, на некоторых примерах «пинг-понги» проходили, правда с большими задержками. Попытки зацепиться за это в общем-то не привели к стабильной работе.

Стабильная работа модулей

Была и хорошая новость. В примерах AlexGyver есть вариант (в стандартной библиотеке его нет) простой приемо-передачи. То есть без переключений для подтверждений принятой информации, а просто один модуль шлет, второй принимает. Этот пример с самого начала работал гораздо лучше других. Правда чуть по-разному на разных из 5-и пришедших модулях. На прием они все работали одинаково, а на передачу один лучше всех, затем два других похуже и еще два совсем плохо. В общем, подозрение на неправильно работающие модули осталось. Причем, если все наладится, то «осадок останется» 🙂

На всякий случай заказал модули в другом конструктиве и к ним адаптеры питания тоже в другом конструктиве. Чтобы была уверенность, что модули произведены в другом месте, поэтому будут отличаться. Этот конструктив нравится больше, поскольку там все заэкранировано, как по моим представлениями и должно быть на таких частотах. Дальность обещают 2 км 🙂

Неосуществившаяся (пока) логика радиообмена

Как уже упоминал, «на низком» уровне модули позволяют строить вычислительную сеть с топологией «звезда». Более приземленно, можно на низком уровне объединять 6 модулей. Эти 6 модулей «сами» поддерживают между собой пинг-понговую связь, переключаясь когда нужно в режимы передатчика или приемника, доставляя пакеты несколько раз, пока не будет получено подтверждение и т.п. Наверное далее такие ячейки могут объединяться в сеть, но в эту сторону не копал. В общем, 6 (или меньше, по желанию) модули «перестукиваются», когда им нужно. На следующем уровне «вверх» роли модулей неодинаковы. Есть центровой (номер 0) и основной помощник (номер 1), которые легко общаются по двусторонней связи. Остальные 4-е это как бы ассистенты помощника, их назначение состоит в передаче информации «в центр». При этом номер ноль может слышать одновременно все остальные пять. Интересно, что в качестве обратного пакета для «перестукивания» можно выбирать что послать (не переводя программно на верхнем уровне модуль в режим передатчика).

Если перевести эти роли в «хронометраж для горных лыж», то получалось примерно так. Номер ноль это базовый блок. Номер один — Старт, номер 2 — Финиш. Таким образом, базовый блок получает со Старта и Финиша времена срабатываний, поддерживает хронометраж до 3 участников на трассе (подробнее здесь: Хронометраж для горных лыж на Ардуино. Логика), и передает на Старт информацию «Можно дать старт» и «Финиш готов». В качестве подтверждений о приеме информации базовый блок рассылает на Старт и Финиш время своего внутреннего таймера. По этому времени с учетом замера времени доставки Старт и Финиш постоянно синхронизирует свои часы и передают на базовый блок время факта срабатывания уже приведенное ко времени базового блока.

К сожалению, от такого подхода пришлось отказаться, но оставлю здесь, может вернусь на новых модулях. На моих нынешних модулях подтверждение обычно не работало вообще. А когда работало, то время между доставкой и получением подтверждения «гуляло», а значения превышали показанные в примерах от AlexGyver в 5 раз. Поскольку это не «цифра», а радиотехника, причин для этого (помимо моей некомпетентности) может быть много, найти главную причину пока не удалось. Но и время, отведенное на поиски вышло 🙂  Да и результат мне нужен с повышенной надежностью, иначе вместо того чтобы кататься на лыжах станешь «рабом омеги» 🙂

Логика радиоканала

Пока новые модули едут, работаю с тем, что есть. То есть, если не идет основной режим работы, с контролем доставки каждого пакета (для этого и организован «пинг-понг»), а работает режим приемник-передатчик, то придется «подрихтовать» логику радиоканала в хронометраже.

Базовый (основной) блок переместился на Старт. На Старте в систему входят обычные (не радио) сигналы со стартовой калитки, обрабатывается логика на измерение результатов участников (еще раз, подробнее здесь: Хронометраж для горных лыж на Ардуино. Логика). Радиомодуль стартового блока постоянно настроен на прием.

Финишный блок постоянно настроен на передачу пакетов данных из двух полей: текущее внутреннее время микрокомпьютера (в миллисекундах) и факт пересечения финишного луча (да, нет).

При пересечении финиша, время запоминается и вместе с фактом «да» передается на Старт, скажем 10 раз (настраивается в программе). Надеюсь, что хотя бы один такой пакет дойдет. Поскольку подтверждений нет, узнать об этом наверняка невозможно 🙁

Время между передачами пакетов от «пустующего» Финиша на Старт установил в полсекунды. То есть, если финиш не пересечен, то каждые полсекунды Старт получает с Финиша пакет из текущего времени внутреннего таймера микрокомпьютера и факта «никто пока не проехал».

Факт пересечения финиша обрабатывается через «прерывание». На Ардуино нано есть две «ножки», на каждую из которых можно «навесить» кнопку, нажатие на которую обрабатывается сразу, независимо от хода течения программы.

Проверка связи «Старт — Финиш»

Стартовый блок в своем цикле постоянного опроса кнопки калитки и анализа того, что происходит на трассе, обращается к буферу приемника. Там что-то может быть, а может и не быть, потому что прием и передача никак не синхронизированы (потому что пинг-понга нет). То есть, если например Старт опрашивает буфер чаще, чем Финиш шлет информацию, то в приемном буфере иногда есть пакет, а иногда нет, и это нормально 🙂  В общем-то ничего страшного, просто вводится «тайм-аут» промежуток времени, когда пока нет повода для беспокойства. Если тайм-аут нарушен, то можно сделать вывод, что связи с финишем нет. Это первая задача стартового блока. Если связи нет — зажечь соответствующую лампочку.

Синхронизация часов «Старт — Финиш»

Вторая задача — синхронизация таймеров стартового и финишных блоков. Стартовый блок вычитает приходящее текущее время финишного блока из своего, а получившуюся разницу усредняет, скажем по 10-и прошедшим измерениям. Кстати, внутренние таймеры (двух конкретных Ардуин, с которыми вожусь заметно  не совпадают, измеренная (в миллисекундах) разница «плывет» со временем в одну сторону, то есть «миллисекунды» у разных Ардуин разные 🙂 В течение одного спуска этим конечно можно пренебречь 🙂 На всякий случай подобрал коэффициент изменения скорости таймера в финишном блоке, так чтобы если пакет приходит нормально, то чтобы с точностью до миллисекунды дрейфа не было.

Обработка факта финиша

Третья задача, это когда придет факт «финиш пересечен» (первый из пакетов с такой одинаковой информацией), то вместо того, чтобы сравнивать со своим текущим временем, нужно с учетом текущей усредненной разницы перевести пришедшее время финиша во время стартового блока. И пустить этот результат в дальнейшую обработку. Такие сложности нужны потому что точно не известно, какой из пакетов будет получен и сколько он будет доставляться.  Да и вообще, в «цифре» передается не сигнал, а цифра, поэтому лучше постараться минимизировать влияние времени доставки.

В «лабораторных» условиях стабильно проходит первый пакет и вычисленное с такими ухищрениями время пересечения финиша совпадает со фактом принятия пакета стартовым модулем с точностью до миллисекунды. А 10 пакетов с одинаковой информацией о времени пересечения финиша передаются на старт примерно за 45 миллисекунд (5 сотых секунды).

Передача результата на выносное табло

Затем стартовому блоку нужно взять паузу, погасить лампочку «Можно дать старт» и соблюсти все необходимые действия с танцами и приседаниями по переключению в режим «передатчик и только». Затем передать уже готовую информацию о результате прохождения дистанции на блок «Табло», который работает постоянно в режиме приемника. А потом Старту нужно спокойно переключиться обратно в режим приема.

nRF24L01+ и питание 3.3 вольта

добавлено позже

Как упоминал выше, в моем случае проблемы были при переключении модулей в режим передатчика. Согласно даташиту сама микросхема потребляет в режиме приема и передачи примерно одинаково и немного. Но к нашему случаю это не относится, поскольку на плате расположен еще мощный антенный усилитель. Видимо из-за того, что  модуль переключается в режим передатчика «в импульсе», происходит большая «просадка» по питанию.

Особенно это стало заметно, когда пришли новые радиомодули в другом конструктиве. Судя по описанию можно сделать вывод, что антенный усилитель в этих модулях мощнее. При замене старых модулей на новые (разъем и разводка совпадают, поэтому просто из адаптера вынимается старый и ставится новый) в режиме передатчика модули не работали вообще. Но после замены в программе параметра мощности передачи с максимального на минимальный работали хорошо. В общем, подозрение на адаптер, заказанный у «нерекомендованного» AlexGyver поставщика резко усилилось.

В сети есть впечатляющий ролик любителя из Новой Зеландии, в котором показана связь на таких «новых» радиомодулях и с направленной wi-fi антенной на расстоянии 31 км (в прямой видимости). Передатчик был установлен на холме недалеко от Окланда, а приемник перемещали на машине, с остановками для измерений.

Вот скриншот из видео того же автора, в котором он рассказывает о «железе». Радиомодуль был запитан без специального адаптера, просто «понижайкой» с 5 до 3.3 вольт, но с «хорошими» конденсаторами. Заказал, конечно, такие же «понижайки» с Али, но увы, пришлось столкнуться с тем, что последовательное решение проблем может растянуться на месяцы.

Довольно часть в сети рекомендуют запараллелить питание 3.3 в на радиомодуле парой конденсаторов (0.1 — 0.5 мкФ керамический + 10 — 100 мкФ например электролитический, точное значение разное в разных источниках информации, поэтому обозначен диапазон). Но при этом во многих источниках информации подчеркивается, что если использовать специальный адаптер питания для радиомодуля  или хороший отдельный модуль на 3.3 в, то конденсаторы не обязательны. Мне этот подход нравится больше, поскольку хотелось бы остаться в рамках «радиоконструктора».

В общем, пришлось «запараллелить» заказы с Али для решения проблемы «питание 3.3 вольта» и устроить гонку, какой заказ первый придет. Заказал понижающие модули как на скриншоте выше, и другие с большими электролитическими конденсаторами. А еще раньше заказал адаптеры питания радиомодуля с визуально большими танталовыми конденсаторами (адаптеры показаны выше на фото с «новыми» радиомодулями).

Заказанные модули понижения напряжения

Для кардинального решения проблемы заказал вариант Ардуино Нано от RobotDyn с мощным питанием 3.3 в на борту.

Ардуино Нано от RobotDyn

Ну и сами конденсаторы, мешок керамики и мешок электролитических, заказаны гораздо раньше, но никак не доедут. Пара «советских» конденсаторов, которая нашлась в доме (керамика на 1 мкФ и электролит на 10 мкФ) что-то улучшали, но не кардинально, «на ступеньку».

Первыми пришли Ардуино Нано от RobotDyn и закрыли проблему. Про эти Ардуино есть отдельная заметка. Радиоканал работает очень хорошо. Правда, возвращаться к исходной точке не стал. К этому времени были сделаны наработки в настройках радио, как нагружать передатчик по минимуму, так что и на предыдущих «обычных» Ардуино все заработало на максимальной мощности, но не стабильно, было много «пропущенных пакетов». Эти настройки и оставил. Теперь работает стабильно, можно тестировать на дальность.

Активация радиоканала без режима «пинг-понг» командами библиотеки «RF24»

Осталось разобраться еще с одной небольшой проблемой по питанию. Похоже, что «нагрузочный импульс» передатчика подсаживает и «повышайку» напряжения от аккумулятора до «бортовых» 5.0 вольт. Выражается это в том, что при питании от  USB модули работают нормально, а если те же 5 вольт идут с аккумулятора, то не работают. Но если регулировочным резистором понизить бортовое напряжение до 4.7 вольт, то от аккумулятора все тоже работает нормально. Пропускание питание через Vin Ардуино ничего не меняет. Про питание Ардуино есть отдельная заметка, поэтому здесь отмечу только, что едет еще и «повышайка» с большими конденсаторами.

Здесь собраны все заметки по теме «Хронометраж для горных лыж на Ардуино».


Vadim Nikitin DigInfo.ruВадим Никитин

 

 

 

на начало страницы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *