nRF24L01+ : побеждаем модуль.

Тема в разделе "Проводная и беспроводная связь", создана пользователем ИгорьК, 19 июн 2014.

  1. Delta36652

    Delta36652 Нуб

    Сейчас посидел помедитировал , поизгибал антенны под всякими углами и связь на 250 kbps и PA_MAX заработала(о чудо!). Но вот как заставить ее работать под любыми углами изгиба?
    PS Открутил антенну от модуля и прозвонил тестером ту фигню, куда антенна крепится(не знаю, как оно называется...). Оказалась странная вещь: внутренний контакт(гнездо?) прекрасно звонится с корпусом данной штуки. Ситуация такая же и на втором модуле. Это так и должно быть?
    PS2
    В режиме 250kbps PA_MAX одел на каждую антенну "шапочку" из фольги. Связь стала почти идеальной. Как объяснить - не знаю.
     
    Последнее редактирование: 13 янв 2017
  2. sslobodyan

    sslobodyan Гик

    Да, выход сделан под 50 ом. На высоких частотах это очень большое сопротивление, все нормально.
    Значит модули близко, сигнал передающего очень сильный и "оглушает" приемник. Разнесите их хотя бы на 2-3 метра и увидите разницу. А "шапочке" приглушила уровень как передатчика, так и приемника, что позволило приемнику "войти в норму".
     
  3. Delta36652

    Delta36652 Нуб

    Разнес, изменений не увидел. Снова все решается колдунством над антеннами. Тут еще выясняется, что один модуль передает гораздо лучше другого, а другой сам почти ничего отправлять не может(на PA_MAX), а потом выясняется, что если его перевернуть антенной вниз и написать другую программу(полудуплекс), то оно вроде как работает. Взрыв мозга короче...
    Как разобрать антенну? Гугление ничего не дало(по советам из гугла не разбирается).
     
  4. sslobodyan

    sslobodyan Гик

    У меня антенки разъединялись после сгибания. Опять предлагаю разобрать их и пропаять. Сам наступал, знаю. Тоже грешил на код, а оказался непропай.
     
  5. Delta36652

    Delta36652 Нуб

    Разобрал, уже были пропаяны. Пропаял еще раз прикрутил. На PA_MAX ситуация чуть-чуть улучшилась, но не намного.(И снова только под определенными углами)
     
  6. sslobodyan

    sslobodyan Гик

    Вариантов кроме как искать пару других рабочих антенн, я не вижу. Код здесь не поможет, только харкор ;)
     
  7. sergey-fedor

    sergey-fedor Нерд

    Уважаемые победители :)) Подскажите не сталкивались ли с такой ситуацией : два модуля с антеннами работали замечательно на протяжении нескольких месяцев - и вдруг связь пропала. Пока дошли до них руки прошил простейшие скетчи на прием и отправку 1 символа, чисто проверить связь , дак вот один из модулей совсем не хочет ничего отправлять , принимает идеально , а отправлять не хочет! такое бывает? чтобы модуль сломался наполовину :)) Этот модуль висит на улице и пережил уже морозы в -42 градуса, а помер как то бесславно в -15 и то на половину только :))
     
  8. Oleg_7

    Oleg_7 Гик

    Добрый день,! ) Вопрос по прослушке нескольких труб, упрощенный код:
    Код (C++):
    передатчик:
    uint64_t pipe_[5] = {0xAABBCCDD00LL, 0xAABBCCDD11LL,0xAABBCCDD22LL, 0xAABBCCDD33LL,0xAABBCCDD44LL};
    ......
    radio.openWritingPipe(pipe_[2]);
    radio.write(&this_myroom, sizeof(myroom))

    приемник:
    uint64_t pipe_[5] = {0xAABBCCDD00LL, 0xAABBCCDD11LL,0xAABBCCDD22LL, 0xAABBCCDD33LL,0xAABBCCDD44LL};
    ......
    radio.openReadingPipe(2,pipe_[2])
    ......
    if (radio.available(&pipeNum))
    {
      serial.println(pipeNum);
    }
    Так вот, приема - НЕТ !)) А начинает принимать и только если заменить на radio.openReadingPipe(1,pipe_[2]), и соответственно в сериал порте видим единицу! Подскажите, в чем может быть дело? Кто-нибудь имел дело с приемом по нескольким трубам? )
     
  9. АнтонCnC

    АнтонCnC Нуб

    Здравствуйте. Работоспособность модулей вроде в порядке, точно не знаю первый раз с ними работаю. Модули китайские. В паре работать не хотят, не как я их не подружу.[​IMG][​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"

    RF24 radio(9,10); // Для Уно
    //RF24 radio(9,53);// Для Меги
    const uint8_t num_channels = 128;
    uint8_t values[num_channels];
    void setup(void)
    {
      Serial.begin(57600);
      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 );
    }
     
    На пару не работают, что-то не понятное.
    Код (C++):
    /*
       March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
       Parts derived from examples by J. Coliz <maniacbug@ymail.com>
    */

    /**
    * Example for efficient call-response using ack-payloads
    *
    * This example continues to make use of all the normal functionality of the radios including
    * the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well.
    * This allows very fast call-response communication, with the responding radio never having to
    * switch out of Primary Receiver mode to send back a payload, but having the option to switch to
    * primary transmitter if wanting to initiate communication instead of respond to a commmunication.
    */

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

    // Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10
    RF24 radio(9,10);
                                                                               // Topology
    byte addresses[][6] = {"1Node","2Node"};              // Radio pipe addresses for the 2 nodes to communicate.

    // Role management: Set up role.  This sketch uses the same software for all the nodes
    // in this system.  Doing so greatly simplifies testing.
    typedef enum { role_ping_out = 1, role_pong_back } role_e;                 // The various roles supported by this sketch
    const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};  // The debug-friendly names of those roles
    role_e role = role_pong_back;                                              // The role of the current running sketch

    byte counter = 1;                                                          // A single byte to keep track of the data being sent back and forth


    void setup(){

      Serial.begin(9600);
      printf_begin();
      printf("\n\rRF24/examples/GettingStarted/\n\r");
      printf("ROLE: %s\n\r",role_friendly_name[role]);
      printf("*** PRESS 'T' to begin transmitting to the other node\n\r");

      // Setup and configure radio

      radio.begin();
      radio.setAutoAck(1);                    // Ensure autoACK is enabled
      radio.enableAckPayload();               // Allow optional ack payloads
      radio.setRetries(0,15);                 // Smallest time between retries, max no. of retries
      radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
      radio.openWritingPipe(addresses[1]);        // Both radios listen on the same pipes by default, and switch when writing
      radio.openReadingPipe(1,addresses[0]);      // Open a reading pipe on address 0, pipe 1
      radio.startListening();                 // Start listening
      radio.powerUp();
      radio.printDetails();                   // Dump the configuration of the rf unit for debugging
    }

    void loop(void) {

     
    /****************** Ping Out Role ***************************/

      if (role == role_ping_out){                               // Radio is in ping mode

        byte gotByte;                                           // Initialize a variable for the incoming response
       
        radio.stopListening();                                  // First, stop listening so we can talk.    
        printf("Now sending %d as payload. ",counter);          // Use a simple byte counter as payload
        unsigned long time = micros();                          // Record the current microsecond count  
                                                               
        if ( radio.write(&counter,1) ){                         // Send the counter variable to the other radio
            if(!radio.available()){                             // If nothing in the buffer, we got an ack but it is blank
                printf("Got blank response. round-trip delay: %lu microseconds\n\r",micros()-time);    
            }else{    
                while(radio.available() ){                      // If an ack with payload was received
                    radio.read( &gotByte, 1 );                  // Read it, and display the response time
                    printf("Got response %d, round-trip delay: %lu microseconds\n\r",gotByte,micros()-time);
                    counter++;                                  // Increment the counter variable
                }
            }
       
        }else{        printf("Sending failed.\n\r"); }          // If no ack response, sending failed
       
        delay(1000);  // Try again later
      }


    /****************** Pong Back Role ***************************/

      if ( role == role_pong_back ) {
        byte pipeNo, gotByte;                          // Declare variables for the pipe and the byte received
        while( radio.available(&pipeNo)){              // Read all available payloads
          radio.read( &gotByte, 1 );                  
                                                       // Since this is a call-response. Respond directly with an ack payload.
                                                       // Ack payloads are much more efficient than switching to transmit mode to respond to a call
          radio.writeAckPayload(pipeNo,&gotByte, 1 );  // This can be commented out to send empty payloads.
          printf("Sent response %d \n\r", gotByte);
       }
    }



    /****************** Change Roles via Serial Commands ***************************/

      if ( Serial.available() )
      {
        char c = toupper(Serial.read());
        if ( c == 'T' && role == role_pong_back )
        {
          printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");

          role = role_ping_out;                      // Change roles (ping out)
          radio.openWritingPipe(addresses[0]);       // Open different pipes when writing. Write on pipe 0, address 0
          radio.openReadingPipe(1,addresses[1]);     // Read on pipe 1, as address 1
        }
        else if ( c == 'R' && role == role_ping_out )
        {
          printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
         
           role = role_pong_back;                    // Become the primary receiver (pong back)
           radio.openWritingPipe(addresses[1]);      // Since only two radios involved, both listen on the same addresses and pipe numbers in RX mode
           radio.openReadingPipe(1,addresses[0]);    // then switch pipes & addresses to transmit.
           radio.startListening();                   // Need to start listening after opening new reading pipes
        }
      }
    }
     
  10. sergey-fedor

    sergey-fedor Нерд

    стесняюсь спросить, а запитаны как наны? вроде бы как надо земли модуля и ардуино нано соединить вместе , и подскажите какую библиотеку используете для nrf ? а то у меня с последними обновлениями IDE и библиотек перестал сканер вообще компилиться , выдает кучу ошибок
    p/s совет , не пользуйтесь примером, просто на одном передавайте "1" на другом просто принимайте что пришло, так проще отследить ошибки
     
    Последнее редактирование: 18 янв 2017
  11. sergey-fedor

    sergey-fedor Нерд

    Приемник:

    Код (C++):
    #include <SPI.h>
    #include <RF24.h>
    RF24 radio(9, 10);
    const uint32_t pipe = 123456789;

    byte massiv[4];

    void setup()
    {
      //pinMode(6, OUTPUT);
      Serial.begin(9600);
      radio.begin();
      radio.setChannel(55);
      radio.setDataRate(RF24_1MBPS); // RF24_1MBPS или RF24_2MBPS
      radio.setPALevel(RF24_PA_MIN);
      radio.openReadingPipe(1,pipe); // открыть канал на приём
      radio.startListening(); // приём
    }


    void loop()
    {
      if(radio.available())
        {
          radio.read(massiv, 1);
          Serial.println(massiv[0]);
        }      
    }
    Передатчик:
    Код (C++):
    #include <SPI.h>
    #include <RF24.h>
    RF24 radio(9, 10); // можно использовать любые
    const uint32_t pipe = 123456789; // адрес
    byte massiv[1];

    void setup()
    {
      Serial.begin(9600);
      radio.begin();
      radio.setChannel(55);
      radio.setDataRate(RF24_1MBPS); // скорость обмена данными RF24_1MBPS или RF24_2MBPS
      radio.setCRCLength(RF24_CRC_16);
      radio.setPALevel(RF24_PA_MIN);
      radio.openWritingPipe(pipe); // открыть канал на отправку
    }


    void loop()
    {
      massiv[0] = 8;
      radio.write(massiv, 1);
      delay(1000);
      massiv[0] = 9;
      radio.write(massiv, 1);
      delay(1000);
    }
     
    мои модули когда затыкаются закидываю эти скетчи проверяю, валятся циферки в ком порт ? хорошо , меняю скетчи местами передатчик становится приемником , и снова проверяю ... как то так
     
    Последнее редактирование: 18 янв 2017
  12. АнтонCnC

    АнтонCnC Нуб

    Питаются наны просто от usb, земли модуля и наны не соединены. Библиотеки ставил разные с разных источников не работали, множество ошибок было при компиляции. В итоге все снес и установил библиотеку rf24 со среды IDE и все прошивается без проблем.
    Модули заработали в обоих направлениях, все работает. Запускаются только после сброса ардуины кнопкой. Вот только нано и уно с модулями в паре не работают, только нана нана. Кандеры электролиты и керамика в цепи питания стоят. Одна сборка запаяна другая на клемах, помехи одинаковые, может их экранировать в коробочку, только антенку вывести, не знаю
    За скетчи спасибо, буду ими пользоваться. Щас попробую.
     
  13. sergey-fedor

    sergey-fedor Нерд

    у меня как раз уно и нано с этими модулями - все норм и пины совпадают
     
  14. sslobodyan

    sslobodyan Гик

    sergey-fedor, вы обещались попробовать мою библиотеку на каникулах. Не срослось?
     
  15. sergey-fedor

    sergey-fedor Нерд

    К сожалению пока не получилось
     
  16. Securbond

    Securbond Гуру

    Вопрос к знатокам. Можно ли назначить пин CE (NRF), на пин А0 ардуины??
     
  17. mcureenab

    mcureenab Гуру

    Да. Все пины МК могут работать в цифровом режиме.
     
  18. OOM

    OOM Нерд

    Подскажите пожалуйста как организовать подтверждение выполненной команды, т.е.
    Первая nrf включает реле на второй, реле включились и отправила подтверждение первой, что реле включились и на первой скажем загорелся светодиод.
     
  19. mcureenab

    mcureenab Гуру

    Отправить команду с порядковым номером и некоторое время ждать ответа периодически повторяя отправку. Получив ответ отправить подтверждение и так же ждать ответа. Если ответ на подтверждение снова пришел, отправить его еще раз.
    Если ответ не пришел во время, снова отправляем команду с тем же порядковым номером.

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

    На управляемой стороне получив команду отправляем подтверждение с её порядковым номером и назначаем номер самому подтверждению. Если команда с тем же номером пришла снова опять отправляем подтверждение со следующим номером.

    В итоге управляющий модуль должен убедиться, что его команда принята.
    А управляемый модуль должен прекратить отправку подтверждений.
     
    Последнее редактирование: 24 янв 2017
    MickNich нравится это.
  20. ИгорьК

    ИгорьК Гуру

    Еще вариант - почитать тему хотя бы первые три страницы. И даташит на модуль. Это очень крутой вариант.
     
    Tomasina и sslobodyan нравится это.