NRF24L01+ (библиотека TMRH20): Получатель получает пустые данные

Я работаю над образцом проекта Arduino для связи по NRF24L01+ (библиотека TMRH20), в моем примере все работает нормально, за исключением одной проблемы: мой приемник получает сообщение, но это сообщение пустое. Теперь я не уверен, как мне отлаживать передачу данных в соответствии с последовательным монитором, в соответствии с последовательным монитором приемника он получает данные, но они пустые.

Код передатчика -

// SimpleTx - the master or the transmitter

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


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};


RF24 radio(CE_PIN, CSN_PIN); // Создать радио

char dataToSend[12] = "Msg AKSHAY";
//int dataToSend = 1;
char txNum = '0';


unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // отправка один раз в секунду


void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Всегда используйте функцию sizeof (), так как она определяет размер как количество байтов.
        // Например, если бы dataToSend был размером int, функция sizeof() правильно вернула бы 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // таким образом, вы можете видеть, что отправляются новые данные
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[10] = txNum;
}

Код приемника -

// SimpleRx - the slave or the receiver

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

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
  if ( radio.available() ) {

       radio.read( &dataReceived, sizeof(dataReceived) );
      Serial.println(dataReceived);
       newData = true;
   } else {
       Serial.println("No radio available");
   }
   delay(100);
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

Ниже показан выходной сигнал TX1 (передатчик ), а RX1-приемник. Вы можете видеть, что передатчик также получает подтверждение.

Оба моих устройства являются arduino nano, и ниже приведена схема подключения между arduino и nrf24l01.

Я также видел несколько сообщений, в которых люди предлагали использовать конденсатор 100uf в NRF24L01 (GND и VCC), это помогло мне с точностью подключения, но данные все еще отсутствуют.

, 👍2

Обсуждение

Если бы вы попробовали цикл " для " при печати ваших данных на последовательном, поскольку вы получаете данные в виде массива символов., @Vaibhav

Я пытался, но это не помогает., @Akshay

Не могли бы вы, пожалуйста, загрузить неизмененный пример PingPair и посмотреть, сработает ли это? Действительно трудно понять настоящую причину, если это может быть просто ваш код., @Avamander


2 ответа


-1

Сначала пара уточнений

  1. В момент времени 22:38 приемник не обнаруживает никаких доступных радиоустройств, но на стороне передатчика принимается подтверждение. Как это возможно? Как ваш tx получает ack без подключения rx?

  2. Я не видел раба адресами установить в качестве -
    константный байт подч устройств[5] = {'р','х','А','А','А'};
    Для справки, с NRF24L01 адресов 5 байт по умолчанию, а не 1 байт, как вы определили. При определении адресов каналов первые 4 байта адресов должны быть одинаковыми для всех адресов каналов. Только последний байт должен быть уникальным.
    Адреса каналов могут быть 0xF0F0F0F0A1, 0XF0F0F0F0B1, 0XF0F0F0F0C1, 0XF0F0F0F0D1, 0XF0F0F0F0F0E1
    Попробуйте задать адреса каналов как
    адрес uint_64t[5] = {0XF0F0F0F0F0A1LL, 0XF0F0F0F0B1LL, 0XF0F0F0F0C1LL, 0XF0F0F0F0D1LL, 0XF0F0F0F0E1LL};
    Сделайте то же самое объявление и на приемном конце. И кстати, вы можете указать любой байт, который вы хотите, в последнем байте адреса. Здесь я определил последние байты как A1, B1, C1, D1, E1.

  3. Чтобы убедиться, что связь прошла успешно, установите некоторый пользовательский байт ack и сравните его с полученным ack. Если оба совпадают, вы можете быть уверены, что rx действительно получил данные. Иногда NRF24L01 может улавливать значения мусора из случайных сигналов, присутствующих вокруг, и может рассматривать их как данные, отправленные получателем. Поэтому, чтобы избежать ложного срабатывания, лучше сделать надежный механизм ACK.

,

Ваше второе замечание вообще не имеет смысла. Вы пытаетесь поместить значения шириной в пять байт в один байт, что бессмысленно. Фактически, первоначальное намерение операции с его " постоянным байтовым адресом раба[5] = {"R", "x", "A", "A", "A"};`, по-видимому, является попыткой создать 5-байтовый адрес. Именно так, как ты сказал, должно быть. Это *один* ведомый адрес, а не пять из них., @AnT

Прости! Это должно быть uint_64t. Спасибо, что указал на это, Муравей, @Pranit Pawar

(Во-первых, это "uint64_t", а не "uint_64t".) Но это приведет к объявлению 5 отдельных адресов. Как это относится к вопросу ОП? Почему 5? Ему не нужно пять отдельных адресов, ему нужен только один., @AnT

Кроме того, это пример из самого файла заголовка RF24: адрес uint8_t[] = { 0xCC,0xCE,0xCC,0xCE,0xCC }; radio.openWritingPipe(адрес);. (https://github.com/nRF24/RF24/blob/master/RF24.h#L246) Как вы можете видеть, это то же самое, что и в коде операции. В этом нет ничего плохого., @AnT


3

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

void getData() {
  uint8_t pipeNum;
  if ( radio.available(&pipeNum) ) {

       radio.read( &dataReceived, sizeof(dataReceived) );
      //Serial.println(dataReceived);
      if (pipeNum < 2) {
       newData = true;
      }
   } else {
       Serial.println("No radio available");
   }
   // delay(100);
}
,