Много мусора у NRF24L01 + PA + LNA

,

Здравствуйте, столкнулся с проблемой большего количества ломаных битов и медленной передачей между модулями NRF24L01+PA+LNA. Заказал их естественно с Тэму, ибо в стране нет нормальных или такие же с Китая по завышенной цене. Итак, два модуля стоят на стабилизаторе YL-105, одни подключен к Уно, а другой к Про Микро(5 B, видимо тоже китайский аналог, потому что распознается как Arduino Leonardo и часто глючит). Оба модуля выдают информацию о себе в монитор, оба отлично сканируют сеть, но при попытке передать между ними конкретное слово происходят беды.

Код на Уно:

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>




RF24 radio(7, 8);

const byte address[6] = "00001";




unsigned long lastStatsTime = 0;

unsigned int packetsReceived = 0;




char getMostFrequentChar(char* chunk) {

  int counts[256] = {0}; 

  int maxCount = 0;

  char bestChar = '?';

  

  for (int i = 0; i < 5; i++) {

    char c = chunk[i];

    counts[(unsigned char)c]++;

    if (counts[(unsigned char)c] > maxCount) {

      maxCount = counts[(unsigned char)c];

      bestChar = c;

    }

  }

  return bestChar;

}




void setup() {

  Serial.begin(9600);

  

  if (!radio.begin()) {

    Serial.println("Радиомодуль не отвечает!");

    while (1) {}

  }

  

  radio.openReadingPipe(0, address);

  radio.setChannel(108);

  radio.setPALevel(RF24_PA_MIN);

  radio.setDataRate(RF24_1MBPS);

  

  radio.setAutoAck(false);

  radio.disableCRC();

  

  radio.startListening();

  Serial.println("RX (Uno) запущен. Ожидаю данные...");

  

  lastStatsTime = millis(); 

}




void loop() {

  if (radio.available()) {

    char receivedData[21] = {0}; 

    

    radio.read(&receivedData, 20);

    receivedData[20] = '\0'; 

    

    char decodedWord[5]; 

    

    for (int i = 0; i < 4; i++) {

      decodedWord[i] = getMostFrequentChar(&receivedData[i * 5]);

    }

    decodedWord[4] = '\0'; 

    

    Serial.print("Получено: ");

    Serial.print(receivedData);

    Serial.print(" | Расшифровано: ");

    Serial.println(decodedWord);

    

    packetsReceived++;

  }

  

  if (millis() - lastStatsTime >= 1000) {

    Serial.print("=========================================\n");

    Serial.print(">>> СТАТИСТИКА: Принято пакетов за сек: ");

    Serial.println(packetsReceived);

    Serial.print("=========================================\n");

    

    packetsReceived = 0; 

    lastStatsTime = millis();

  }

}

Код на про микро:

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>






RF24 radio(7, 8);

const byte address[6] = "00001";





char payload[21] = "PPPPPIIIIINNNNNGGGGG";






void setup() {




  Serial.begin(9600);

  delay(2000);

 

  if (!radio.begin()) {

    Serial.println("Радиомодуль не отвечает!");

    while (1) {}

  }




 




  radio.openWritingPipe(address);

  radio.setChannel(108);




  radio.setPALevel(RF24_PA_MIN);




  radio.setDataRate(RF24_1MBPS);




  radio.setAutoAck(false);

  radio.disableCRC();




 

  radio.stopListening();

  Serial.println("TX (Pro Micro) запущен. Начинаю отправку...");




}




void loop() {

  radio.write(&payload, 20);

  Serial.print("Отправлено: ");

  Serial.println(payload);




  delay(50);

}

Вывод от Уно:(про микро не интересует, он спокойно отправляет)

=========================================


>>> СТАТИСТИКА: Принято пакетов за сек: 7


=========================================


Получено: ��PPIIIIHa�NNNGGGGF | Расшифровано: PING


Получено: a��PPIIIIH�NNNGGGGD | Расшифровано: PING


Получено: @�PPIIIII@�NNGGGGG | Расшифровано: PING


Получено: a�PPPIIIIH�NNNGGGGD | Расшифровано: PING


Получено: P_�PPIIIII@_�NNGGGGG | Расшифровано: PING


Получено: P@��PIIIIIN��NGGGGG | Расшифровано: PING


Получено: @_�PPIIIIIH�NNGGGGG | Расшифровано: PING


Получено: Pa��PIIIIIN@_�NGGGGG | Расшифровано: PING

В среднем приходят за секунду 4-7 пакетов, дай бог выдаст 11 ну и умудряется получить всего 2. Так как я хочу собрать радиоуправляемый самолетик, то мне нужна скорость передачи и чтобы не было часто такого мусора. Оно хоть и расшифровывает это как PING, но когда я попытался таким методом запустить удаленно бесколлекторный движок, то он принял мусор как максимальное значение и успешно намотал шторы.
Чтобы избавиться от этого я пытался экранировать, подключал через BEC(5V/3A) от ESC, но все напрасно, такой же мусор.

Вопрос: Как можно избежать этого мусора и сделать быстрее передачу пакетов? Может стоит поменять вообще модуль и взяться за другой?

P.S. готовые летные контроллеры не предлагать, не интересно.

переписать код

Нынешний код, мягко говоря, не очень. Ошибок просто куча

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

если этот код работает, к чему вы тему открыли? Работает - и радуйтесь

Проблем в том, что оно не работает как надо. Часто битые символы и мало пакетов прилетает. Почему так? Я не понимаю, поэтому и открыл тему. Да и похожих не видел в интернете

А другие библиотеки не испытывали?

Возможно уже есть успешные проекты…

Я сделал на 433MHz на самых дешевых приемопередатчиках и использовал свой код.


void lider()
{
  digitalWrite(outPin, HIGH);   // включаем вывод
  delayMicroseconds(500);        // задержка в 50 микросекунд

  digitalWrite(outPin, LOW);    // выключаем вывод
  delayMicroseconds(3000);        // задержка в 50 микросекунд

  digitalWrite(outPin, HIGH);   // включаем вывод
  delayMicroseconds(500);        // задержка в 50 микросекунд

}
void bit0()
{
  digitalWrite(outPin, LOW);    // выключаем вывод
  delayMicroseconds(1250);        // задержка в 50 микросекунд

  digitalWrite(outPin, HIGH);   // включаем вывод
  delayMicroseconds(500);        // задержка в 50 микросекунд
}
void bit1()
{ digitalWrite(outPin, LOW);    // выключаем вывод
  delayMicroseconds(750);        // задержка в 50 микросекунд

  digitalWrite(outPin, HIGH);   // включаем вывод
  delayMicroseconds(500);        // задержка в 50 микросекунд
}


Ошибки конечно есть. Там передача температуры раз в минуту циклом.

Работает много лет. Расстояние метров 300.

вы уж определитесь…

Пробовал ещё библиотеку Mirf, но безуспешно. Да и из радиомодулей есть только NRF, а они на 2.4Ггц работает вроде

Код - работает.

Сигнал - не доходит и оомается.

Вопрос: почему не доходит и ломается сигнал?

попробуйте передавать нужные данные сразу в десятикратном дублировании

Если у вас из вашей нагрузки в 20 байт, часть принялось нормально, а часть битое - это на 99% не сигнал, а кривой код.

NRF24 это цифровой передатчик, тут или принимается то что отправлено, или идет сплошной мусор.

Это не решит проблему скорости передачи. А так как по идеи через эти модули должен будет управляться самолётик, то нужна скорость.

Про то что модули NRF24 это полная помойка, вы что, первый раз слышите? Какой самолетик, у них дальность 5-10м
С антенной чуть дальше.

Берите нормальный модуль, НС-12 или Лору

Вот это у вас зачем вставлено?
Вы понимаете, что это одна из причин, почему у вас идут битые сообщения?

habr

очень подробно описано

не запускали сканер?

Как раз с этим хотя бы что то приходит. Если стоит CRC ничего не приходит, хоть ты тресни. Я уже что не делаю с кодом, ничего не доходит чисто. И да, слышал что модули полное г-вно. Но как другим удается связать их нормально на несчастные, пусть то будет, 100 метров, а я эти на пол метра связать не могу??

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

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

Пробовал, уже припаян конденсаторы, сканировал эфир, там все хорошо. А как передать конкретное слово, то теряются пакеты и мусор появляется

И как добиться передачи сообщения? В этом весь и вопрос

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

на 100 метрах работает esp32 на экономном протоколе esp now, но скорее всего с дополнительной антенной лучше делать!

вот только не обижайтесь пж, но я так понимаю вы свою попу не отрывали, и не тестировали модуль на больших расстояниях а только вблизи друг друга ?))) хотя бы на расстоянии 3 метров тестировали бы…
radio.setPALevel(RF24_PA_MIN, 0);// для самых ленивых существует)))

тестировали YL-105 ? именно в момент передачи! что бы убедиться что не проседает питание…

короче много у вас лени)))

Передатчик (Pro Micro):


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

RF24 radio(7, 8);
const byte address[6] = "00001";

// Структура для передачи данных (команда и значение)
struct DataPacket {
  char command[5]; // например "PING" или "MOTR"
  int value;       // значение от 0 до 255 для двигателя
};

DataPacket payload;

void setup(){
  Serial.begin(9600);
  if (!radio.begin()) {
    Serial.println("Радиомодуль не отвечает!");
    while (1) {}
  }
  
  radio.openWritingPipe(address);
  radio.setChannel(108);
  // Для тестов на столе - МИНИМАЛЬНАЯ мощность с отключенным LNA!
  radio.setPALevel(RF24_PA_MIN, 0); // 0 - отключает LNA
  radio.setDataRate(RF24_1MBPS);
  
  // Включаем надежность
  radio.setAutoAck(true);    // Включить подтверждения
  radio.enableAckPayload();  // Разрешить маленький ответ (опционально)
  // CRC включен по умолчанию, но можно явно:
  radio.setCRCLength(RF24_CRC_16);
  
  radio.stopListening();
  
  // Заполняем тестовые данные
  strcpy(payload.command, "PING");
  payload.value = 0;
  Serial.println("TX (Pro Micro) запущен.");
}

void loop() {
  // Отправляем структуру
  bool report = radio.write(&payload, sizeof(payload));
  
  if (report) {
    Serial.print("Отправлено: ");
    Serial.print(payload.command);
    Serial.print(" ");
    Serial.println(payload.value);
  } else {
    Serial.println("Ошибка отправки (нет подтверждения)");
  }
  
  delay(50);
}






Приемник (Uno):


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

RF24 radio(7, 8);
const byte address[6] = "00001";

struct DataPacket {
  char command[5];
  int value;
};

DataPacket receivedData;
unsigned long lastStatsTime = 0;
unsigned int packetsReceived = 0;

void setup() {
  Serial.begin(9600);
  if (!radio.begin()) {
    Serial.println("Радиомодуль не отвечает!");
    while (1) {}
  }
  
  radio.openReadingPipe(0, address);
  radio.setChannel(108);
  radio.setPALevel(RF24_PA_MIN, 0); // Обязательно MIN и LNA=0 для тестов!
  radio.setDataRate(RF24_1MBPS);
  
  // Настройки, соответствующие передатчику
  radio.setAutoAck(true);
  radio.setCRCLength(RF24_CRC_16);
  
  radio.startListening();
  Serial.println("RX (Uno) запущен. Ожидаю данные...");
  lastStatsTime = millis();
}

void loop() {
  if (radio.available()) {
    radio.read(&receivedData, sizeof(receivedData));
    
    // Если мы здесь - пакет прошел проверку CRC и пришел целым!
    Serial.print("Получено: ");
    Serial.print(receivedData.command);
    Serial.print(" ");
    Serial.println(receivedData.value);
    
    packetsReceived++;
  }
  
  // Статистика раз в секунду
  if (millis() - lastStatsTime >= 1000) {
    Serial.print("=========================================\n");
    Serial.print(">>> СТАТИСТИКА: Принято пакетов за сек: ");
    Serial.println(packetsReceived);
    Serial.print("=========================================\n");
    packetsReceived = 0;
    lastStatsTime = millis();
  }
}

но сдается мне что при тестах вы вовсе модуль на модуль ложили, и вообще не читали толком)))