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), это помогло мне с точностью подключения, но данные все еще отсутствуют.
@Akshay, 👍2
Обсуждение2 ответа
Сначала пара уточнений
В момент времени 22:38 приемник не обнаруживает никаких доступных радиоустройств, но на стороне передатчика принимается подтверждение. Как это возможно? Как ваш tx получает ack без подключения rx?
Я не видел раба адресами установить в качестве -
константный байт подч устройств[5] = {'р','х','А','А','А'};
Для справки, с NRF24L01 адресов 5 байт по умолчанию, а не 1 байт, как вы определили. При определении адресов каналов первые 4 байта адресов должны быть одинаковыми для всех адресов каналов. Только последний байт должен быть уникальным.
Адреса каналов могут быть0xF0F0F0F0A1, 0XF0F0F0F0B1, 0XF0F0F0F0C1, 0XF0F0F0F0D1, 0XF0F0F0F0F0E1
Попробуйте задать адреса каналов какадрес uint_64t[5] = {0XF0F0F0F0F0A1LL, 0XF0F0F0F0B1LL, 0XF0F0F0F0C1LL, 0XF0F0F0F0D1LL, 0XF0F0F0F0E1LL};
Сделайте то же самое объявление и на приемном конце. И кстати, вы можете указать любой байт, который вы хотите, в последнем байте адреса. Здесь я определил последние байты какA1
,B1
,C1
,D1
,E1
.Чтобы убедиться, что связь прошла успешно, установите некоторый пользовательский байт 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
Я проверил ваш код. Похоже, что вокруг есть дефектные клоны 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);
}
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- В чем разница между библиотеками Software Serial? Какая из них совместима с Arduino Nano?
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- Пустое значение не игнорируется, как должно быть.
- Проблемы с последовательной связью от Arduino к Bluetooth HC-05
- Как Arduino может проверить, подключен ли он к ПК и включен ли компьютер?
- Как отправлять и получать беззнаковые целые (unsigned int) от одного arduino к другому arduino
- Проблема с NRF24L01
Если бы вы попробовали цикл " для " при печати ваших данных на последовательном, поскольку вы получаете данные в виде массива символов., @Vaibhav
Я пытался, но это не помогает., @Akshay
Не могли бы вы, пожалуйста, загрузить неизмененный пример PingPair и посмотреть, сработает ли это? Действительно трудно понять настоящую причину, если это может быть просто ваш код., @Avamander