NRF24L01 + Arduino: радиосвязь 2.4 ГГц между платами
Модуль nRF24L01 связывает две платы Arduino по радио на частоте 2.4 ГГц. В комнате берёт 10-20 метров, на открытом пространстве 80-100 метров. Это не WiFi и не Bluetooth: у чипа Nordic Semiconductor свой протокол с адресацией до шести каналов приёма, и в библиотеке RF24 про WiFi нет ни одной строчки.
Модуль стоит 200-400 рублей, и для базовой схемы их нужно два, ведь связь двусторонняя. Проводов семь: три линии SPI, питание, земля, выбор микросхемы и включение приёмника. Стартовать проще, чем кажется, потому что библиотека прячет регистры чипа и оставляет только пять понятных вызовов.
Пока модуль едет в посылке, каркас протокола проверяется в нашем симуляторе Arduino: там работает логика отправки и разбора пакета, а настоящий радиоканал проверяется только на живом железе.
Распиновка: три сигнала SPI и три уникальных
Интерфейс у модуля SPI, поэтому базовая проводка совпадает с любой другой SPI-платой: MOSI на D11, MISO на D12, SCK на D13. Эти три линии можно разделить с картой SD или дисплеем, они работают по очереди. Уникальных сигналов у nRF24L01 всего три: CSN (выбор микросхемы, в коде это SS), CE (включение передатчика или приёмника) и IRQ (прерывание). CSN и CE заводят на любые свободные цифровые пины, обычно берут D10 и D9. IRQ подключают только тогда, когда скетч не должен ждать опроса радио.
Полная раскладка на Arduino Uno: VCC к 3.3 В, GND к GND, MOSI к D11, MISO к D12, SCK к D13, CSN к D10, CE к D9, IRQ к D8 по желанию. Питание 3.3 В обязательно, и это стоит сказать прямо: чип Nordic рассчитан на диапазон от 1.9 до 3.6 В, подача 5 В сожжёт его мгновенно. На дешёвых платах с адаптером уже стоит LDO, и тогда питать можно от 5 В. На «голых» модулях без стабилизатора нужен отдельный AMS1117-3.3.
Грабли питания: главная причина потери пакетов
Вторая по частоте проблема после неправильной распиновки это просадка питания. Штатный выход 3.3 В на Uno рассчитан примерно на 50 мА, а модуль в режиме приёма забирает около 13.5 мА, в передаче на максимальной мощности около 11.5 мА. Формально всё укладывается, но пульсация по цепи получается такой, что часть пакетов не проходит аппаратную проверку CRC и молча теряется. Отдельный LDO AMS1117-3.3 с конденсатором 10 мкФ на входе и 0.1 мкФ на выходе снимает вопрос полностью. Готовый адаптер с переключателем 3.3 и 5 В делает то же самое.
#include <SPI.h>#include <RF24.h>RF24 radio(9, 10); // CE, CSNconst byte addr[6] = "1Node";void setup() { radio.begin(); radio.openWritingPipe(addr); radio.setPALevel(RF24_PA_LOW); radio.stopListening(); radio.setDataRate(RF24_250KBPS);}void loop() { const char text[] = "Hello"; radio.write(&text, sizeof(text)); delay(1000);}Приёмник отличается двумя строками: openReadingPipe(0, addr) вместо openWritingPipe и startListening() вместо stopListening(). Дальше работает radio.available(), который отвечает на вопрос «есть ли пакет», и radio.read(&buf, sizeof(buf)), который его забирает. Адрес передатчика и приёмника должен совпадать до байта: в примере это шесть символов «1Node», а в реальном проекте удобнее брать шесть цифр, потому что такие адреса удобно читать в дампе.
Мощность задаётся radio.setPALevel: RF24_PA_LOW хватает в одной комнате, RF24_PA_MAX пробивает стену и поднимает ток передачи до 11.5 мА. Скорость выбирается radio.setDataRate: 250 кбит/с самая устойчивая к помехам, 1 Мбит/с это компромисс, а 2 Мбит/с для видеопотока не годится. Канал ставится radio.setChannel, и лучше брать нестандартный номер вроде 100, чтобы не попасть на WiFi-роутер.
| Параметр | nRF24L01+ | Bluetooth HC-05 |
|---|---|---|
| Частота | 2.4 ГГц (свой протокол) | 2.4 ГГц (Bluetooth Classic) |
| Дальность | 80-100 м открыто / 10-20 м в помещении | 10-15 м |
| Скорость | 250 кбит/с - 2 Мбит/с | 1-3 Мбит/с |
| Подключение | SPI (6 пинов) | UART (TX/RX) |
| Парные устройства | 1 передатчик - 6 приёмников | точка-точка |
| Питание | 3.3 В (критично стабильное) | 3.6-6 В (на плате LDO) |
Что сначала не получилось
Первый стенд я собрал на двух платах, запитав модули от пина 3V3 Uno. Связь была, но рваная: пакеты доходили через раз, а в Serial порой появлялись случайные байты вместо принятого текста. Я сначала решил, что дело в скорости, и перевёл модули с 1 Мбит/с на 250 кбит/с. Стало немного лучше, но потери остались, потому что скорость тут ни при чём. Помог только отдельный стабилизатор AMS1117-3.3 с конденсаторами.
Вторая ошибка была логической. Я использовал один и тот же массив адресов на обеих платах, но в передатчике забыл stopListening(), а в приёмнике не вызвал startListening(). Модуль вроде как работал, но в Serial не было ничего, кроме пустоты. Проверка радио из примера библиотеки показала, что приёмник слушает адрес 0x0000000000, а у меня был другой. Синхронизация режима и адреса закрыла вопрос за минуту.
Личный опыт: стенд на двух столах
Рабочий стенд у меня получился из двух Uno, двух модулей nRF24L01 и двух адаптеров питания. Задача была простая: передатчик шлёт короткий пакет со счётчиком раз в секунду, приёмник печатает его и зажигает светодиод, когда номер нечётный. На столе в одной комнате связь шла без потерь на расстоянии около 6 метров через одну бетонную стену. Настройки, которые в итоге остались в скетче: скорость 250 кбит/с, мощность RF24_PA_MAX, канал 100.
Проверял я это не только на глаз. Библиотека RF24 умеет показывать RSSI принятого пакета, и по шкале из её документации -50 dBm считается отличным сигналом, а значения около -100 dBm и ниже означают, что приём на грани. В комнате показания держались в зоне отличного сигнала, на улице при 40 метрах прямой видимости по RSSI чувствительность заметно падала, и на 1 Мбит/с пакеты начали теряться там, где на 250 кбит/с всё ещё проходили. Это ровно тот эффект, о котором предупреждает даташит: с ростом скорости падает чувствительность приёмника.
Авторская позиция: что взять новичку
Берите модули с адаптером питания, где есть переключатель 3.3 и 5 В и ряд контактов под обе стороны. Такие платы стоят чуть дороже, зато снимают половину граблей до того, как новичок начнёт искать причину. Модуль без переходника под первый проект не берите: там начинается с вопроса, откуда взять 3.3 В и почему ток прыгает. Библиотеку берите RF24, она лежит в менеджере библиотек Arduino IDE и работает с обоими вариантами модуля. И сразу закладывайте два модуля: связь двусторонняя, а значит нужен и передатчик, и приёмник.