Проблема с nRF24l01

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

конденсатор обязателен , хоть и 10см, хоть 10м

svm
Offline
Зарегистрирован: 06.11.2016

Jon2013 пишет:

Все же грешу на библиотеки.

Условия для тестирования идиальные: 5В и 3.3В лаб. БП. Конденсаторы, экранировку модуля не рассматриваю как не существенное для теста на столе с растоянием 10 см друг от друга. Модули и Ардуинки из одной партии. Тесты модулей, сети, каналов все проходит на ура.

Самое главное: система заводится. 3 сообшения проходят отлично. Причем, всегда строго 3 шт, а потом на передатчике модуль отваливается, вижу по амперметру: на БП - потребление в ноль. Ардуинка переходит в неуправляемый бесконечный цикл, так как будто непрерывно идет сообщение с модуля. Такое ощущение что переполняется буфер radio.available() . Получается что функция  radio.read( &command, sizeof(command) не очищает буфер до конца. Или я не в ту сторону копаю?

  

Расположение модулей на расстоянии 10 см, не гарантирует идеальных условий, а может сыграть отрицательную роль. Лучше разнести хотя-бы метра на два. Конденсатор обязателен.

Буфера обмена перед сеансом связи лучше чистить принудительно командами flush_rx  и  flush_tx. Режим подтверждения приема лучше отключить (хотя-бы на этапе экспириментов). Экранирование модулей позволяет избавиться от влияния рук и взаимного расположения отдельных частей устройства на качество связи, что довольно часто сбивает с толка.

Я в начале тоже пытался перебирать библиотеки, но большого эффекта не было. Сейчас тупо делаю 50 попыток (хотя реально устойчивый отклик максимум с третьей попытки получается). Ввел дополнительный параметр, который изменяется при каждом сеансе связи, т.к. в начале было, что вроде данные получены как-бы нормальные, но они от предыдущего сеанса связи (хотя буфер очищался ???).

Теперь базовый блок работает с четырьмя подчиненными, один в 70 метрах, один за металлической стеной и два в подвале бод бетонными перекрытиями на расстоянии 10-15 метров. За пару месяцев не было ни одного сбоя. Даже при кратковременном отключении питания или сбросе подчиненного устройства, данные не пропадают. Правда у меня нет ограничений на время отклика, и задержка на 1-2 сек некритична.

Вот кусок кода базового блока отвечающий за радиообмен. Он передает 16 параметров одному из подчиненных устройств и получает от них ответ:

//*********************               Радиообмен              **************************************
r_obmen:
Repit=0;                                                //Счетчик попыток

 // ********************** передача команды ********************* 
  j++; if(j==99)j=0;data[15]=j;                         // Вспомогательный параметр изменяется при каждой передаче
repit:
  Repit++;                                              //Счетчик попыток
  radio.flush_rx();                                     //Чистим буфера
  radio.flush_tx();
  done_R=0;
  radio.stopListening   ();                              // передача
  delay(15);
  radio.write(&data, sizeof(data));
  // ********************** прием ответа ********************* 
  radio.startListening  (); delay(25);                   // переключаемся на прием < 20 - нет приема при больших - задержка
  if(radio.available()){                                 // Что-то прилетело?
  done_R=radio.read(&datarx, sizeof(datarx));   
  if (!done_R)goto repit;                                //если не приняты данные - повторить
  if(data[15]!=datarx[15])goto repit;                    //если приняты не те данные - повторить
  radio.stopListening   ();
  }                                                      
  if (!done_R && Repit < 50) goto repit;                 // повторить попытку 50 раз

Библиотека эта: https://yadi.sk/d/X3Ycd1B-hBHnYw   различия с библиотекой из #51 большие.

А это ответная часть, по сути радиомост между базовым блоком и блоком управления, с которым он общается по сериалу.




// Радиоканал

#include <nRF24L01.h>                                     // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                                         // Подключаем библиотеку  для работы с nRF24L01+
RF24           radio(9, 10);                              // Создаём объект radio   для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)


static byte           data[16],datatx[16],i;                              // Создаём массив для приёма данных
unsigned long T_Out;
bool done_rx,done_tx;

void setup() {
   delay(300);
    
    Serial.begin(115200);
    Serial.print("START");
  
    radio.begin();                                        // Инициируем работу nRF24L01+
    radio.setChannel(105);                                // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
    radio.setRetries(15,15);                              // Установка интервала и количества попыток "дозвона" до приемника;
    radio.setDataRate     (RF24_250KBPS);                 // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек 
    radio.setPALevel      (RF24_PA_HIGH);                 // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
    radio.setAutoAck(0);                                  // Установка режима подтверждения приема;
    radio.openWritingPipe(0xE8E8F0F0E1LL);                // Активация данных для отправки
    radio.openReadingPipe (1, 0xE8E8F0F0E1LL);            // Открываем 1 трубу с идентификатором 0xE8E8F0F0E1LL для приема данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
    radio.startListening  ();                             // Включаем приемник, начинаем прослушивать открытую трубу
}
//********************************************************************************
void loop(){
ns:            // ------------ Слушаем эфир ----------------
   T_Out=millis();
  bool done_rx = false;
  if(radio.available()){                                  // Если в буфере имеются принятые данные
  while (!done_rx) {done_rx=radio.read(&data, 16);}}      // Уперто читаем данные в массив data 
  if(!done_rx && (millis()-T_Out)<2000){goto ns;}         //при отключенном подтверждении наверное не работает
  for (i=0; i <= 15; i++){if(data[i]==255)data[i]=99;}
  radio.flush_rx();
  radio.stopListening   ();                               // встаем на передачу
 if(data[0]==115||data[0]==60||data[0]==63){              // если в D0 допустимая команда 
  for (i=0; i <= 15; i++){Serial.write(data[i]);}}        // передаем БУ
 delay(15);
               // ------------ Передаем ответ  ----------------
  radio.flush_tx();
  done_tx = false;
  T_Out=millis(); 
 //if(Serial.available()>0){                              // если есть ответ от БУ
 //for (i=0; i <= 15; i++){datatx[i]=Serial.read();}}
 
  for (i=0; i <= 15; i++){datatx[i]=data[i];}             // Имитация ответа от БУ
  datatx[1]=1;                                            //просто данные для теста
  datatx[2]=2;
  datatx[3]=3;
  datatx[5]=56;
  
  while (!done_tx && (millis()-T_Out)<2000){              //в течении 2 секунд долбим
  done_tx=radio.write(&datatx, 16);}                      //при отключенном подтверждении наверное не работает
  radio.startListening  (); 
}             
 
 
Jon2013
Offline
Зарегистрирован: 18.12.2013

Волшебная команда: radio.flush_rx(); помогла очистить буфер и все стабильно стало работать. С библиотекой RF24-мастер модуль не заводилася. Предыдущая библиотека (пост#51) не имела команду на очистку буфера. Скачал версию из стандартных обновлений RF24 by TMRh20 вот с ней все срослось. 

Спасибо всем за помощь.

svm
Offline
Зарегистрирован: 06.11.2016

На всякий случай выложи ссылку, чтобы вслепую не тыкаться.

Jon2013
Offline
Зарегистрирован: 18.12.2013

я либу взял через управление библиотеками из среды программирования Arduino IDE. Именно так она там и называется из всего зоопарка который там есть: RF24 by TMRh20

maks100
Offline
Зарегистрирован: 15.04.2017

Последнею неделю игрался с данными модулями, пришел к выводу что обязательно нужно модули припаивать (да да стандартные ардуино коннекторы что мы все так используем не вариант ), иначе  никак...Обязательный конденсатор непосредственно напаянный на сам модуль.

Maksim1
Offline
Зарегистрирован: 06.07.2018

Добавлю пару слов о питании данного модуля (с антенной). Все пишут что нужно запитываться от отдельного источника питания. Так то оно может и так, только в проектах уж сильно жирно получается и по стоимости и по габаритам. Я же решил в своем проекте (где дальность - 150м мне достаточно) просто напаять конденсатор 47мкф, а дальше баловаться с кодом. Не экранировал, все по дефолту, питание 3,3В от нано. И получилось: нужно выставить 250 скорость и LOW питание. Провел при данных настройках тест. При выходе из квартиры до открытой местности (не знаю сколько там бетонных блоков) связь ни разу не прервалась. И дальше на открытой местности (ну как открытая, деревья конечно были) я получил около 200м стабильной связи. Модули брал вот эти: тык.

И еще вопрос - вот допустим вы хотите использовать данный передатчик в совокупности и сериал портом. От чего запитываться? Паять к юсб порту отдельный разветвитель для питания? Или как?

И вообще, сколько разных форумов с обсуждением данной темы и неужели китайцы еще не придумали плату, где все проблемы решены? Никто не интересовался?

sadman41
Offline
Зарегистрирован: 19.10.2016

Не знаю, что вы представляете себе под такой платой, но у роботдина есть вайрлесс шилд под нано. Там уже и конденсатор и стабилизатор на борту. Правда, по традиции, нрф-ка на весу находится.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Я это представляю как отдельный стабилизатор на 3.3В с конденсатором, обычно ams1117 и все.

Иван89
Offline
Зарегистрирован: 24.02.2019

Доброго времени. Сказано было очень много интересного, но вот послушайте. Вышеуказанный модуль, DC-DC (5 на 3.4В) и ардуино-нано. Аналогично предыдущим есть прослушка  диапазонов у обоих модулей. Оба модуля раотают в режиме приема, ну как работают, показывают что принят "0". Проблема  заключается в том, что при использовании одного из модулей в качестве "передатчика", скорость его работы сильно падает, если только об этом можно судить по монитору внутреннего порта. При касании пальцем 12го вывода дуньки, скорость резко возрастает и впринципе совпадает со скоростью указанной в видеоуроке. Не понимаю в какую сторону копать. Да, при закоментивании процедуры записи (radio.write(&counter...), в монитор порта поступают данные с правильной скоростью.

GarlenX
Offline
Зарегистрирован: 09.03.2019

Доброе утро... у меня проблемка с НРФками возникла... Уже какую неделю с ними мучаюсь... припаял конденсаторы, подключил, проверил скетчем, вроде они опознаются... но когда отправляю команды, то ничего не происходит... сигнала нет... Вы не могли бы подсказать в какую сторону копать?

zjiode1
Offline
Зарегистрирован: 06.05.2019

Есть ли кто-то , у кого имеется опыт работы с NRF24L01+ и соответсвенно ардуино, помочь с написанием скетча для проекта за рузмуную плату?

Walrus
Offline
Зарегистрирован: 05.08.2019

ПРОСЬБА ПОДСКАЗАТЬ НАЧИНАЮЩЕМУ. ПРИ ТЕСТИРОВАНИИ NRF 24L01 МОНИТОР ПОРТА ВЫДАЁТ СООБЩЕНИЕ:

 

ЧТО ОБОЗНАЧАЕТ ЭТО СООБЩЕНИЕ?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ТЫ ЕГО САМ-ТО МОЖЕШЬ ТУТ РАЗГЛЯДЕТЬ?  

СКОПИРУЙ И ВСТАВЬ, МАТЬТВАЮ.  И свои буквы поменьше сделай

Walrus
Offline
Зарегистрирован: 05.08.2019

http://arduino.ru/sites/default/files/u49171/monitor.jpg

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ок. Это неизлечимо.  Вернее, непомогабельно. 

Green
Offline
Зарегистрирован: 01.10.2015

Мышкой по экрану клац, затем CTRL+A CTRL+C и через CTRL+V вставил в форум. Это ж азы!

b707
Offline
Зарегистрирован: 26.05.2017

Walrus - судя по выводу, это пример из библиотеки. И там написано. для чего он и что вывдает.

А вы что получить то пытаетесь?

Walrus
Offline
Зарегистрирован: 05.08.2019

Монитор порта выдает нули  ( TX_ADDR = 0x010000 c 00c?   RX_PW_P0_6 = 0X00 0x00 0x00 итд)     и     и CRC Length - Disabled .

Почему?

b707
Offline
Зарегистрирован: 26.05.2017

Walrus пишет:

Монитор порта выдает нули  ( TX_ADDR = 0x010000 c 00c?   RX_PW_P0_6 = 0X00 0x00 0x00 итд)     и     и CRC Length - Disabled .

Почему?

может вы все-таки выложите вывод программы как текст, а то и правда на картинке нифига не видно.

Что за привычка постить скриншоты? -

Walrus
Offline
Зарегистрирован: 05.08.2019

монитор порта

 

19:28:27.497 -> STATUS         = 0x06 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=3 TX_FULL=0
19:28:27.543 -> RX_ADDR_P0-1     = 0x2020270610 0x2020270610
19:28:27.590 -> RX_ADDR_P2-5     = 0x41 0x40 0x40 0x42
19:28:27.637 -> TX_ADDR         = 0x2020270610
19:28:27.684 -> RX_PW_P0-6     = 0x00 0x00 0x00 0x00 0x00 0x00
19:28:27.731 -> EN_AA         = 0x00
19:28:27.731 -> EN_RXADDR     = 0x00
19:28:27.731 -> RF_CH         = 0x04
19:28:27.778 -> RF_SETUP     = 0x00
19:28:27.778 -> CONFIG         = 0x00
19:28:27.825 -> DYNPD/FEATURE     = 0x00 0x00
19:28:27.825 -> Data Rate     = 1MBPS
19:28:27.825 -> Model         = nRF24L01
19:28:27.872 -> CRC Length     = Disabled
19:28:27.918 -> PA Power     = PA_MIN
19:28:32.888 -> 00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777777
19:28:33.029 ->  0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
19:28:33.123 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19:29:44.666 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19:30:56.196 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19:32:07.763 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19:33:19.327 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19:34:30.876 ->  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Walrus
Offline
Зарегистрирован: 05.08.2019

скетч

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

//RF24 radio(8,7); // Для Уно
RF24 radio(7,8);// Для Меги
const uint8_t num_channels = 128;
uint8_t values[num_channels];
void setup(void)
{
  Serial.begin(9600);
  printf_begin();
  radio.begin();
  radio.setAutoAck(false);
  radio.startListening();

  radio.printDetails();  // Вот эта строка напечатает нам что-то, если все правильно соединили.
  delay(5000);              // И посмотрим на это пять секунд.

  radio.stopListening();
  int i = 0;    // А это напечатает нам заголовки всех 127 каналов
  while ( i < num_channels )  {
    printf("%x",i>>4);
    ++i;
  }
  printf("\n\r");
  i = 0;
  while ( i < num_channels ) {
    printf("%x",i&0xf);
    ++i;
  }
  printf("\n\r");
}
const int num_reps = 100;

void loop(void)
{
  memset(values,0,sizeof(values));
  int rep_counter = num_reps;
  while (rep_counter--) {
    int i = num_channels;
    while (i--) {
      radio.setChannel(i);
      radio.startListening();
      delayMicroseconds(128);
      radio.stopListening();
      if ( radio.testCarrier() )
        ++values[i];
    }
  }
  int i = 0;
  while ( i < num_channels ) {
    printf("%x",min(0xf,values[i]&0xf));
    ++i;
  }
  printf("\n\r");
}
int serial_putc( char c, FILE * ) {
  Serial.write( c );
  return c;
}

void printf_begin(void) {
  fdevopen( &serial_putc, 0 );
}

b707
Offline
Зарегистрирован: 26.05.2017

Walrus, cудя по выводу в порт, данные с чипа вы получаете успешно, то есть по подключению проблем нет. А вот с приемом у вас хуже. Либо модули поддельные с очень низкой чувствительностью, либо в настройках косяк.