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

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

  1. forfrends

    forfrends Нерд

    Меня просто ввело в заблуждение то, что почти во всех примерах что я смотрел, прописывалось значение только одной "трубы". Из-за этого сложилось впечатление что как для приема, так и для передачи используется одна и та же "труба".
    только что еще раз прогнал тест - модуль глухой. Хороший модуль показывает шумы на каналах 1F - 29, а этот на всех канал показывает "0". Пробовал и на МЕГЕ и на ДУЕ, везде результат одинаков.
     
  2. sergey-fedor

    sergey-fedor Нерд

    уважаемые победители :) так как никто всю тему не читает все равно я пользуясь случаем хочу спросить у вас как начинающий радиолюбитель: кто какими проводами коннекторами и разъемами пользуется для коммутации ? так как пытаюсь сделать проект без участия печатных плат лутов и т.д., все естественно собрано на проводчках и коннекторах BNC или как их называют наши китайские друзья - Дюпон. В очередной раз собрав проверенную схему на столе, убрав все аккуратно в коробочки , проверив , понес на места дислокации :)) сответственно в подвал дома и чердак бани, ну и как обычно - пока нес где то пропал контакт ничего не работает и начинаются игрища в стиле - возьми мультиметр прозвони контакты проверь питание.. :( Больше нет сил это терпеть - контакты в колодках ардуин разбалтываются, проводочки из этих дюпонов вываливаются хотя и пропаиваю. Кабель ничего лучше чем витую пару - придумать не могу ( в силу отсутствия опыта) да и удобны они из за того что имеют цветовую индикацию- но не удобны своей хрупокостью. А ведь большая часть проводов будет зимой в не отапливаемом помещении. Или может создать тему отдельную уже и не знаю, или может есть такая тема ? ткните носом можно и в личку
     
  3. ИгорьК

    ИгорьК Гуру

    Паяльник наше все.
    Дюпон - он тоже вполне годен. Надо только "уметь его готовить". Вон, в коптеростроении и хоббийной авиации на дюпонах сидит управление двигателями, и ничего. А там вибрация поболе будет, чем моуль в подвал отнести.
     
  4. sergey-fedor

    sergey-fedor Нерд

    Без паяльника понятно что вообще никак , а провода какие пользуете или шлейфы? , все таки витуха тонковата что то бы AWG22 да разных бы цветов , да еще не дорого :)
     
  5. Sturgeon

    Sturgeon Нуб

    Приветствую участников форума!
    Надеюсь, что как и многим другим мне помогут разобраться с модулем и укажут на мои ошибки.

    По порядку, что я сделал:
    Напаял кондеры 4,7 мкФ. Керамики не паял по причине отсутствия и по почте мне идут дополнительные модули питания.
    Библиотеки пробовал три разные из первого поста. В итоге так как не заработала ни одна и я уже начал путаться в них, решил остановиться на какой-то одной и разбираться с ней. Оставил библиотеку tmrh20.
    Инициализурую модули полностью (насколько я могу понять).
    Подключаю модули к ардуино НАНО. Добился того, что параметры модуля (СRC PA и другие) меняются так как указано. Сканер из примеров тоже стабильно работает, разные модули показывают одинаковые свободные каналы. А вот связь друг с другом мне пока не дается. Модули не отвечают на запросы. Скорее всего проблема в коде. Не могли бы уважаемые участники форума посмотреть на мой код и указать на ошибки, которые я скорее всего допустил. Код взят из библиотеки tmrh20 из примера Getting Started, в который я добавил код инициализации. Переменные radioNumber и role для каждого из двух передатчиков установлены соответственно в разные значения (0 и 1.)

    Код (C++):

    /*
    * Getting Started example sketch for nRF24L01+ radios
    * This is a very basic example of how to send data from one node to another
    * Updated: Dec 2014 by TMRh20
    */


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

    /****************** User Config ***************************/
    /***      Set this radio as radio number 0 or 1         ***/
    bool radioNumber = 0;

    /* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
    RF24 radio(7,8);
    /**********************************************************/

    byte addresses[][6] = {"1Node","2Node"};

    // Used to control whether this node is sending or receiving
    bool role = 0;

    void setup() {
      Serial.begin(115200);
      Serial.println(F("RF24/examples/GettingStarted"));
      Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
     
          radio.begin();
          delay(2000);
          radio.enableDynamicPayloads();
          radio.enableAckPayload();
          radio.setDataRate(RF24_1MBPS);
          radio.setChannel(0);
          radio.setRetries(15,15);
          radio.setAutoAck(false);
          radio.setCRCLength(RF24_CRC_16);
          radio.setPALevel(RF24_PA_MAX);
          radio.powerUp();

     
      // Open a writing and reading pipe on each radio, with opposite addresses
      if(radioNumber){
        radio.openWritingPipe(addresses[1]);
        radio.openReadingPipe(1,addresses[0]);
      }else{
        radio.openWritingPipe(addresses[0]);
        radio.openReadingPipe(1,addresses[1]);
      }
     
      // Start the radio listening for data
      radio.startListening();
    }

    void loop() {
     
     
    /****************** Ping Out Role ***************************/
    if (role == 1)  {
       
        radio.stopListening();                                    // First, stop listening so we can talk.
       
       
        Serial.println(F("Now sending"));

        unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
         if (!radio.write( &start_time, sizeof(unsigned long) )){
           Serial.println(F("failed"));
         }
           
        radio.startListening();                                    // Now, continue listening
       
        unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
        boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not
       
        while ( ! radio.available() ){                             // While nothing is received
          if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
              timeout = true;
              break;
          }    
        }
           
        if ( timeout ){                                             // Describe the results
            Serial.println(F("Failed, response timed out."));
        }else{
            unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
            radio.read( &got_time, sizeof(unsigned long) );
            unsigned long end_time = micros();
           
            // Spew it
            Serial.print(F("Sent "));
            Serial.print(start_time);
            Serial.print(F(", Got response "));
            Serial.print(got_time);
            Serial.print(F(", Round-trip delay "));
            Serial.print(end_time-start_time);
            Serial.println(F(" microseconds"));
        }

        // Try again 1s later
        delay(1000);
      }



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

      if ( role == 0 )
      {
        unsigned long got_time;
       
        if( radio.available()){
                                                                        // Variable for the received timestamp
          while (radio.available()) {                                   // While there is data ready
            radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
          }
       
          radio.stopListening();                                        // First, stop listening so we can talk  
          radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.    
          radio.startListening();                                       // Now, resume listening so we catch the next packets.    
          Serial.print(F("Sent response "));
          Serial.println(got_time);
       }
    }




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

      if ( Serial.available() )
      {
        char c = toupper(Serial.read());
        if ( c == 'T' && role == 0 ){    
          Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
          role = 1;                  // Become the primary transmitter (ping out)
       
       }else
        if ( c == 'R' && role == 1 ){
          Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));    
           role = 0;                // Become the primary receiver (pong back)
           radio.startListening();
         
        }
      }


    } // Loop
     
     
  6. forfrends

    forfrends Нерд

    Их не нужно менять. Роль передатчик-приемник меняется через сериал путем ввода клавиши 'T' или 'R'. Там же в коде написано:
    CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
    CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK.
    Вот этот пример что вы привели, без изменений, прошейте в обе ардуины. Потом откройте сериал и нажмите 'T' , отпишитесь о результатах.
    Еще вопрос: модули из одной партии? И они "нормальные"? не урезанные (смотри фото на предыдущей странице)? Если максимально простые - то у меня такие не заработали.
     
  7. Sturgeon

    Sturgeon Нуб

    Да, действительно забыл написать. Модули с внешней антенной, такого плана http://www.robimek.com/wp-content/uploads/2-4G-NRF24L01-antenli.jpg. Все из одной партии. Китайской коммунистической.

    Код пробовал залить одинаковый на обе ардуины. Результата нет. В сериале строки:
    Now sending
    Failed, response timed out.


    Мне кажется что он не должен быть одинаковый. Про переменную role согласен. Ее можно менять в ходе выполнения программы. Хотя удобнее сразу прошивать один модуль как передатчик, а второй как приемник. Но роли это не играет. А вот переменная radioNumber мне кажется должна быть разной на разных модулях. Вот этот код как раз и открывает две разные трубы на прием и передачу на разных модулях в зависимости от того 0 или 1 принимает переменная

    // Open a writing and reading pipe on each radio, with opposite addresses
    if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
    }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);

    Хотя пробовал и так и так - результата нет.
     
  8. Sturgeon

    Sturgeon Нуб

    Вроде получилось!!!!
    Изменил PALevel с MAX на MIN и все как по волшебству заработало!!!
    Спасибо Haradnur за оставленный комментарий!!!

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

    Хочется еще уточнить вот про эту строчку

    const uint8_t addresses[][6] = {"1Node","2Node"};

    Вместо Node во всех других библиотека используется номер трубы, которые состоит из 8 байт. А тут просто какие-то слова. Вроде поискал в библиотеке нигде они не подменяются на числовые значения. Как это работает?
     
    Последнее редактирование: 26 авг 2016
  9. anth

    anth Нерд

    в вашем примере 8 байтовые числа определяются строками, вернее массивами символов.
    То же самое с помощью чисел будет:

    const uint8_t addresses[2] = { 0x65646f4e31LL, 0x65646f4e32LL };

    0x65 ascii код символа 'e'
    ...
    0x4e - 'N'
    0x31 - '1'
    0x32 - '2'
     
    Sturgeon нравится это.
  10. anth

    anth Нерд

    У меня модули заработали в следующих случаях:
    • запитаны 5v (пины на клоне uno)
    • через адаптер http://goo.gl/k1mPxc, адаптер при этом так же запитан 5v
    конденсаторы (не важно керамика или электролиты) были в обоих случаях. Без них работает нестабильно.

    Было подозрение, что клон uno не держит 3.3v. Однако просадки напряжения не заметил. В лучшем случае модуль мог что-то передать, но в ответ - timeout.
    Пробовал подать внешнее, отдельное питание на модуль:
    • через такую штуку http://goo.gl/omkMA6, 5v и 3.3v
    • элементы питания AA, AAA, 2 или 3 штуки
    Все безуспешно. Работает, только если подать 5v с пинов uno.

    Какие будут мысли?
     
    Последнее редактирование: 28 авг 2016
  11. anth

    anth Нерд

    Имея рабочую конфигурацию решил проверить имеющиеся модули.
    3 пары покупались у разных продавцов.
    Все работают. В режиме radio.setPALevel(RF24_PA_HIGH) пробивают в квартире 3 стены (15см газосиликат), одна под углом. Общее расстояние 18м. На открытом пространстве пока не тестил.

    Попробовал убрать конденсаторы, все равно работает и довольно стабильно.

    Что, так и питать от 5v? :)
     
  12. Denis_

    Denis_ Нуб

    Решил проблему со спящим режимом, подключил ножку MISO через резистор 330R.
     
  13. Sturgeon

    Sturgeon Нуб

    Продолжаю разбираться. Пробую чуть изменить скетч Getting Started так, чтобы передавать не число, а символ. Для этого изменил в передатчикекод так, чтобы он всегда отсылал в ответ символ "W", а в приемнике изменил код так, чтобы он этот символ выводил:

    Код (C++):
      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

    Подскажите, из-за чего это может быть и какие особенности могут быть при передаче разных типов данных?
     
  14. Stas Di

    Stas Di Нуб

    Добрый вечер!
    Получил на днях два модуля для экспериментов. Но вот беда, не пашут. Стандартные примеры пробовал, кидает в порт каракули и то рывками как-то. Скорость 9600. Попробовал ваш тест: выкинуло вот что:
    Код (Text):
    STATUS         = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    RX_ADDR_P0-1     = 0xe7e7e7e7e7 0xc2c2c2c2c2
    RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
    TX_ADDR         = 0xe7e7e7e7e7
    RX_PW_P0-6     = 0x00 0x00 0x00 0x00 0x00 0x00
    EN_AA         = 0x00
    EN_RXADDR     = 0x02
    RF_CH         = 0x4c
    RF_SETUP     = 0x07
    CONFIG         = 0x0f
    DYNPD/FEATURE     = 0x00 0x00
    Data Rate     = 1MBPS
    Model         = nRF24L01+
    CRC Length     = 16 bits
    PA Power     = PA_MAX
    00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777777

    0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

    00101279c2553e951010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    000000000000000000000008aa830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    0001211110000036af353fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    0002fb72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    0001002021221111230001200487a600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    0010258d0464fb720011022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    STATUS         = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    ..... и т.д. по кругу
    Первая часть вроде ничего, но в конце что это за ряды данных?
    При чем всегда по разному.
    Судя по тесту вроде модуль рабочий.

    Сразу оговорюсь с ардуинкой только знакомлюсь. На модуле кондера еще нет т.к. пока нет в наличии, заказал.
     
  15. ИгорьК

    ИгорьК Гуру

    Код (C++):
    RX_ADDR_P0-1     = 0xe7e7e7e7e7 0xc2c2c2c2c2
    Эта строка показывает адреса каналов (труб), которые Вы устанавливаете. Совпадает хоть один из двух? Не похоже.
     
  16. Sturgeon

    Sturgeon Нуб

    Никак не могу решить описанную выше проблему. При передаче символа char он выводится в сериал постоянно, даже при отключенном передатчике. Мне кажется это как-то связано с тем, что он остается в буфере, потому что если приемник перезагрузить, то в сериал выводится ноль. Пробовал следовать совету со второй страницы темы и сделал функции flush_tx и flush_rx в публичными. Вызываю их перед radio.read. Результата нет. Да и непонятно зачем это делать, если flush_tx и flush_rx вызываются при каждом stopListening и startListening. Еще более непонятно, почему при передаче int все работает как надо и при отключении передатчика в сериал сразу выводится ноль. Кто-нибудь сталкивался с таким? Скорее всего это моя ошибка где-то в коде, хотя правки кода минимальные. Просто поменял int data[1]; на char data[1];
     
    Последнее редактирование: 5 сен 2016
  17. Oleg_7

    Oleg_7 Гик

  18. Denis_

    Denis_ Нуб

    Нормальный модуль, работает.
    [​IMG]
     
  19. TEXTRON

    TEXTRON Нерд

    Всем доброго вечера. Использую как раз модули с антенной. Модули, выполняющие роль приемников, работают нормально, а вот модуль-передатчик капризничает. Проявляется в следующем: в руках модуль работает супер, как только убираю из рук - практически ничего не передает... (1-2 посылаемых сигнала из 10 все-таки проходят). Методом тыка установлено, что касаясь элемента на картинке все работает, не касаясь - капризулит)))) Что это за элемент (на фото)? В чем может быть причина такого поведения модуля?

    P.S. - модули (их более 2х), менял местами - все одна и та же проблема на передатчике...
    [​IMG]
     

    Вложения:

  20. Denis_

    Denis_ Нуб

    Попробуй замотать модуль стрейч плёнкой, поверх плёнки фольгу, фольгу на минус.