Умер. ))) Основная причина - практически невозможно догнать micronucleous. Когда проект начинался, было с ними 50/50. Что-то у меня было лучше, что-то у них. Но они вложили в проект явно больше сил и времени, чем я.
Вы и вправду слишком серьёзно относитесь к примерам с гитхаба ;) Назначений у данного примера было — показать минимально достаточный набор настроек и продемонстрировать устойчивость (или неустойчивость) процесса отправки сообщений. При этом скетч должен позволить решить свою задачу: обеспечить контроль успешности приёма-отправки пакетов. Так, чтобы можно было залить пример на две ардуины и посмотреть, потаскав одну из них из комнаты в комнату.
Поэтому по порядку:
Вы считаете очевидным, что функцию stopListening вызывать необходимо? То есть у вас есть некоторое априорное знание, что после включения модуль находится в режиме приёма? Или зачем ещё её надо вызывать? Спешу огорчить, согласно даташиту бит PRIM_RX регистра CONFIG инициализируются нулём — то есть модуль после перезагрузки будет находится в режиме передатчика. Я в первом своём сообщении указал, что именно делает функция stopListening, и почему она так сильно нужна для режима с ожиданием ответа приёмника. При radio.setAutoAck(false); она полностью теряет смысл. Включать нулевой канал на приём нужно именно для того, чтобы получать ответы с приёмника. Можете её выкинуть — работоспособность вашего примера никак не измениться.
Я проверял скетч на моей arduino nano, и у неё безо всякого кода есть светодиод индикации питания, зачем мне нужен ещё один? По поводу различия: сериал/светодиод, тут всё просто: один модуль подключен к компу и весьма информативно пишет в сериал всё что с ним происходит. Второй таскается по комнатам. Конечно можно было бы взять второй ноут, но зачем? Тут и так всё понятно — если в течении 120мс не пришло очередного пакета (хотя должен был прийти в течении 100мс) — значит гасим светодиод, показывая что у нас был сбой. Светодиод будет в погашенном состоянии минимум 80мс — достаточно чтобы заметить и даже прикинуть — сколько именно пакетов было пропущено — процесс приёма качественно контролируется визуально. Частое моргание сразу после включения в данном случае — это не подключен NRF24. Вроде все варианты разобраны.
Интервал в 100мс был выбран для того, чтобы можно было без труда визуально детектировать пропавшие пакеты. В конце концов из комнаты в комнату носишься именно с приёмником, так что изначально видишь только этот светодиод. А 120мс — это выбранное наобум значение, большее 100 (по идее и 101мс должна была подойти, но я взял с запасом). Так как передатчик отправляет пакеты раз в 100мс, то неполучение пакета за чуть более время — это признак пропущенного пакета. В целом — советую чуть внимательнее посмотреть этот код и подумать — что он делает.
Ну а к вашему коду претензии более простые:
У вас много избыточного: как будто вы пытались подобрать параметры, чтобы оно наконец-то заработало, и как только заработало — оставили всё как есть.
Я уже говорил, что stopListening(false), ровно как и setRetries(...) не имеют смысла, если вы вызвали setAutoAck(false).
С другой стороны — я настоятельно рекомендую всё таки не выключать подтверждение приёма, так как в большинстве случаев вам всё равно придётся городить подобную систему поверх. Зачем, если она уже есть на железном уровне?
И ещё про избыточное: ознакомьтесь вот с этим кодом и не делайте то, что и без того сделано за вас: setRetries(5, 15) — уже выставлено и оно является оптимальной настройкой ретраев. powerUp() уже вызван, незачем его вызывать ещё раз. setDataRate(RF24_1MBPS); тоже выставлено. И если вам не надо 2мб/с или 128кб/с — то смело пропускайте. write_register(EN_AA, 0x3F) работает как setAutoAck(true) — так что тоже можете не менять.
PS: пока писал вам это всё, нашёл такой коммит: начиная с версии 1.3.12 уже не обязательно вызывать stopListening на передатчике. Магия больше не нужна
Я лишь излил результаты своих ковыряний с модулем (видимо у каждого в жизни должен быть этап ковыряния с ним ). Так что разумеется: проверяйте, как будет возможность и руки дойдут
На самом деле этот модуль очень просто готовить. Всё что нужно сделать — это обязательно вызвать
radio.stopListening();
в передатчике.
Ну и да, после:
radio.setAutoAck(false);
уже бесполезно выставлять ретраи. Они работают только с включённым autoAck
radio.setRetries(0, 15)
Так что: НЕ отключаем autoack (по дефолту он и так включен), не меняем настройку ретраев (она нормальная сходу). Просто вызываем stopListening на передатчике, и всё работает как часы.
Функция stopListening «заодно» включает нулевой пайп. И именно этот пайп используется для того, чтобы получить ответ ACK от приёмника. Вместе с этим начинает нормально работать механизм ретраев и пара модулей будут работать как часы.
PS. Необходимости включать нулевой пайп на приёмнике не описана даже в даташите. Да, там описано, что нужно записать в него правильный адрес, но о необходимости его включить — не слова. А без него передатчик с включёнными ретраями будет считать, что отправка провалена, хоть приёмник посылку и получит.
Вот наверное такое же чувство должны испытывать люди после хорошего психиатра: я по прежнему болен, но теперь хотя бы знаю, как это называется.
Значит вот это всё, потому что я rock star.
Также приглашаю желающих присоединиться к проекту. Требуется — профилирование, перевод комментов на English, создание build скриптов под разные платформы. Да и любой вклад, который вам интересно преподнести.
И это не мой репозиторий o_O. Хотя код мой. Удивительно
Умер. ))) Основная причина - практически невозможно догнать micronucleous. Когда проект начинался, было с ними 50/50. Что-то у меня было лучше, что-то у них. Но они вложили в проект явно больше сил и времени, чем я.
Вы и вправду слишком серьёзно относитесь к примерам с гитхаба ;) Назначений у данного примера было — показать минимально достаточный набор настроек и продемонстрировать устойчивость (или неустойчивость) процесса отправки сообщений. При этом скетч должен позволить решить свою задачу: обеспечить контроль успешности приёма-отправки пакетов. Так, чтобы можно было залить пример на две ардуины и посмотреть, потаскав одну из них из комнаты в комнату.
Поэтому по порядку:
radio.setAutoAck(false);
она полностью теряет смысл. Включать нулевой канал на приём нужно именно для того, чтобы получать ответы с приёмника. Можете её выкинуть — работоспособность вашего примера никак не измениться.Ну а к вашему коду претензии более простые:
Я уже говорил, что
stopListening(false)
, ровно как иsetRetries(...)
не имеют смысла, если вы вызвалиsetAutoAck(false)
.setRetries(5, 15)
— уже выставлено и оно является оптимальной настройкой ретраев.powerUp()
уже вызван, незачем его вызывать ещё раз.setDataRate(RF24_1MBPS);
тоже выставлено. И если вам не надо 2мб/с или 128кб/с — то смело пропускайте.write_register(EN_AA, 0x3F)
работает какsetAutoAck(true)
— так что тоже можете не менять.PS: пока писал вам это всё, нашёл такой коммит: начиная с версии 1.3.12 уже не обязательно вызывать stopListening на передатчике. Магия больше не нужна
Тут как раз пара передатчик-приёмник. Сделал специально под проверку
Я лишь излил результаты своих ковыряний с модулем (видимо у каждого в жизни должен быть этап ковыряния с ним ). Так что разумеется: проверяйте, как будет возможность и руки дойдут
в передатчике.
Ну и да, после:
уже бесполезно выставлять ретраи. Они работают только с включённым autoAck
Так что: НЕ отключаем autoack (по дефолту он и так включен), не меняем настройку ретраев (она нормальная сходу). Просто вызываем stopListening на передатчике, и всё работает как часы.
А секрет тут:
github.com/nRF24/RF24/blob/master/RF24.cpp#L847
Функция stopListening «заодно» включает нулевой пайп. И именно этот пайп используется для того, чтобы получить ответ ACK от приёмника. Вместе с этим начинает нормально работать механизм ретраев и пара модулей будут работать как часы.
PS. Необходимости включать нулевой пайп на приёмнике не описана даже в даташите. Да, там описано, что нужно записать в него правильный адрес, но о необходимости его включить — не слова. А без него передатчик с включёнными ретраями будет считать, что отправка провалена, хоть приёмник посылку и получит.
Вот наверное такое же чувство должны испытывать люди после хорошего психиатра: я по прежнему болен, но теперь хотя бы знаю, как это называется.
Значит вот это всё, потому что я rock star.