Есть 3 модуля связанные по nrf24l01. Подтверждение отключено везде. Речь пойдет только о двух модулях.
Старт постоянно принимает. Финиш постоянно передает. Отсылаю 20 пакетов с номером попытки отправки один раз в 200 миллисекунд.
Если на приемник приходит 0й пакет - задержки на попытку не было (можно пренебречь), время не компенсируем.
Если 0й потерялся, а пришел 1й пакет - компенсируем 200мс т.к передатчик затратил это время на ожидание между попытками.
Проблема в том, что 1й пакет приходит раньше 200мс и время компенсируется с избытком.
Например, модули настроены на авто-тестирование. Нажимают «старт-финиш» автоматом со строго определёнными интервалами. Настроены на результат 10000мс.
Когда приходит попытка 0 - результат фиксируется от 10003-9999 (это устраивает)
Когда приходит попытка 1 - результат фиксируется 10158-10161. (Хотя на передатчике настроено 200мс между попытками)
Когда приходит попытка 2 - результат фиксируется 10352-10353
Лог с приёмника приложил.
Команда отправки: radio.writeFast(&data, sizeof(data)); В data лежит структура вида: struct FinStruct { unsigned long finishID; byte tryNumber; int finishPacketCode; };
Вложения:
Комментарий к файлу: Блоки настроены на 2000мс. pong это фиксация пакета который отсылается раз в 333мс для проверки связи. Лог c millis. Ожидаемый результат 2000мс.txt [5.39 KiB]
Скачиваний: 50
не пойму логику работы Секундомера... зачем так делать ?
а что надо ? измерить сколько секунд от старта до финиша ? ну так достаточно сделать два таймера и синхронизировать их по радио... с помощью Nrf24l01...
Надо измерить время с момента прерывания на блоке «старт» до момента прерывания на блоке «финиш». Отобразить результат на блоке «старт» Передать время на блок «табло» (но это пока меня мало интересует, т.к время фиксируется неточно)
Блок «старт» считает время с момента прерывания. Ждет сигнала с блока «финиш». Как только приходит сигнал - понимает какой номер пакета до него дошел и высчитывает результат.
Что не так в моей логике? В случае с 2 таймерами нужно будет так же ждать радиосигнал с финиша и понимать какой пакет пришел. Нет?
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Блок «старт» считает время с момента прерывания. Ждет сигнала с блока «финиш». Как только приходит сигнал - понимает какой номер пакета до него дошел и высчитывает результат.
bootooz писал(а):
Что не так в моей логике?
Проблема в том, что пакет может с первого раза не дойти... Nrf24l01 часто теряют пакеты... особенно при слабом сигнале...
По этой причине мы можем сказать точно когда именно произошло прерывание на блоке «финиш»...
Вывод: 1. нужно два таймера: таймер «старт» и таймер «финиш» синхронизировать по радио. 2. блок «финиш» будет передавать только точное время прерывания. 3. блок «старт» будет считать разницу с момента прерывания «старт» до момента прерывания «финиш»: Секундомер = прерывание «финиш» - прерывания «старт».
В общем полёт нормальный, в течение 1.5 часов нет рассинхрона по времени, поэтому достаточно один раз "сверить часы")
Теперь возникла новая проблема. Через разный промежуток времени происходит обрыв связи с одним из модулей. Это точно не зависание МК. Сделал конфигурацию радио-модуля по кнопке. После обрыва связи при конфигурации модуля связь восстанавливается.
Думаю нужно раз в пару секунд считывать все возможные регистры и сравнивать их с установленными при конфигурации.
Может быть есть у кого-то код для автопроверки регистров nrf24l01+?
В nRF24L01 есть регистры для подсчета количества неудачных (неподтвержденных) передач на передающей стороне. Читайте этот регистр - ненулевое значение будет показывать ненадежность радиоканала. Возможно, нужно сменить частоту, поскольку в этом же диапазоне работают вай-вай точки, а сейчас в жилых домах их навалом. Лучше nRF модуль загнать на частоту выше 13-го канала вай-фая, установив 2,5 ГГц. (2540 МГц, если на память не ошибаюсь). И обычные компактные модули без PA и штыревой антенны имеют весьма небольшой радиус действия. Конечно, секундомер на таких модулях будет иметь запаздывание времени на приемнике, равное сумме времён загрузки в модуль передатчика по интерфейсу, задержке начала передачи, времени передачи по радиоканалу, времени отправке подтверждения приемником, времени реакции МК в приемнике и прочтению из модуля приемника.
Конечно, секундомер на таких модулях будет иметь запаздывание времени на приемнике, равное сумме времён загрузки в модуль передатчика по интерфейсу, задержке начала передачи, времени передачи по радиоканалу, времени отправке подтверждения приемником, времени реакции МК в приемнике и прочтению из модуля приемника.
что-то больно много... полагаю, перед работой их можно поставить рядом и запустить синхронизацию по проводку, в этом случае задержка лишь на обработку этого события, а её можно даже посчитать. Остальное расхождение будет только из-за уплывания частот, но если термостатировать всё это дело да ещё сравнить в течение долгого периода и вычислить некоторые поправки, то, наверное можно на пару порядков лучше требуемого получить результат.
"Не было ни единого разрыва"(С)Уральский (кто помнит, лет 15 назад была хохма). Отойдите подальше, или за пару стен - и будут вам разрывы связи. Я эти модули вдоль и поперек раньше избороздил, в том числе и LNA+PA+штыревая антенна, в том числе и в многоадресном режиме.
Цитата:
что-то больно много...
Вот как выглядит процесс передачи-приема: а это - при неподтвержденной передаче и автоперезапуске передачи:
Добавлено after 7 minutes 16 seconds: roman.com, код - жэээээсть Ёлы-палы, эт ахтунг
А я вот не понял, как делает автор - он каждый раз при неудачной попытке передачи заново загружает новое значение времени и заново пытается передать? Кстати, из-за наличия трехуровневого FIFO, там есть особенность работы - неподтвержденная передача не удаляет пакет из FIFO. И если не сбросив TX FIFO, пытаться загружать новые данные, то на третий раз FIFO уже переполнится и произойдет то, что автор называет "зависло". В этом же кроется и секрет того, что приходит неверное время - оно из прошлого FIFO может приходить. Переконфиг модуля не нужен. Нужен просто сброс передающего FIFO - команда Flush TX FIFO.
Поэтому, полноценный код при работе с подтверждением передачи должен содержать проверку флагов прерывания IRQ, определение события, вызвавшего прерывание, и выполнение действий по этим событиям. Этих флагов - три штуки - "есть принятые данные", "успешная передача", "достигнуто максим.число повторов передачи". И например, прерывание по достижению макс.числа авторетрансмиттов должно быть обработано сбросом передающего ФИФО и сбросом этого флага. Иначе, последующие загрузки пакетов в модуль будут загружаться в очередь ФИФО, и через три неуспешных передачи модуль просто перестанет принимать новые данные. Аналогичная фигня происходит и на приемнике, если вовремя не вычитать весь приемный ФИФО - канал остановится, приемник перестанет принимать данные и отправлять подтверждене. Поэтому, читая приемное ФИФО, нужно вычитывать его полностью до ухода бита наличия данных в очереди ФИФО. А если используете разные "трубы" (pipe), то нужно пред чтением пакета прочитать регистр статуса, он содержит информацию о том, к какой "трубе" относятся данные в ячейке ФИФО. Так что, полноценный код работы с этим трансмиттером имеет довольно сложную структуру.
Ох, ну так цифрами то мало чего понятно, мы ж на память то не помним, да еще и переводить в биты. Я ж там написал причины, по которым может быть эффект зависания. Прочитайте регистр Status. У вас он = 0х2F, что говорит о том, что бит 0: TX FIFO full. = 1. Это как раз то, о чем я писал выше. Все три уровня ФИФО передачи заполнены, дальнейшая запись невозможна, требуется команда сброса ФИФО - Flush TX FIFO. Причину этого я описал выше в предыдущем посте. Нужен просто полноценный код, обрабатывающий все три флага прерывания (для передатчика в данном случае - можно только два).
Сейчас этот форум просматривают: Demiurg и гости: 29
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения