Обсуждаем контроллеры компании Atmel.
Ответить

Секундомер на Nrf24l01+

Пт сен 02, 2022 14:19:33

Делаю секундомер на радиосвязи.

Есть 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;
};
Вложения
Лог c millis. Ожидаемый результат 2000мс.txt
Блоки настроены на 2000мс. pong это фиксация пакета который отсылается раз в 333мс для проверки связи.
(5.39 KiB) Скачиваний: 50
Лог без millis. Ожидаемый результат 10000мс.txt
Блоки настроены на 10000мс. pong это фиксация пакета для проверки связи.
(3.39 KiB) Скачиваний: 53

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 15:28:57

не пойму логику работы Секундомера... зачем так делать ?

а что надо ? измерить сколько секунд от старта до финиша ? ну так достаточно сделать два таймера и синхронизировать их по радио... с помощью Nrf24l01...

тут мы делали радиоуправление на Nrf24l01...
https://www.radiokot.ru/forum/viewtopic ... &start=440
там два Nrf24l01 работают синхронно... с точностью до микросекунды ))
PCM-256.jpg
(150.59 KiB) Скачиваний: 64

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 16:12:52

Надо измерить время с момента прерывания на блоке «старт» до момента прерывания на блоке «финиш».
Отобразить результат на блоке «старт»
Передать время на блок «табло» (но это пока меня мало интересует, т.к время фиксируется неточно)

Блок «старт» считает время с момента прерывания. Ждет сигнала с блока «финиш». Как только приходит сигнал - понимает какой номер пакета до него дошел и высчитывает результат.

Что не так в моей логике? В случае с 2 таймерами нужно будет так же ждать радиосигнал с финиша и понимать какой пакет пришел. Нет?

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 16:20:10

синхронизировать часы на обеих блоках и обмениваться лишь данными времени, когда произошло событие, а не моментом события.

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 16:30:08

Спасибо, roman.com и Martian! Пойду переписывать код

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 16:52:37

bootooz писал(а):Блок «старт» считает время с момента прерывания. Ждет сигнала с блока «финиш». Как только приходит сигнал - понимает какой номер пакета до него дошел и высчитывает результат.

:roll:
bootooz писал(а):Что не так в моей логике?

Проблема в том, что пакет может с первого раза не дойти... Nrf24l01 часто теряют пакеты... особенно при слабом сигнале...

По этой причине мы можем сказать точно когда именно произошло прерывание на блоке «финиш»...

Вывод:
1. нужно два таймера: таймер «старт» и таймер «финиш» синхронизировать по радио.
2. блок «финиш» будет передавать только точное время прерывания.
3. блок «старт» будет считать разницу с момента прерывания «старт» до момента прерывания «финиш»:
Секундомер = прерывание «финиш» - прерывания «старт».
:tea:

Re: Секундомер на Nrf24l01+

Пт сен 02, 2022 20:39:48

Спасибо, господа! Помогло!)

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 15:22:15

В общем полёт нормальный, в течение 1.5 часов нет рассинхрона по времени, поэтому достаточно один раз "сверить часы")

Теперь возникла новая проблема. Через разный промежуток времени происходит обрыв связи с одним из модулей. Это точно не зависание МК. Сделал конфигурацию радио-модуля по кнопке. После обрыва связи при конфигурации модуля связь восстанавливается.

Думаю нужно раз в пару секунд считывать все возможные регистры и сравнивать их с установленными при конфигурации.

Может быть есть у кого-то код для автопроверки регистров nrf24l01+?

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 16:27:06

В nRF24L01 есть регистры для подсчета количества неудачных (неподтвержденных) передач на передающей стороне. Читайте этот регистр - ненулевое значение будет показывать ненадежность радиоканала. Возможно, нужно сменить частоту, поскольку в этом же диапазоне работают вай-вай точки, а сейчас в жилых домах их навалом. Лучше nRF модуль загнать на частоту выше 13-го канала вай-фая, установив 2,5 ГГц. (2540 МГц, если на память не ошибаюсь).
И обычные компактные модули без PA и штыревой антенны имеют весьма небольшой радиус действия.
Конечно, секундомер на таких модулях будет иметь запаздывание времени на приемнике, равное сумме времён загрузки в модуль передатчика по интерфейсу, задержке начала передачи, времени передачи по радиоканалу, времени отправке подтверждения приемником, времени реакции МК в приемнике и прочтению из модуля приемника.

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 18:10:27

за всё время работы с Nrf24l01+ никаких проблем не обнаружено...
ни разу ни одного обрыва связи не было...

там же мы подробно разобрали эти модули...
https://www.radiokot.ru/forum/viewtopic ... 8&t=148087

там же есть все нужные регистры...
ATmega8-nRF24L01+.txt
(15.99 KiB) Скачиваний: 58

и т.д.

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 19:13:08

Конечно, секундомер на таких модулях будет иметь запаздывание времени на приемнике, равное сумме времён загрузки в модуль передатчика по интерфейсу, задержке начала передачи, времени передачи по радиоканалу, времени отправке подтверждения приемником, времени реакции МК в приемнике и прочтению из модуля приемника.

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

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 20:22:14

ни разу ни одного обрыва связи не было...

"Не было ни единого разрыва"(С)Уральский (кто помнит, лет 15 назад была хохма).
Отойдите подальше, или за пару стен - и будут вам разрывы связи. Я эти модули вдоль и поперек раньше избороздил, в том числе и LNA+PA+штыревая антенна, в том числе и в многоадресном режиме.

что-то больно много...

Вот как выглядит процесс передачи-приема:
Изображение
а это - при неподтвержденной передаче и автоперезапуске передачи:
Изображение

Добавлено after 7 minutes 16 seconds:
roman.com, код - жэээээсть :))) Ёлы-палы, эт ахтунг

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 20:34:13

MLX90640, так ведь значение времени передаётся, пусть хоть "неделю" ползёт, лишь бы доползло сквозь все тернии

Добавлено after 3 minutes 30 seconds:
да, код - пипец.

Re: Секундомер на Nrf24l01+

Вс сен 04, 2022 20:50:13

А я вот не понял, как делает автор - он каждый раз при неудачной попытке передачи заново загружает новое значение времени и заново пытается передать?
Кстати, из-за наличия трехуровневого FIFO, там есть особенность работы - неподтвержденная передача не удаляет пакет из FIFO. И если не сбросив TX FIFO, пытаться загружать новые данные, то на третий раз FIFO уже переполнится и произойдет то, что автор называет "зависло". В этом же кроется и секрет того, что приходит неверное время - оно из прошлого FIFO может приходить. Переконфиг модуля не нужен. Нужен просто сброс передающего FIFO - команда Flush TX FIFO.

Поэтому, полноценный код при работе с подтверждением передачи должен содержать проверку флагов прерывания IRQ, определение события, вызвавшего прерывание, и выполнение действий по этим событиям. Этих флагов - три штуки - "есть принятые данные", "успешная передача", "достигнуто максим.число повторов передачи". И например, прерывание по достижению макс.числа авторетрансмиттов должно быть обработано сбросом передающего ФИФО и сбросом этого флага. Иначе, последующие загрузки пакетов в модуль будут загружаться в очередь ФИФО, и через три неуспешных передачи модуль просто перестанет принимать новые данные.
Аналогичная фигня происходит и на приемнике, если вовремя не вычитать весь приемный ФИФО - канал остановится, приемник перестанет принимать данные и отправлять подтверждене. Поэтому, читая приемное ФИФО, нужно вычитывать его полностью до ухода бита наличия данных в очереди ФИФО. А если используете разные "трубы" (pipe), то нужно пред чтением пакета прочитать регистр статуса, он содержит информацию о том, к какой "трубе" относятся данные в ячейке ФИФО.
Так что, полноценный код работы с этим трансмиттером имеет довольно сложную структуру.

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 13:32:21

Сделал 2 кнопки.
1. Принт текущих настроек Nrf24l01+
2. Конфигурация Nrf24l01+

Подключил блок который зависал к компу, логирую всё в Serial.

При включении контроллера вывожу в Serial настройки до конфигурации и после.

______________до конфигурации в функции setup():______________
SPI Speedz = 10 Mhz
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 = 0x0000000000 0x0000000000
RX_ADDR_P2-5 = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0000000000
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR = 0x00
RF_CH = 0x00
RF_SETUP = 0x00
CONFIG = 0x00
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1 MBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
ARC = 0

Вывод в hex:
getCRCLength - 0
getChannel - 0
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 0
getARC - 0
getDataRate - 0



_____________после конфигурации в функции setup():_______________
SPI Speedz = 10 Mhz
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x0000000002 0x0000000001
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0000000002
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x77
RF_SETUP = 0x27
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250 KBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
ARC = 0

Вывод в hex:
getCRCLength - 2
getChannel - 77
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 3
getARC - 0
getDataRate - 2


Поймал зависание модуля.
Нажимаю кнопку 1 (вывожу настройки nrf)

SPI Speedz = 10 Mhz
STATUS = 0x2f RX_DR=0 TX_DS=1 MAX_RT=0 RX_P_NO=7 TX_FULL=1
RX_ADDR_P0-1 = 0x0000000002 0x0000000001
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0000000002
RX_PW_P0-6 = 0x20 0x20 0x20 0x00 0x00 0x20
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x77
RF_SETUP = 0x27
CONFIG = 0x00
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250 KBPS
Model = nRF24L01+
CRC Length = Disabled
PA Power = PA_MAX
ARC = 0
Вывод в hex:
getCRCLength - 0
getChannel - 77
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 3
getARC - 0
getDataRate - 2

Нажимаю кнопку 2 (конфигурирую nrf)
Нажимаю кнопку 1 (вывожу настройки nrf)

SPI Speedz = 10 Mhz
STATUS = 0x2e RX_DR=0 TX_DS=1 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x0000000002 0x0000000001
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0000000002
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x77
RF_SETUP = 0x27
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250 KBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
ARC = 0
Вывод в hex:
getCRCLength - 2
getChannel - 77
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 3
getARC - 0
getDataRate - 2


Работа возобновилась.

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 16:10:54

Ох, ну так цифрами то мало чего понятно, мы ж на память то не помним, да еще и переводить в биты. Я ж там написал причины, по которым может быть эффект зависания. Прочитайте регистр Status. У вас он = 0х2F, что говорит о том, что бит 0: TX FIFO full. = 1. Это как раз то, о чем я писал выше. Все три уровня ФИФО передачи заполнены, дальнейшая запись невозможна, требуется команда сброса ФИФО - Flush TX FIFO. Причину этого я описал выше в предыдущем посте. Нужен просто полноценный код, обрабатывающий все три флага прерывания (для передатчика в данном случае - можно только два).

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 20:43:59

Может быть они переполнены потому, что завис модуль?) ("завис" - т.е что-то повлияло на регистры) В общем причина не ясна.

Пока решил этим методом, который запускаю в цикле loop:

Код:
void checkCorrectNRF() {
  static unsigned long lastCheckCrrectNRF;
  bool isReboot = false;
 
  if (millis() - lastCheckCrrectNRF >= 2000) {
    lastCheckCrrectNRF = millis();

    if(radio.failureDetected) {
      configNRF();
      radio.failureDetected = 0;
      isReboot = true;
    } else {
      switch( radio.getCRCLength() ) {
        case RF24_CRC_DISABLED :
          if (millis() - gLastConfigNRF > 2000) {
            isReboot = true;
            configNRF();
          }
        break; // Если полученное значение совпало с константой RF24_CRC_DISABLED
      }
    }

    if (isReboot) { // произошла перезагрузка?
      Serial.println("Ошибка. NRF перезапущен!");
    }

    isReboot = false; // на всякий случай (не кидайте палками.)
  }
}

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 21:02:29

что это ? очередная ардуино ? )) с глючной библиотекой ?

Добавлено after 5 minutes 49 seconds:
а почему нельзя нормально написать ? без глюков ?

Добавлено after 8 minutes 2 seconds:
Поймал зависание модуля.
Нажимаю кнопку 1 (вывожу настройки nrf)

SPI Speedz = 10 Mhz
STATUS = 0x2f RX_DR=0 TX_DS=1 MAX_RT=0 RX_P_NO=7 TX_FULL=1
RX_ADDR_P0-1 = 0x0000000002 0x0000000001
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0000000002
RX_PW_P0-6 = 0x20 0x20 0x20 0x00 0x00 0x20
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x77
RF_SETUP = 0x27
CONFIG = 0x00
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250 KBPS
Model = nRF24L01+
CRC Length = Disabled
PA Power = PA_MAX
ARC = 0
Вывод в hex:
getCRCLength - 0
getChannel - 77
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 3
getARC - 0
getDataRate - 2

Нажимаю кнопку 2 (конфигурирую nrf)
Нажимаю кнопку 1 (вывожу настройки nrf)

SPI Speedz = 10 Mhz
STATUS = 0x2e RX_DR=0 TX_DS=1 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x0000000002 0x0000000001
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0000000002
RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x77
RF_SETUP = 0x27
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250 KBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
ARC = 0
Вывод в hex:
getCRCLength - 2
getChannel - 77
getPayloadSize - 20
getDynamicPayloadSize - 0
getPALevel - 3
getARC - 0
getDataRate - 2


Работа возобновилась.

всё верно.

регистр CONFIG:
// 0... .... 0
// .0.. .... MASK_RX_DR, 1: Interrupt not reflected on the IRQ pin
// ..1. .... MASK_TX_DS, 1: Interrupt not reflected on the IRQ pin
// ...1 .... MASK_MAX_RT, 1: Interrupt not reflected on the IRQ pin
// .... 1... EN_CRC, 1: Enable CRC.
// .... .1.. CRCO, 1: 2 bytes
// .... ..1. PWR_UP, 1: POWER UP, 0:POWER DOWN
// .... ...0 PRIM_RX, 1: RX, 0: TX

если сбросить регистр CONFIG
CONFIG = 0x00

то вместе с ним не будет работать и проверка контрольной суммы СRС-16
CRC Length = Disabled
getCRCLength - 0

а значит ни один пакет не будет принят...
:tea:

а кто сбрасывает регистр CONFIG ? Глючная библиотека Ардуино ? ))

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 21:25:00

За 7688951 миллисекунд (~2 часа) было 4 перезагрузки только на одном из модулей с глючной библиотекой ардуино.

Перезагрузки через разные промежутки времени.

Может напишите свою "не глючную" библиотеку? Буду с удовольствием пользоваться :)

Конечно лучше писать без библиотек. Подумаю над тем чтобы всё переписать) :write: :beer:
Вложения
Screenshot_1.png
(20.94 KiB) Скачиваний: 43

Re: Секундомер на Nrf24l01+

Пн сен 05, 2022 21:38:24

Дело может быть не только в по, но и аппаратно надо проглядеть, фиг знает, мож накапливает-ловит-перегревает чего...
Ответить