nRF24L01 использует отправителя в качестве получателя и наоборот с помощью библиотеки RF24
У меня есть два модуля nRF24L01 (я попробовал 2 с антенной и 2 без антенны), сопряженные с их базовым модулем питания и подключенные к двум разным платам Arduino Mega 2560. Я могу передавать от одного модуля к другому до 32 байт данных и получать подтверждение без каких-либо проблем. Но когда я переключаю их, когда я пытаюсь отправить данные от получателя и получить их от отправителя, у меня ничего нет. Никаких данных не получено, никакого подтверждения не отправлено в качестве ответа.
Как я уже говорил, первая часть этого кода работает хорошо, но когда дело доходит до второй части, которая находится после задержки(1000),
наступает тишина...
мой код таков:
Приемник
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include "printf.h"
// Set pipes
const uint64_t pipe01_ = 0xE8E8F0F0A1LL;
const uint64_t pipe02_ = 0xE8E8F0F0A2LL;
const uint64_t pipe03_ = 0xA3LL;
const uint64_t pipe04_ = 0xA4LL;
const uint64_t pipe05_ = 0xA5LL;
const uint64_t pipe06_ = 0xA6LL;
RF24 radio(9, 53);
void setup()
{
Serial.begin(115200);
delay(250);
radio.begin();
radio.setChannel(0x57);
radio.setPALevel(RF24_PA_LOW);
radio.enableAckPayload();
radio.openReadingPipe(1, pipe01_);
radio.openWritingPipe(pipe02_);
radio.enableDynamicPayloads();
radio.startListening();
}
void loop()
{
if (radio.available())
{
char newMessage[33];
memset(newMessage, 0, sizeof(byte) * 33);
while (radio.available())
{radio.read(newMessage, 32);}
Serial.println("newMessage: " + String((const char*)newMessage));
delay(1000);
radio.stopListening();
char response[32] = "1234567890qwertyuiopasdfghjklzxc";
radio.write(response, 32);
unsigned long ack = 0;
if (radio.isAckPayloadAvailable())
{
radio.read(&ack, sizeof(ack));
Serial.println("ack: " + String(ack));
}
radio.startListening();
}
}
Отправитель
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include "printf.h"
// Set pipes
const uint64_t pipe01_ = 0xE8E8F0F0A1LL;
const uint64_t pipe02_ = 0xA2LL;
const uint64_t pipe03_ = 0xA3LL;
const uint64_t pipe04_ = 0xA4LL;
const uint64_t pipe05_ = 0xA5LL;
const uint64_t pipe06_ = 0xA6LL;
RF24 radio(9, 53);
void setup()
{
Serial.begin(115200);
delay(250);
radio.begin();
radio.setChannel(0x57);
radio.setPALevel(RF24_PA_LOW);
radio.enableAckPayload();
radio.openReadingPipe(2, pipe02_);
radio.openWritingPipe(pipe01_);
radio.enableDynamicPayloads();
radio.stopListening();
char message[32] = "qwertyuiopasdfghjklzxc1234567890";
radio.write(message, 32);
radio.startListening();
}
void loop()
{
if (radio.available())
{
char respMessage[33];
memset(respMessage, 0, sizeof(byte) * 33);
while (radio.available())
{radio.read(respMessage, 32);}
Serial.println("respMessage: " + String((const char*)respMessage));
}
}
Пожалуйста, помогите мне.
@Faig, 👍2
Обсуждение1 ответ
Обновление: Вчера это работало, но сегодня... то же самое, что и с "задержкой()". Что не так с этими радиомодулями??
Я обнаружил, что функция delay()
вызывала такое ненормальное поведение.
Поэтому я реализовал периоды вместо задержки ()
, и теперь я могу переключать режим работы между "приемником" и "передатчиком". Более того, я обнаружил несколько дополнительных условий, которые необходимо выполнить (прочитайте комментарии к коду).
Ниже приведен рабочий пример кода, в котором передатчик отправляет какое-то большое сообщение. Получатель получает его, ждет 2 секунды, затем отвечает другим большим сообщением и получает подтверждение для этого сообщения:
Отправитель
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include "printf.h"
const uint64_t pipe01_ = 0xE8E8F0F0A1LL; //пишем трубы должен быть полный адрес, если признает, будет использоваться
const uint64_t pipe02_ = 0xE8E8F0F0A2LL; //хотя бы одного из чтения труб должен быть полный адрес
const uint64_t pipe03_ = 0xA3LL;
const uint64_t pipe04_ = 0xA4LL;
const uint64_t pipe05_ = 0xA5LL;
const uint64_t pipe06_ = 0xA6LL;
RF24 radio(9, 53);
void setup()
{
Serial.begin(115200);
delay(250);
radio.begin();
radio.setChannel(0x57); //не требуется. Но должны быть равны с обеих сторон
radio.setPALevel(RF24_PA_LOW); //не требуется. Но должны быть равны с обеих сторон
radio.enableAckPayload(); //Для возможности изменения полезной нагрузки Ack с помощью writeAckPayload()
radio.openReadingPipe(2, pipe02_); //По крайней мере один из каналов чтения должен быть полным адресом
radio.openWritingPipe(pipe01_); //Канал записи должен быть полным адресом, если для подтверждения будет использоваться
radio.enableDynamicPayloads(); //Если не установлен, размер будет фиксированной длины. Фиксированная длина по умолчанию составляет 32 байта
/*Необходимо выполнить это, если "startListening()" будет использоваться в любом месте приведенного ниже кода.
nRF24L01 запоминает его состояние, даже если Arduino был перезапущен*/
radio.stopListening();
Serial.println("Отправка сообщения...");
char message[32] = "qwertyuiopasdfghjklzxc1234567890"; //какое-то тестовое сообщение
radio.write(message, 32); //Отправить сообщение по предопределенному "каналу записи".
Serial.println("Waiting for response...");
radio.startListening(); //Сбрасывает буфер TX и переключает режим радиомодуля в "приемник".
uint16_t ack = 123;
radio.writeAckPayload(2, &ack, sizeof(ack)); //Пользовательская полезная нагрузка ACK должна быть установлена после "startListening()". Потому что "startListening()" сбрасывает буфер TX
}
void loop()
{
if (radio.available())
{
char respMessage[33];
memset(respMessage, 0, sizeof(byte) * 33);
while (radio.available())
{radio.read(respMessage, 32);}
Serial.println("respMessage: " + String((const char*)respMessage));
}
}
Приемник
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include "printf.h"
#define period_ 2000
const uint64_t pipe01_ = 0xE8E8F0F0A1LL; //хотя бы одного из чтения труб должен быть полный адрес
const uint64_t pipe02_ = 0xE8E8F0F0A2LL; //пишем трубы должен быть полный адрес, если признает, будет использоваться
const uint64_t pipe03_ = 0xA3LL;
const uint64_t pipe04_ = 0xA4LL;
const uint64_t pipe05_ = 0xA5LL;
const uint64_t pipe06_ = 0xA6LL;
unsigned long checkPoint = 0;
bool messageReceived = false;
RF24 radio(9, 53);
void setup()
{
Serial.begin(115200);
delay(250);
radio.begin();
radio.setChannel(0x57); //не требуется. Но должны быть равны с обеих сторон
radio.setPALevel(RF24_PA_LOW); //не требуется. Но должны быть равны с обеих сторон
radio.enableAckPayload(); //Для возможности изменения полезной нагрузки Ack с помощью writeAckPayload()
radio.openReadingPipe(1, pipe01_); //По крайней мере один из каналов чтения должен быть полным адресом
radio.openWritingPipe(pipe02_); //Канал записи должен быть полным адресом, если будет использоваться подтверждение
radio.enableDynamicPayloads(); //Канал записи должен быть полным адресом, если будет использоваться подтверждение
radio.startListening(); //Если не установлен, размер будет фиксированной длины. Фиксированная длина по умолчанию составляет 32 байта
}
void loop()
{
if (radio.available())
{
char newMessage[33];
memset(newMessage, 0, sizeof(byte) * 33);
while (radio.available())
{radio.read(newMessage, 32);}
Serial.println("newMessage: " + String((const char*)newMessage));
checkPoint = millis();
messageReceived = true;
}
unsigned long timePassed = millis() - checkPoint;
//Когда он получает, контроллер ждет 2 секунды, а затем отправляет ответ только один раз
if (messageReceived && timePassed > period_)
{
messageReceived = false;
checkPoint = millis();
Serial.println("отправка ответа...");
//Это должно быть вызвано перед отправкой чего-либо (кроме подтверждения).
radio.stopListening(); //Сбрасывает буфер TX и переключает режим радиомодуля на передатчик
char response[32] = "1234567890qwertyuiopasdfghjklzxc";
radio.write(response, 32);
unsigned long ack = 0;
if (radio.isAckPayloadAvailable())
{
radio.read(&ack, sizeof(ack));
Serial.println("получено подтверждение: " + String(ack));
}
radio.startListening(); //Сбрасывает буфер TX и переключает режим радиомодуля в "приемник".
}
}
- NRF24L01+ PA не работает с Arduino Mega (работает с Nano)
- SPI с преобразователем уровня на другом конце соединения
- nRF24l01+ вывод мусорных значений
- Отправка структуры данных с 2 полями int из Arduino в Raspberry через NRF24L01
- Питание Arduino Mega 2560 от Raspberry Pi Usb
- Проблема с SPI при использовании трансивера RF24 NRF24L01 со светодиодной матрицей MD_MAX72xx
- Модули NRF24L01 +pa +lna не взаимодействуют
- Как разделить входящую строку?
Строка
qwertyuiopasdfghjklzxc1234567890
содержит 32 символа плюс неявный нулевой терминатор, для которого в массиве нет пробела. Было бы безопаснее объявить это как `char message [] = "..."'. Здесь вы можете страдать от поврежденной памяти., @Christian Lindig