Вопросы по NRF24L01

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@bort707,

GettingStarted_CallResponse:
#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

    }

  }

}
обычный самый GettingStarted_CallResponse
затабуировал все radio.openReadingPipe(1, addresses[0]) и radio.openWritingPipe(addresses[1]) что бы убедиться, что проблема там
 
Изменено:

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
@Nilon, во-первых, изучать ваш код в таком виде очень сложно, оформите его правильно.
Ну и во-вторых, возможно потому что вы опубликовали код абы как - я не вижу в нем никаких следов указанных вами идентификаторов 0xe7e7e7e7e7 или 0xc2c2c2c2c2
если мы не заявляем трубы,то у нас вот так 0xe7e7e7e7e7 0xc2c2c2c2c2 в обоих ардуино
Если начинаем выбирать трубы, то у нас сразу меняется (0xe7e7e7e7e7 0xc2c2c2c2c2) на (0х0000000106 0х0000000100) в случае выбора труб 0 и 1 на UNo, если выбрать другие трубы, то меняются только последние 2 знака. На мега все тоже самое но (0х0000000206 0х0000000200)
 

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@bort707,
Я их тоже не вижу. Что бы появились идентификаторы в таком варианте 0xe7e7e7e7e7 0xc2c2c2c2c2 нужно удалить из кода
присвоение radio.openWritingPipe и radio.openReadingPipe. Те мы не назначаем никаких труб и пользуемся тем, что выберет сама nfr24. А она как раз и выбирает 0xe7e7e7e7e7 0xc2c2c2c2c2, как только начинаешь сам трубы назначать, то адреса на UNO будут иметь вид 0х0000000100, 0х0000000106, 0х0000000116 , а тот же код на Мега будет х0000000200, 0х0000000206, 0х0000000216. Програмно удается менять только последние 2 цифра.
Весь вопрос - как поменять в RX_ADDR_P0-1 не последние 2 цифры а остальные перед ними ?
 

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
как только начинаешь сам трубы назначать, то адреса на UNO будут иметь вид 0х0000000100, 0х0000000106, 0х0000000116 , а тот же код на Мега будет х0000000200, 0х0000000206, 0х0000000216. Програмно удается менять только последние 2 цифра.
То есть в коде, который вы нам показали, обсуждаемой проблемы нет? Зачем тогда вы его выложили?
Не надо рассказывать истории, лучше покажите код, где сначала адрес трубы 0xe7e7e7e7e7, а потом удивительно меняется на 0х0000000100. Чтобы в этом коде было видно, как вы эти трубы читаете и как пытаетесь менять.
Иначе я не вижу темы для обсуждения вообще.
 

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@bort707,
Есть в нем проблема: Этот код мне на ардуино mega дает идентификатор 0х0000000200, а на UNo 0х0000000100и получается, что они в разных трубах работают. Если затекстовать строки 69,71,189,191, 205, 207 загрузить в ардуино и отключить/включить от питания, то на Мега и на Уно будет одинаковая труба вида 0xe7e7e7e7e7. Если пытаюсь поменять трубу, то один код (вот тот что выше) дает разные трубы на разных ардуино и они не общаются из-за этого

весь вопрос: через какую команду можно прописать весь RX_ADDR_P0-1, а не 2 последние цифры? последние две меняются выбором трубы одной из 6
 

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
Этот код мне на ардуино mega дает идентификатор 0х0000000200
Как вы это установили? Покажите с кодом.


один код (вот тот что выше) дает разные трубы на разных ардуино
Слушайте, эту библиотеку используют миллионы пользователей по всему миру. Если бы оно искажало адреса, то проблемы были бы у каждого второго. А мы этого не видим, ваш случай только второй с 2019 года. Значит косяк на вашей стороне.

Добавка
Чтобы найти проблему, нужно больше определенности. Давайте рассмотрим подробно, по шагам - какой именно код заливаете, как проверяете имена труб, что делаете чтобы оно изменилось.
Пока вы описываете проблему в таком стиле:
затекстовать строки 69,71,189,191, 205, 207 загрузить в ардуино и отключить/включить от питания,
боюсь у нас ничего не получится
 
Изменено:

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@Nilon, Итак ответ:
Эти модули - не оригиналы. На них стоит чип Si24r1. Проблема верной настройки решается заменой 17 строки:
присвоение идентификатора трубам:
byte addresses[][6] = {"1Node", "2Node"}; // Radio pipe addresses for the 2 nodes to communicate.
на вот такой

C++:
byte addresses[6] = {"1Node", "2Node"}; // Radio pipe addresses for the 2 nodes to communicate.
Код byte addresses[][6] = {"1Node", "2Node"} выглядит довольно странно в примере. Мы заявляем двухразрядный массив, а в коде обращаемся лишь к первому разряду, который даже не прописывали. В итоге если сделать одноразрядный, то все начинает работать.

Но! Теперь появилась новая проблема:
Все функционирует до тех пор, пока не создается пауза вещания TX более чем на 13мс. Допустим если слать пакеты непрерывно
void loop() {radio.write(&MySignal, sizeof(MySignal)); } , то все работает. Если добавить delay(), то все работает пока delay меньше 14мс, как только ставишь 15 и более, то трансляция прекращается, сигнал TX не издает, хотя в Serial исправно отправляет уведомления, а сам модуль не вещает в эфир ничего. Будто бы модуль проваливается в сон.
Если вместо delay организовать задержку через millis(), то тот же самый эффект - как только превышаем 14мс, то трансляция прекращается.
Если отправлять сигнал не через промежутки времени, а принудительно кнопкой, то все функционирует четко.
Я в логическом тупике.
Именно по этой причине у некоторых проходит только первый сигнал! Потому что, остальные TX перестает слать, так как в коде delay(100): Отправляется первый пакет, потом происходит что-то необъяснимое связанное с этим delay и прекращает трансляцию в модуле. Ардуинка продолжает делать попытки отправки, но модуль молчит.
 

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
Код byte addresses[][6] = {"1Node", "2Node"} выглядит довольно странно в примере. Мы заявляем двухразрядный массив, а в коде обращаемся лишь к первому разряду, который даже не прописывали.
Ничего странного нет. Совершенно верный синтаксис. Вы в курсе, что строки в С/С++ - это массивы? Каждая строка "1Node", "2Node" - это массив из 6 элементов, а массив таких строк - это массив массивов, или двмерный массив. К какому "первому разряду" вы там обращаетесь, я вообще не понял.
если сделать одноразрядный, то все начинает работать.
А вот как раз ваш "одноразрядный" - это бред с точки зрения синтаксиса. Вам бы какую-нибудь книжку по С на ночь почитать, глядишь все ваши проблемы разрешились бы.

Что касается второй части вашего сообщения - опять без кода нет смысла обсуждать.
 

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@bort707,
Вы тут на форуме какую-то должность занимаете? Просто от ваших ответов пользы никакой. Если я не первый столкнулся с этой проблемой, то и не я последний. А ваши комментарии в стлие "дурак иди учись" никак не приближают к решению, только создают больше флуда. Я пока ковырялся со своей проблемой уже разобрался с другими двумя, которые тоже есть в этом форуме от людей, которые не получили ничего интересного. Ответы пустые. Не нужно мне отвечать, если по делу ответить нечего. Я сам разберусь и сюда опубликую решение, что бы могли найти решение, а не направление куда им идти с их проблемами. Спасибо большое теперь я знаю что правильно говорить массив массивов, или двухмерный массив, а не двухразрядный, теперь то я с этим знанием все вопросы решу. Только работает почему-то на моей si24r1 мой неправильный одномерный, а "массив массивов" не работает. Код тот же самый что и был на верху сообщение #401
 
Изменено:

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
А ваши комментарии в стлие "дурак иди учись" никак не приближают к решению,
А какие еще комментарии вы ждете на свои рассуждения, что стандартное обьявление двумерного массива в С++ выглядит для вас "странно"?
Я сам разберусь и сюда опубликую решение,
Желаю успеха. Только вот сомневаюсь, что "решение" от человека, который банально не знает язык, будет для кого-то особенно полезным. Примерно как ваш совет заменить "двуразрядный" массив "одноразрядным"....

Вы бы лучше не "взбрыкивали", а пытались чему-нибудь научится. Разве вам самому не очевидно, что ваши знания языка С/С++ откровенно слабые? Вы никогда не сможете писать надежные программы без знания языка. Как-то запустить код - еще можете, случайно найти какую-нибудь "затычку" на форумах. Но это замок на песке. Стоит чуть-что изменить в коде - и у вас опять все посыпется.
 
Изменено:

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
Только работает почему-то на моей si24r1 мой неправильный одномерный, а "массив массивов" не работает.
Какая плата у вас?
Для Ардуино Нано ваш одномерный массив (строчка ниже)
C++:
byte addresses[6] = {"1Node", "2Node"};
- вообще не компилируется.
C++:
sketch_jul27c:1:37: error: too many initializers for 'byte [6] {aka unsigned char [6]}'
 byte addresses[6] = {"1Node", "2Node"};
Что вполне ожидаемо, кстати.
 

Nilon

✩✩✩✩✩✩✩
21 Июл 2026
7
0
@bort707,
проверил,согласен написал фигню. в таком варианте не работает, а вот в таком пашет как миленькая:
C++:
byte addresses[6] = {0xB3B4B5B6F1, 0xB3B4B5B6CD}; // Radio pipe addresses for the 2 nodes to communicate.
Снимок экрана 2026-07-27 153605.jpgСнимок экрана 2026-07-27 153206.jpg

Код byte addresses[][6] = {"1Node", "2Node"} не прописывает Si24R1 и она прописывается какими-то своими кодами. При этом у Нано и Уно эти коды всегда ..000100 и ..000106 а у Мега ..000206. И нельзя переключить эти адреса с приема на передачу. А вот в варианте byte addresses[6] = {0xB3B4B5B6F1, 0xB3B4B5B6CD}; уже все функционирует хорошо. Трубы друг друга находят.
Остался вопрос с Delay(). Как только в цикле делаешь Delay больше 13, то Si24R1 сразу перестает транслировать. Ладно бы сильно короткий бы создавал проблему, а тут делаешь задержку длиннее и все...... А если прописать отправку на кнопку, то все улетает без сбоев. Я понимаю что это подделка под NFR24L1 и они бывают разные и готовых ответов я не найду,, но возможно кого то были похожие симптомы работы с чипами, что они начинают лагать из за увеличения задержки.
Удивляет тот факт, что ручная инициация отправок работает без сбоев, а delay() millis() и все - приемник прекращает вещание. Принудительная отправка через запрограммированную кнопку возвращает трансляцию приемнику. Казалось бы delay и millis функционируют в ардуино, а Si24R1 вообще не должна понимать какая логика в ардуино начинает транслировать сигналы. Никак не могу понять что такого страшного в этих delay что происходит такое
 

bort707

★★★★★★★
21 Сен 2020
3,483
1,000
согласен написал фигню. в таком варианте не работает,
...
А вот в варианте byte addresses[6] = {0xB3B4B5B6F1, 0xB3B4B5B6CD}; уже все функционирует хорошо.
простите, но это ровно такая же фигня, как предыдущая. Вот что пишет про это компилятор:
C++:
/home/dmit/Arduino/sketch_jul27c/sketch_jul27c.ino:1:48: warning: narrowing conversion of '771830953713' from 'long long int' to 'byte {aka unsigned char}' inside { } [-Wnarrowing]
byte addresses[6] = {0xB3B4B5B6F1, 0xB3B4B5B6CD};
                                                ^
Если непонятно - я поясню. Тип вашего массива - байт. Байт - это целое число от 0 до 255. Вы же в него пытаетесь запихнуть значение 0xB3B4B5B6F1, что десятичном выражении составляет 771830953713 и никак в байт не поместится.
Что хорошо видно на ваших же скринах - из всего значения 0xB3B4B5B6F1 в номер трубы попало только "F1".
То, что это почему-то работает - не более чем случайность. Ибо даже если оно "работает" - то вовсе не так, как вы планировали.

Вы опять будете недовольны моим ответом... но вы вот только что подтвердили, что не понимаете в коде почти ничего.
Вам не надоело тыкаться вслепую?