Библиотека RF24
Радиомодули nRF24L01+: связь двух и более плат на 2,4 ГГц пакетами до 32 байт.
nRF24L01+ — дешёвый приёмопередатчик на 2,4 ГГц с дальностью от десятков метров до километра у версии с усилителем. Библиотека RF24 прячет регистры чипа за понятной моделью: у каждого получателя есть адрес-«труба», отправитель открывает трубу на запись и шлёт структуру, получатель слушает и читает.
Пакет — до 32 байт. Удобнее всего слать структуру целиком: sizeof(data) с обеих сторон должен совпадать.
Установка и подключение
В менеджере библиотек ищите RF24 автора TMRh20. Если менеджер предложит поставить зависимости — соглашайтесь. Как открыть менеджер и что делать, если библиотека не находится, — в общей статье про библиотеки.
#include <SPI.h>
#include <RF24.h>Создание объекта — обычно до setup():
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "NODE1"; // адрес трубы, 5 символов
radio.begin(); // в setup()
radio.openWritingPipe(address); // передатчик
// или
radio.openReadingPipe(1, address); // приёмник
radio.startListening();Методы
Только то, что нужно в обычном скетче. Сигнатуры сверены с версией 1.6.2.
begin()- Инициализировать модуль. false — модуль не отвечает по SPI: провода или питание.
isChipConnected()- Проверить, что чип действительно есть на шине.
openWritingPipe(const uint8_t* address)- Куда отправлять: адрес получателя.
openReadingPipe(uint8_t number, const uint8_t* address)- Слушать адрес на трубе 1–5.
startListening() / stopListening()- Перейти в приём или вернуться в передачу. Перед write() слушание останавливают.
available()- Есть ли принятый пакет.
read(void* buf, uint8_t len)- Забрать пакет в буфер.
write(const void* buf, uint8_t len)- Отправить пакет и дождаться подтверждения. true — доставлено.
setPALevel(rf24_pa_dbm_e level)- Мощность: RF24_PA_MIN для отладки рядом, RF24_PA_MAX для дальности — но тогда нужен конденсатор по питанию.
setDataRate(rf24_datarate_e rate)- RF24_250KBPS даёт лучшую дальность, RF24_2MBPS — скорость.
setChannel(uint8_t ch)- Канал 0–125; уходите от Wi-Fi выше 100.
setRetries(uint8_t delay, uint8_t count)- Пауза и число повторов при неудаче.
printDetails()- Вывести конфигурацию в Serial — при отладке видно, что чип живой (нули везде — не живой).
Пример
#include <SPI.h>
#include <RF24.h>
RF24 radio(9, 10);
const byte address[6] = "NODE1";
const bool TRANSMITTER = true; // на второй плате — false
struct Packet { unsigned long ms; int value; };
void setup() {
Serial.begin(9600);
if (!radio.begin()) { Serial.println("Модуль не найден"); while (1); }
radio.setPALevel(RF24_PA_LOW);
radio.setDataRate(RF24_250KBPS);
if (TRANSMITTER) {
radio.openWritingPipe(address);
radio.stopListening();
} else {
radio.openReadingPipe(1, address);
radio.startListening();
}
}
void loop() {
if (TRANSMITTER) {
Packet p = { millis(), analogRead(A0) };
bool ok = radio.write(&p, sizeof(p));
Serial.println(ok ? "Доставлено" : "Нет ответа");
delay(500);
} else if (radio.available()) {
Packet p;
radio.read(&p, sizeof(p));
Serial.print(p.ms); Serial.print(": "); Serial.println(p.value);
}
}Один скетч на обе платы: меняется только константа TRANSMITTER. Так проще держать структуру пакета одинаковой.
На чём попадаются
begin() возвращает false или printDetails() печатает нули
Модуль не виден по SPI. Питание строго 3,3 В, CE и CSN как в конструкторе, провода короткие.
Работает рядом, теряет пакеты на расстоянии
Просадка питания при передаче. Конденсатор 10–100 мкФ прямо на выводах питания модуля — обязательная деталь.
Приёмник молчит
Адреса, канал и скорость должны совпадать на обеих платах, а приёмник — вызвать startListening().
Пакет приходит с мусором
Разный размер структуры на платах — например, int на UNO и на ESP32 разной длины. Используйте типы фиксированной ширины: int16_t, uint32_t.