Телеметрия и радиосвязь (nRF24L01+)

Цель этого теста — убедиться, что радиоканал работает в обе стороны: кубсат отправляет пакеты, а наземная станция (отдельная плата ESP32) их принимает.

Тест минимальный: 8-байтный пакет со счётчиком и тестовым числом раз в секунду. После него можно переходить к полной миссии (main_full), где формат пакета будет шире.

Параметры радио

Параметры одинаковые на обеих сторонах, иначе связь не пойдёт:

  • канал 76;

  • pipe TBOY1;

  • скорость 250 kbps;

  • AutoAck выключен (один-ко-многим, без подтверждений);

  • размер пакета фиксированный — 8 байт (sizeof(TelemetryPacket)).

В main_full пакет другой — 32 байта (TboyAirPkt), поэтому тестовый Nano TX и приёмник полной миссии напрямую несовместимы. Тестовая пара (nrf24_nano_tx + nrf24_esp32_rx) — отдельный учебный сценарий «работает ли железо».

Распиновка

Кубсат (Nano) — CE=D9, CSN=D10 (см. Подготовка среды разработки).

Базовая станция (ESP32, отдельная плата) — другие пины: CE=GPIO2, CSN=GPIO4, VSPI 18/19/23. Это особенность ESP32-DevKit: «удобные» SPI-пины не совпадают с Nano-шилдом, поэтому библиотека инициализируется с другими номерами.

Питание nRF24L01+ — только 3.3 В. На 5 В модуль выгорает.

Необходимые библиотеки

  • RF24 (TMRh20).

Передатчик: Arduino Nano (на кубсате)

examples/nrf_test/nrf24_nano_tx/nrf24_nano_tx.ino
#include <SPI.h>
#include <RF24.h>

// Nano (как в main_full): CE=D9, CSN=D10
const uint8_t PIN_NRF_CE = 9;
const uint8_t PIN_NRF_CSN = 10;

RF24 radio(PIN_NRF_CE, PIN_NRF_CSN);
const byte PIPE[6] = "TBOY1";

struct TelemetryPacket {
  uint32_t ms;
  uint16_t counter;
  int16_t value;
};

TelemetryPacket pkt;
uint16_t counterTx = 0;

void setup() {
  Serial.begin(115200);
  delay(300);

  if (!radio.begin()) {
    Serial.println("nRF24 begin FAILED");
    while (true) delay(1000);
  }

  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);
  radio.setChannel(76);
  radio.setAutoAck(false);
  radio.setPayloadSize(sizeof(TelemetryPacket));
  radio.openWritingPipe(PIPE);
  radio.stopListening();

  Serial.println("Nano TX ready (ch=76, pipe=TBOY1)");
}

void loop() {
  pkt.ms = millis();
  pkt.counter = counterTx++;
  pkt.value = (int16_t)(1000 + (pkt.counter % 200)); // тестовое значение

  bool ok = radio.write(&pkt, sizeof(pkt));

  Serial.print("TX ");
  Serial.print(ok ? "OK " : "FAIL ");
  Serial.print("cnt=");
  Serial.print(pkt.counter);
  Serial.print(" ms=");
  Serial.print(pkt.ms);
  Serial.print(" val=");
  Serial.println(pkt.value);

  delay(1000);
}

Раз в секунду шлёт пакет с инкрементируемым счётчиком и тестовым value (циклится 1000…1199).

Что видно в Serial Monitor (115200) при запуске Nano TX:

Nano TX ready (ch=76, pipe=TBOY1)
TX OK cnt=0 ms=312 val=1000
TX OK cnt=1 ms=1313 val=1001
TX OK cnt=2 ms=2313 val=1002
...

TX OK без приёмника всё равно будет, потому что AutoAck выключен — Nano не ждёт подтверждения и считает любую отправку успешной. Реальная проверка связи — на стороне приёмника.

Приёмник: ESP32 (наземная станция)

examples/nrf_test/nrf24_esp32_rx/nrf24_esp32_rx.ino
#include <SPI.h>
#include <RF24.h>

// ESP32 (как в main_esp32_nrf_rx): CE=2, CSN=4, VSPI=18/19/23
const uint8_t PIN_NRF_CE = 2;
const uint8_t PIN_NRF_CSN = 4;

RF24 radio(PIN_NRF_CE, PIN_NRF_CSN);
const byte PIPE[6] = "TBOY1";

struct TelemetryPacket {
  uint32_t ms;
  uint16_t counter;
  int16_t value;
};

void setup() {
  Serial.begin(115200);
  delay(300);

  if (!radio.begin()) {
    Serial.println("nRF24 begin FAILED");
    while (true) delay(1000);
  }

  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);
  radio.setChannel(76);
  radio.setAutoAck(false);
  radio.setPayloadSize(sizeof(TelemetryPacket));
  radio.openReadingPipe(1, PIPE);
  radio.startListening();

  Serial.println("ESP32 RX ready (ch=76, pipe=TBOY1)");
  Serial.println("Waiting packets...");
}

void loop() {
  if (!radio.available()) {
    delay(10);
    return;
  }

  TelemetryPacket pkt;
  radio.read(&pkt, sizeof(pkt));

  Serial.print("RX cnt=");
  Serial.print(pkt.counter);
  Serial.print(" tx_ms=");
  Serial.print(pkt.ms);
  Serial.print(" val=");
  Serial.println(pkt.value);
}

Что видно в Serial Monitor (115200) на стороне ESP32:

ESP32 RX ready (ch=76, pipe=TBOY1)
Waiting packets...
RX cnt=4 tx_ms=4313 val=1004
RX cnt=5 tx_ms=5313 val=1005
RX cnt=6 tx_ms=6313 val=1006
...

Если cnt растёт без пропусков — связь стабильная. Если идут скачки (cnt=10, 14, 18) — пакеты теряются, антенна не оптимальна или дальность на пределе.

Как запустить тест связи

  1. Залейте nrf24_nano_tx.ino на Nano кубсата. В Serial Monitor (115200) Nano должен начать выдавать TX OK.

  2. Залейте nrf24_esp32_rx.ino на отдельную плату ESP32. В Serial Monitor (115200) ESP32 должен сначала писать Waiting packets..., а потом RX cnt=….

  3. Если оба видны и cnt совпадает — всё работает.

Если nRF24 begin FAILED

  • Питание не 3.3 В (или просадка под нагрузкой) — у nRF большой пик тока при передаче, дешёвый стабилизатор Nano может проседать.

  • Контакт CE/CSN или одна из линий SPI оторваны — пошевелите провода у разъёма.

  • Модуль действительно сгорел (часто — после случайного 5 В).

Если TX OK идёт, а на приёмнике тишина

  • Параметры радио на сторонах отличаются (канал, pipe, скорость или размер пакета). Сравните настройки.

  • Антенна на одной из сторон не накручена.

  • Слишком далеко / стены / помехи 2.4 ГГц (рядом мощный Wi-Fi или Bluetooth).