Основы работы с nRF24l01
- Войдите на сайт для отправки комментариев
Добрый день, участники форума! Пытаюсь разобраться с радиомодулем nRF24l01. Запустил сканер. Запустил пример Getting Started. Пытаюсь понемногу менять уже работающий код, чтобы понять принципы работы. Хочу изменить скетч Getting Started так, чтобы передавать не число, а символ. Для этого изменил в передатчике код так, чтобы он всегда отсылал в ответ символ "W", а в приемнике изменил код так, чтобы он этот символ выводил:
unsigned long got_time; //Было char send_char = 0; //Стало
Все заработало, но обнаружился неожиданный эффект. Если при передаче числа в оригинальном скетче
выключить передатчик, то приемник соответствено отображает ответ "ноль" и показывает задержку ответа.
Now sending
Sent 6055876, Got response 6055876, Round-trip delay 1128 microseconds
Now sending
failed
Failed, response timed out.
Sent 7058768, Got response 0, Round-trip delay 268520 microseconds
А если передавать символ, то он вылезает в сериал в любом случае, даже после отключения передатчика. Вот, видно, что передатчик отключен, время ответа очень большое, но символ все равно вылезает.
Sent 8126712, Got response W, Round-trip delay 1080 microseconds
Now sending
failed
Failed, response timed out.
Sent 9129208, Got response W, Round-trip delay 268512 microseconds
Из-за чего это может быть? И как с этим бороться? На Амперке не ответили :(.
Очевидно какой-то переменной присваивается значение "W" и так и торчит в приемнике и не изменяется. Скорее всего после первого вывода на экран это значение сразу надо заменить на "", а уж после этого вновь считывать.
Что вы таким образом хотите выяснить? Скорее всего ситуация в выключением передатчика на ходу никак не обрабатывается в библиотеке и/или вышем коде. Соответственно, результат плохо предсказуем. Так можно дойти до экспериментов, навроде удара топором поперек ардуины, и тоже потом пытаться искать объяснения непонятному поведению программы.
Прошу прощения, конечно, надо было сразу приложить скетчи. Но к вечеру в голове образовалась каша. Выкладывю код приемника и передатчика. За основу взят пример Getting Started из библиотеки TMRh20. Обработки ситуации, когда приходит ноль в этом коде нет, но и вопрос то в том, что ноль не приходит.
Передатчик получает сигнал от приемника и отправляет ответ. Если этот ответ unsigned long, то все работает как надо. Передатчик отключен, передатчик выводит в сериал ноль. С char приемник выводит в сериал постоянное значение, хотя при его перезагрузке выводит снова ноль. Я так понимаю дело в каких-то буферах, где остется полученное значение, но я не могу понять где. И опять же, с unsigned long все работает как надо.
Передатчик
Приемник
Ну и сравнение с битьем топором я совершенно не понял. По моему вполне разумное желание понять, что происходит с приемником, если передатчик по какой-то причине выходит из строя.
Вы продолжаете упорствовать в бессмысленных действиях. Приемник у вас не сообщил о поступлении новых данных, из цикла ожидания вы вываливаетесь по таймауту, но при этом зачем-то лезете читать приемный буфер. Что вы там ожидаете обнаружить? Внеземное послание? Если не выполнялась команда FLUSH_RX (а у вас она не выполнялась), то в ответ на команду чтения приемного буфера, приемник будет всегда возвращать последние корректно принятые данные. Если компанда FLUSH_RX выполнялась, то возвращаемым значением будут нули.
Смысл в сравнимой пользе от такоего эксперимента. То есть полном отсутствии таковой.
В даташите на NRF24L01 подробно описано, как приемник производит декодирование эфирного сигнала. Уверяю, что своим могучим экспериментом вы ни на миллиметр не приблизились к пониманию логики работы приемника.
Если описать вкратце, то приемник работает так: слушает эфир на выбранном канале и при обнаружении данных на несущей чавтоте начинает побитово их запихивать в сдвиговый регистр входного буфера. После каждого бита приемник анализирует, находится ли в буфере корректный заголовок пакета, соответствует ли адрес получателя его собственному адресу, правильно ли указана длина принятых данных и совпадает ли контрольная сумма. Если хотя бы что-то в принятых данных не соответствует ожиданиями приемника (ваш случай с прерыванием передачи), то приемник не предпринимает никаких действий, а продолжает заниматься тем, чем и занимался -- слушать эфир, запихивать биты в регистр и анализировать принятое. Если приемник обнаруживает, что во входном буфере все данные корректны, он переносит их в приемный буфер, который доступен для чтения извне (в данном случае ардуиной) и сигнализирует в статусе, что принят пакет данных, попутно отправив подтверждение передатчику, если последний его запрашивал.
Используемая вами библиотека написана таким образом, что функция radio.available() запрашивает статус модуля и если там утстановлен бит наличия принятых данных, то она возвращает TRUE, иначе FALSE.
Внеся правку в исходный код примера, вы нарушили логику его работы. В примере чтение данных выполнялось так:
Т.е. чтение буфера приема осуществлялось только в случае, если выход из цикла ожидания происходил не по условию наступления таймаута. Вы вынесли весь блок else, который выполнялся только при условии успешного приема, в основной программный код и у вас чтение буфера производится всегда, вне зависимости от того, реально ли были приняты даннные или нет.
Ну и нечего тогда удивляться, что считываются старые данные, которые завалялись в буфере приема.
Логика программы была изменена специально, чтобы посмотреть, как реагирует приемник на, например такую ситуацию, когда передатчик доступен, но ничего не шлет. Про оставание в буфере последнего значения я знал, но я также и был абсолютно уверен, что функция очистки буфера FLUSH_RX вызывается внутри функций StartListening и StopListening. После Вашего ответа я в сотый раз открыл rf24.cpp, чтобы найти этот кусок и доказать Вам, что Вы неправы и проблема гораздо глубже и сложнее... и обнаружил, что FLUSH_RX закомменитрована. После того, как я ее раскомментил, все очищается как положено.
Большое спасибо за уделенное мне внимание. Надеюсь Вас это не сильно затруднило. Еще раз благодарю Вас за помощь,
У приемника нет никакой возможности судить о состоянии передатчика, если тот не передает данные. Передатчик включает радиотракт только на время передачи пакета и автоматически выключает его сразу же, как только передача данных завершилась и все три буфера передачи остаются пустыми. В паузах между передачами в эфир не выдается даже несущая. Работу передатчика можно сделать более продолжительной, если оперативно подбрасывать в буфера передачи свежие данные. Но даже так нельзя заставить работать передатчик постоянно. NRF24L01 имеет аппаратное ограничение времени одного сеанса передачи в 4 миллисекунды.