nRF24L01 и Arduino: подключение, код RF24, дальность и решение проблем
nRF24L01 и Arduino: подключение, питание 3,3 V и конденсатор 10 µF, код передатчика и приёмника на RF24, дальность PA+LNA до 1 км, пульт с джойстиком, ESP32 и Pico.
Связка nRF24L01 и Arduino — самый дешёвый и практичный способ передавать данные между двумя платами без кабеля. Этот модуль размером с ноготь работает в диапазоне 2,4 GHz, передаёт до 2 мегабит в секунду и может быть и передатчиком, и приёмником. Он идеален для радиоуправляемых машинок, беспроводных джойстиков, станции, которая передаёт показания садового датчика в дом, или узлов сигнализации, предупреждающих друг друга. Стандартная версия на открытом пространстве достаёт примерно на 100 метров, а версия nRF24L01+PA+LNA с внешней антенной в хороших условиях — до 1 километра.
В этом руководстве ты узнаешь, как работает модуль, какие пины SPI он использует, почему его нужно питать от 3,3 V и как конденсатор 10 µF решает самую частую проблему. Затем напишешь код передатчика и приёмника с библиотекой RF24, разберёшься с адресами и каналами, соберёшь пульт с джойстиком, подключишь модуль к ESP32 и Raspberry Pi Pico и, наконец, пошагово решишь проблемы «radio.begin() false» и «данные не приходят».

Что такое nRF24L01 и как он работает?
nRF24L01 — микросхема радиоприёмопередатчика на 2,4 GHz от Nordic Semiconductor; почти на всех продаваемых сегодня модулях стоит улучшенная версия nRF24L01+ или совместимый клон. Модуль общается с Arduino по SPI: Arduino записывает по SPI настройки и данные для отправки, а остальное делает чип. Аппаратный протокол Nordic под названием Enhanced ShockBurst снабжает каждый пакет адресом и CRC (проверкой ошибок). Когда приёмник правильно получает пакет, он автоматически отправляет передатчику подтверждение (ACK); если ACK не пришёл, передатчик сам повторяет попытку. Так что код просто говорит «отправить», а повторы и проверка ошибок происходят аппаратно.
Пакет несёт не больше 32 байт данных. Это может показаться мало, но две оси джойстика, несколько кнопок и несколько значений датчиков легко помещаются. Модуль использует один из 126 каналов, а частота канала равна 2400 + номер канала (MHz); канал 76, например, — это 2476 MHz. Приёмник может одновременно слушать 6 разных адресов (так называемых каналов-труб, pipes), так что один хаб может собирать данные с шести передатчиков.
| Параметр | Значение |
|---|---|
| Частота | 2,400–2,525 GHz (126 каналов с шагом 1 MHz) |
| Скорость передачи | 250 kbps, 1 Mbps, 2 Mbps |
| Напряжение питания | 1,9–3,6 V (на практике 3,3 V) |
| Входные пины | Выдерживают 5 V (CE, CSN, SCK, MOSI) |
| Выходная мощность | 0, −6, −12, −18 dBm |
| Ток (передача, 0 dBm) | Около 11,3 mA |
| Ток (приём, 2 Mbps) | Около 13,5 mA |
| Режим power down | Около 900 nA |
| Чувствительность приёмника | −94 dBm (250 kbps), −85 dBm (1 Mbps), −82 dBm (2 Mbps) |
| Размер полезной нагрузки | 1–32 байта |
| Интерфейс | SPI, до 10 MHz |
| Число каналов-труб (pipes) | 6 |
nRF24L01 или nRF24L01+PA+LNA
В продаже встречаются два типа модулей. У стандартного модуля антенна — зигзагообразная медная дорожка на плате. Версия nRF24L01+PA+LNA добавляет перед тем же приёмопередатчиком микросхему радиотракта: PA (Power Amplifier, усилитель мощности) усиливает исходящий сигнал, а LNA (Low Noise Amplifier, малошумящий усилитель) усиливает слабые входящие сигналы, прежде чем они дойдут до чипа. Внешняя антенна накручивается на разъём SMA. У обоих модулей одинаковая распиновка и один и тот же код, и они без проблем общаются друг с другом; разница в дальности и потребляемом токе. Цифры ниже приблизительные и зависят от окружения.

| Параметр | nRF24L01+ (печатная антенна) | nRF24L01+PA+LNA |
|---|---|---|
| Антенна | Напечатана на плате | Внешняя антенна SMA |
| Выходная мощность | До 0 dBm (1 mW) | До +20 dBm (100 mW), в зависимости от модели |
| Пиковый ток при передаче | Около 12 mA | До 115 mA |
| Пиковый ток при приёме | Около 13,5 mA | До 45 mA |
| Дальность на открытом воздухе (250 kbps) | 50–100 м | 800–1100 м |
| Дальность в помещении | 10–30 м, 1–2 стены | Несколько этажей и десятки метров |
| Рекомендуемое питание | Пин 3,3 V + конденсатор 10 µF | Отдельный стабилизатор 3,3 V + конденсатор |
Распиновка nRF24L01 и подключение к Arduino
У модуля 8 выводов в разъёме 2×4. Вывод с квадратной контактной площадкой — вывод 1, это GND; рядом с ним VCC. CE (Chip Enable) переключает модуль в режим прослушивания или передачи, а CSN (Chip Select Not) притягивают к LOW, чтобы сказать по шине SPI «сейчас я обращаюсь к тебе». SCK, MOSI и MISO — стандартные линии SPI, и они должны идти на фиксированные пины SPI платы, а CE и CSN можно подключить к любым цифровым пинам. Пин IRQ не обязателен; он уходит в LOW, когда приходит пакет или заканчивается передача, и используется, если хочешь работать с прерываниями. Как работает SPI — в статье Что такое SPI, а полную карту пинов своей платы смотри в утилите «Распиновка».
| Вывод nRF24L01 | Назначение | Arduino Uno / Nano | Arduino Mega | ESP32 | Raspberry Pi Pico |
|---|---|---|---|---|---|
| 1 GND | Земля | GND | GND | GND | GND |
| 2 VCC | Питание (3,3 V) | 3.3V | 3.3V | 3V3 | 3V3(OUT) |
| 3 CE | Выбор режима | D9 | D9 | GPIO 4 | GP6 |
| 4 CSN | Выбор микросхемы SPI | D10 | D10 | GPIO 5 | GP5 |
| 5 SCK | Тактирование SPI | D13 | D52 | GPIO 18 | GP2 |
| 6 MOSI | Данные от платы к модулю | D11 | D51 | GPIO 23 | GP3 |
| 7 MISO | Данные от модуля к плате | D12 | D50 | GPIO 19 | GP4 |
| 8 IRQ | Прерывание (не обязательно) | Не подключён | Не подключён | Не подключён | Не подключён |
Самая частая ошибка: питание и конденсатор 10 µF
Большинство проблем с nRF24L01 вызывает не код, а питание. В момент передачи модуль потребляет короткие резкие импульсы тока. Длинные перемычки и слабый источник 3,3 V за этими импульсами не успевают; напряжение на мгновение проседает, и чип отправляет повреждённый пакет, пропускает ACK или сам перезагружается. По официальной документации пин 3,3 V у Arduino Uno отдаёт не больше 50 mA; этого хватает для стандартного модуля, но не для версии PA+LNA, которая потребляет до 115 mA. На некоторых клонах Nano пин 3,3 V питается от микросхемы USB-UART и ещё слабее. Симптомы будут знакомы: write() то срабатывает, то нет, модуль работает лучше, если его потрогать, или дальность заканчивается на нескольких метрах.
- Конденсатор 10 µF: поставь электролитический конденсатор 10 µF между выводами VCC и GND модуля, как можно ближе к ним. Длинная ножка (+) идёт к VCC, а сторона с полосой (−) — к GND. Подойдёт и любое значение от 10 до 100 µF; почему это помогает, читай в статье Что такое конденсатор.
- Керамический конденсатор 100 nF: маленький керамический конденсатор (маркировка 104) параллельно электролитическому отфильтровывает высокочастотные помехи. Маркировку конденсаторов можно расшифровать утилитой «Код конденсатора».
- Плата-адаптер: 8-контактные платы-адаптеры, которые продаются для nRF24L01, уже содержат стабилизатор AMS1117-3.3 и конденсаторы. На VCC адаптера подаёшь 5 V, а модуль получает чистые 3,3 V.
- Отдельный стабилизатор: версию PA+LNA питай не от пина 3,3 V Arduino, а от отдельного стабилизатора AMS1117-3.3, запитанного от 5 V, и соедини все земли вместе.
- Короткие провода: по возможности делай перемычки короче 10 см; длинные болтающиеся провода мешают и питанию, и сигналам SPI.

Установка библиотеки RF24
- В Arduino IDE открой Инструменты › Управлять библиотеками (Tools › Manage Libraries) или щёлкни по значку библиотек слева.
- Введи в поиске RF24 и установи библиотеку RF24 от TMRh20. RF24Network, RF24Mesh и RF24Ethernet — отдельные библиотеки, для начала они не нужны.
- После установки в меню «Файл › Примеры › RF24» (File › Examples) появится пример GettingStarted. Код в этой статье использует синтаксис RF24 версии 1.5 и новее.
- Если библиотека устанавливается впервые, следуй шагам из статьи Как добавить библиотеку в Arduino.
Адрес, канал и скорость: как договорить два модуля
Чтобы два модуля слышали друг друга, некоторые настройки должны быть в точности одинаковыми с обеих сторон. Представь разговор по рации: если не настроены одна частота (канал), одна скорость речи (скорость передачи) и один позывной (адрес), другую сторону не услышишь. Адрес — массив из 5 байт, и проще всего записать его в коде строкой из 5 символов, например «00001». Думай об адресе не как об имени устройства, а как об общем пути между двумя устройствами: передатчик кладёт пакеты на этот путь, а приёмник, слушающий его, их подбирает. Важен и размер полезной нагрузки: RF24 по умолчанию использует пакеты фиксированного размера, и если приёмник ждёт не тот же размер, что у передатчика, он пакет не увидит.
| Настройка | Функция RF24 | Значение в этой статье | Примечание |
|---|---|---|---|
| Канал | setChannel(76) | 76 (2476 MHz) | 0–125; должен совпадать с обеих сторон |
| Скорость передачи | setDataRate(RF24_250KBPS) | 250 kbps | Меньше скорость — больше дальность |
| Адрес | stopListening(address) / openReadingPipe(1, address) (передатчик / приёмник) | «00001» | Цель передатчика = труба приёмника |
| Размер полезной нагрузки | setPayloadSize(sizeof(data)) | 32 байта (5 в примере с джойстиком) | При фиксированном размере обе стороны должны совпадать |
| Выходная мощность | setPALevel(RF24_PA_LOW) | Низкая | Совпадать не обязана; задаёт дальность |
| Auto-ACK и CRC | Включены по умолчанию | 16-битный CRC | Если отключаешь, отключай с обеих сторон |
Код передатчика (TX)
Для первой проверки подключи две Arduino к двум разным USB-портам и разнеси модули на 1–2 метра. Загрузи код передатчика ниже в одну из них. Каждую секунду она отправляет пронумерованное сообщение и выводит в монитор порта, подтвердил ли его приёмник. Не забудь выставить в мониторе порта 115200 бод.
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10); // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001"; // iki tarafta aynı adres / same address on both sides
6char message[32]; // en fazla 32 bayt / 32 bytes max
7uint16_t counter = 0;
8
9void setup() {
10 Serial.begin(115200);
11 if (!radio.begin()) { // modül cevap vermiyor / module not responding
12 Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
13 while (true) {}
14 }
15 radio.setChannel(76); // kanal 76 = 2476 MHz / channel 76 = 2476 MHz
16 radio.setDataRate(RF24_250KBPS); // en uzun menzil / longest range
17 radio.setPALevel(RF24_PA_LOW); // masa testi için düşük güç / low power for desk tests
18 radio.setPayloadSize(sizeof(message)); // paket boyu 32 bayt / 32-byte payload
19 radio.stopListening(address); // verici modu + hedef adres / TX mode + target address
20}
21
22void loop() {
23 snprintf(message, sizeof(message), "Merhaba BlueGrays #%u", counter++);
24 bool ok = radio.write(message, sizeof(message)); // onay (ACK) geldi mi? / was it acknowledged?
25 if (ok) {
26 Serial.print(F("Gonderildi: "));
27 Serial.println(message);
28 } else {
29 Serial.println(F("Onay gelmedi"));
30 }
31 delay(1000);
32}Код приёмника (RX)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10); // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001"; // vericiyle aynı adres / same address as the transmitter
6char message[32];
7
8void setup() {
9 Serial.begin(115200);
10 if (!radio.begin()) {
11 Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
12 while (true) {}
13 }
14 radio.setChannel(76); // ayarlar vericiyle aynı / settings match the transmitter
15 radio.setDataRate(RF24_250KBPS);
16 radio.setPALevel(RF24_PA_LOW);
17 radio.setPayloadSize(sizeof(message));
18 radio.openReadingPipe(1, address); // 1 numaralı boruyu aç / open pipe 1
19 radio.startListening(); // alıcı modu / RX mode
20}
21
22void loop() {
23 if (radio.available()) { // paket geldi mi? / has a packet arrived?
24 radio.read(message, sizeof(message));
25 Serial.print(F("Gelen: "));
26 Serial.println(message);
27 }
28}radio.write() отправляет пакет и возвращает true, если приёмник его подтвердил; с настройками по умолчанию она 15 раз повторяет попытку с интервалом около 1,5 мс, прежде чем вернуть false. На приёмнике openReadingPipe(1, address) назначает трубе 1 адрес передатчика, startListening() переводит модуль в режим прослушивания, available() сообщает, ждёт ли пакет, а read() копирует его в переменную. Если в мониторе порта приёмника идут строки с растущим номером вроде «Gelen: Merhaba BlueGrays #0», «#1», «#2» (принято: привет), связь работает.
Дальность: от 100 метров до 1 километра
Дальность определяют три вещи: выходная мощность, чувствительность приёмника и окружение. Чем ниже скорость передачи, тем более слабые сигналы может расшифровать приёмник; чувствительность −94 dBm на 250 kbps, но −82 dBm на 2 Mbps. Эти 12 dB разницы означают примерно вчетверо большую дальность на открытом пространстве. Стены, деревья, тела людей и металлические поверхности заметно ослабляют сигналы 2,4 GHz, а роутеры Wi-Fi, Bluetooth-устройства и микроволновки делят тот же диапазон.
| Скорость передачи | Чувствительность приёмника | Относительная дальность | Когда использовать |
|---|---|---|---|
| 250 kbps | −94 dBm | Наибольшая | Пульты, удалённые датчики |
| 1 Mbps | −85 dBm | Средняя | Общее применение (по умолчанию в RF24) |
| 2 Mbps | −82 dBm | Наименьшая | Высокая скорость, малое расстояние |
Важен и выбор канала. Самые используемые каналы Wi-Fi 1, 6 и 11 занимают примерно 2401–2473 MHz; каналы nRF24L01 74–83 лежат выше и тише, если поблизости нет роутера на Wi-Fi-канале 12 или 13. В Европе (и в Турции) нелицензируемый диапазон 2,4 GHz — от 2400 до 2483,5 MHz, так что не используй каналы выше 83; каналы 100 и выше, которые советуют некоторые примеры в интернете, лежат вне этого диапазона, а точные границы зависят от правил твоей страны. Чтобы увеличить дальность, попробуй следующее:
- Используй 250 kbps: пультам и данным датчиков высокая скорость не нужна, а низкая даёт дальность.
- Сначала наладь питание, потом поднимай мощность: RF24_PA_MAX имеет смысл только со стабильными 3,3 V и конденсатором; повышение мощности при слабом питании только ухудшает дело.
- Ставь антенны высоко и одинаково: 1–2 метра над землёй и обе антенны вертикально в одну сторону заметно увеличивают дальность.
- Держи подальше от металла: не клади модуль в металлическую коробку и не ставь вплотную к большому аккумуляторному блоку.
- Оберни неэкранированную плату PA+LNA: если обмотать модуль PA+LNA без металлического экрана изолентой, а затем алюминиевой фольгой, он меньше мешает сам себе; фольга не должна касаться выводов и разъёма антенны.
- Не передавай без антенны: работа модуля PA+LNA на полной мощности без подключённой антенны перегружает усилитель мощности.
Беспроводной пульт с джойстиком
Теперь соберём настоящий проект: джойстиком на одной Arduino беспроводно управляем сервоприводом и светодиодом на второй. На передатчике пин VRx джойстика идёт на A0, VRy — на A1, а кнопка (SW) — на D2; подробности — в статье Модуль джойстика. На приёмнике сигнальный провод сервопривода идёт на D3, а светодиод — на D4 через резистор 220 Ω. Подключение nRF24L01 на обеих сторонах такое же, как в таблице выше.
Аккуратнее всего отправлять несколько значений в одном пакете через struct (структуру). Здесь есть важная деталь: нужно использовать типы фиксированного размера вроде int16_t и uint8_t. На Arduino Uno int занимает 2 байта, а на ESP32 — 4, и компилятор ESP32 ещё добавляет в конец структуры байты выравнивания. Если одна и та же структура на Uno занимает 5 байт, а на ESP32 — 6, размеры полезной нагрузки не совпадают, и данные не приходят вовсе. __attribute__((packed)) убирает это выравнивание и делает структуру размером 5 байт на любой плате. Сначала передатчик:
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData { // her kartta 5 bayt / 5 bytes on every board
5 int16_t x;
6 int16_t y;
7 uint8_t button;
8};
9
10RF24 radio(9, 10); // CE, CSN pinleri / CE, CSN pins
11const uint8_t address[6] = "JOY01"; // kumanda adresi / remote address
12JoystickData data;
13
14void setup() {
15 pinMode(2, INPUT_PULLUP); // joystick butonu (SW) / joystick button (SW)
16 if (!radio.begin()) {
17 while (true) {} // modül yok / no module
18 }
19 radio.setChannel(76);
20 radio.setDataRate(RF24_250KBPS);
21 radio.setPALevel(RF24_PA_HIGH); // orta-yüksek güç / medium-high power
22 radio.setPayloadSize(sizeof(data));
23 radio.stopListening(address); // verici modu / TX mode
24}
25
26void loop() {
27 data.x = analogRead(A0); // VRx ekseni 0-1023 / VRx axis 0-1023
28 data.y = analogRead(A1); // VRy ekseni 0-1023 / VRy axis 0-1023
29 data.button = (digitalRead(2) == LOW); // basılıysa 1 / 1 when pressed
30 radio.write(&data, sizeof(data));
31 delay(50); // saniyede 20 paket / 20 packets per second
32}Затем приёмник, управляющий сервоприводом и светодиодом:
1#include <SPI.h>
2#include <RF24.h>
3#include <Servo.h>
4
5struct __attribute__((packed)) JoystickData { // vericiyle birebir aynı / identical to the transmitter
6 int16_t x;
7 int16_t y;
8 uint8_t button;
9};
10
11RF24 radio(9, 10); // CE, CSN pinleri / CE, CSN pins
12const uint8_t address[6] = "JOY01"; // vericiyle aynı / same as the transmitter
13JoystickData data;
14Servo servo;
15unsigned long lastPacket = 0;
16
17void setup() {
18 pinMode(4, OUTPUT); // LED çıkışı / LED output
19 servo.attach(3); // servo sinyal pini / servo signal pin
20 if (!radio.begin()) {
21 while (true) {}
22 }
23 radio.setChannel(76);
24 radio.setDataRate(RF24_250KBPS);
25 radio.setPALevel(RF24_PA_HIGH);
26 radio.setPayloadSize(sizeof(data));
27 radio.openReadingPipe(1, address);
28 radio.startListening(); // alıcı modu / RX mode
29}
30
31void loop() {
32 if (radio.available()) {
33 radio.read(&data, sizeof(data));
34 servo.write(map(data.x, 0, 1023, 0, 180)); // X ekseni -> servo açısı / X axis -> servo angle
35 digitalWrite(4, data.button ? HIGH : LOW); // buton LED'i yakar / button lights the LED
36 lastPacket = millis();
37 }
38 if (millis() - lastPacket > 500) { // 0,5 sn paket yok: güvenli konum / no packet for 0.5 s: failsafe
39 servo.write(90);
40 digitalWrite(4, LOW);
41 }
42}Передатчик отправляет 20 пакетов в секунду; для каждого пакета приёмник переводит ось X в 0–180 градусов и записывает в сервопривод. Часть failsafe (защита при потере связи) на приёмнике очень важна: если в пульте сядет батарейка или он выйдет из зоны действия, последняя команда не будет применяться вечно; если 0,5 секунды не приходит ни одного пакета, сервопривод встаёт в центр, а светодиод гаснет. Если собираешь робот-машинку, в том же месте останавливай моторы. Питание сервопривода от отдельного источника 5 V, а не от пина 5V Arduino, тоже не даёт броскам тока сервопривода мешать nRF24L01. Подключи ось Y к драйверу моторов L298N — и получится беспроводная робот-машинка; подробности о сервоприводе — в статье Что такое сервопривод.
Двусторонняя связь и несколько передатчиков
nRF24L01 не может одновременно передавать и слушать, но есть простой способ получить двустороннюю связь — ACK payload, то есть данные, отправленные внутри пакета подтверждения. Приёмник заранее готовит через writeAckPayload() данные, которые прикрепит к следующему ACK (например, напряжение батареи или показание датчика), а передатчик после успешного write() читает этот ответ через available() и read(). Для этого обе стороны должны вызвать enableDynamicPayloads() и enableAckPayload(). Для нескольких передатчиков у приёмника 6 труб: трубы 0 и 1 получают полный 5-байтовый адрес, а трубы 2–5 делят остальную часть адреса трубы 1 и отличаются лишь одним байтом. В RF24 этот байт — первый символ массива адреса, поэтому адреса вроде «1Node», «2Node» и «3Node» отличаются только первым символом. Для больших сетей есть библиотеки RF24Network и RF24Mesh.
Подключение nRF24L01 к ESP32
Библиотека RF24 без изменений работает на ESP32, а radio.begin() использует шину VSPI по умолчанию: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. Для CSN хорошо подходит GPIO 5, а для CE — GPIO 4. Стабилизатор 3,3 V на платах ESP32 DevKit сильнее, чем у Uno, но конденсатор 10 µF не пропускай. На моделях вроде ESP32-C3 или ESP32-S3 пины SPI по умолчанию другие, так что проверь карту пинов своей платы. Поскольку Wi-Fi у ESP32 тоже работает на 2,4 GHz, при совместном использовании выбирай канал nRF24L01 подальше от Wi-Fi-канала роутера. Код ниже читает на ESP32 пакеты передатчика с джойстиком; на той же основе ESP32 можно сделать шлюзом, который пересылает данные с узлов nRF24L01 в интернет. Если плата для тебя новая, начни со статьи Что такое ESP32.
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData { // packed olmasa 6 bayt olurdu / 6 bytes without packed
5 int16_t x;
6 int16_t y;
7 uint8_t button;
8};
9
10RF24 radio(4, 5); // CE = GPIO 4, CSN = GPIO 5 pinleri / CE = GPIO 4, CSN = GPIO 5 pins
11const uint8_t address[6] = "JOY01";
12JoystickData data;
13
14void setup() {
15 Serial.begin(115200);
16 if (!radio.begin()) { // varsayılan VSPI: SCK 18, MISO 19, MOSI 23 / default VSPI pins
17 Serial.println("nRF24L01 bulunamadi!");
18 while (true) delay(1000);
19 }
20 radio.setChannel(76);
21 radio.setDataRate(RF24_250KBPS);
22 radio.setPALevel(RF24_PA_HIGH);
23 radio.setPayloadSize(sizeof(data)); // packed sayesinde 5 bayt / 5 bytes thanks to packed
24 radio.openReadingPipe(1, address);
25 radio.startListening();
26}
27
28void loop() {
29 if (radio.available()) {
30 radio.read(&data, sizeof(data));
31 Serial.printf("X=%d Y=%d Buton=%d\n", data.x, data.y, data.button);
32 }
33}Если нужно связать между собой только платы ESP32, хорошим вариантом будет и ESP-NOW, которому не нужен дополнительный модуль; преимущество nRF24L01 в том, что он работает и с дешёвыми маломощными платами вроде Uno, Nano и Pro Mini.
nRF24L01 с Raspberry Pi Pico и MicroPython
Для MicroPython на Pico используется драйвер nrf24l01.py из официального репозитория micropython-lib. Файл можно скопировать на Pico через Thonny или установить с компьютера командой mpremote mip install nrf24l01. Подключение использует SPI0: SCK = GP2, MOSI = GP3, MISO = GP4, CSN = GP5, CE = GP6 и VCC = 3V3(OUT). Настройки драйвера по умолчанию отличаются от RF24 (канал 46, полезная нагрузка 16 байт), поэтому для связи с Arduino в коде явно задаём канал, скорость и размер полезной нагрузки. Код ниже расшифровывает на Pico пакеты передатчика с джойстиком:
1from machine import Pin, SPI
2import struct
3import utime
4from nrf24l01 import NRF24L01, POWER_2, SPEED_250K
5
6spi = SPI(0, sck=Pin(2), mosi=Pin(3), miso=Pin(4)) # SPI0 pinleri / SPI0 pins
7csn = Pin(5, mode=Pin.OUT, value=1) # CSN pini GP5 / CSN pin GP5
8ce = Pin(6, mode=Pin.OUT, value=0) # CE pini GP6 / CE pin GP6
9
10nrf = NRF24L01(spi, csn, ce, channel=76, payload_size=5) # Arduino ile aynı / same as the Arduino
11nrf.set_power_speed(POWER_2, SPEED_250K) # -6 dBm güç, 250 kbps / -6 dBm power, 250 kbps
12nrf.open_rx_pipe(1, b"JOY01") # vericinin adresi / transmitter address
13nrf.start_listening() # alıcı modu / RX mode
14print("Dinleniyor... / Listening...")
15
16while True:
17 if nrf.any(): # paket geldi mi? / packet waiting?
18 x, y, button = struct.unpack("<hhB", nrf.recv()) # 2 + 2 + 1 bayt / 2 + 2 + 1 bytes
19 print("X:", x, "Y:", y, "Buton:", button)
20 utime.sleep_ms(5)struct.unpack("<hhB") превращает 5 пришедших байт в два знаковых 16-битных числа и один байт; начальный «<» задаёт порядок байтов little-endian, который используют AVR и ESP32. Если модуль не найден, драйвер выдаёт «nRF24L01+ Hardware not responding» (устройство не отвечает) — аналог MicroPython для begin(), возвращающей false на Arduino. Если Pico для тебя в новинку, сначала прочитай Что такое Raspberry Pi Pico.
radio.begin() возвращает false: пошаговое решение
Если в мониторе порта появляется «nRF24L01 bulunamadi» (не найден) или сообщение «radio hardware is not responding!!» (радиомодуль не отвечает) из примеров RF24, Arduino вообще не может общаться с модулем по SPI. В таком случае проблема почти всегда в подключении или питании, а не в коде. Сначала загрузи диагностический скетч ниже; он выводит все настройки модуля в читаемом виде.
1#include <SPI.h>
2#include <RF24.h>
3#include "printf.h" // RF24 ile gelir / ships with RF24
4
5RF24 radio(9, 10); // kendi CE, CSN pinlerin / your CE, CSN pins
6
7void setup() {
8 Serial.begin(115200);
9 printf_begin(); // printPrettyDetails için / needed for printPrettyDetails
10 bool ok = radio.begin();
11 Serial.print(F("begin(): "));
12 Serial.println(ok ? "true" : "false");
13 Serial.print(F("isChipConnected(): "));
14 Serial.println(radio.isChipConnected() ? "true" : "false");
15 radio.printPrettyDetails(); // tüm ayarları yazdır / print every setting
16}
17
18void loop() {
19}- Проверь MOSI и MISO: эти два провода путают чаще всего. На Uno и Nano MOSI = D11, MISO = D12 и SCK = D13; на Mega это 51, 50 и 52.
- Совпадают ли CE и CSN с кодом: если написано RF24 radio(9, 10), CE идёт на D9, а CSN — на D10. Пример GettingStarted из RF24 использует пины 7 и 8; если пробуешь пример без изменений, подключай так.
- Питание 3,3 V? Измерь мультиметром между VCC и GND; должно быть 3,0–3,6 V. Если модуль когда-нибудь подключали к 5 V, он может быть повреждён.
- Посмотри вывод printPrettyDetails: если адреса и значения регистров все показывают 0x00 или 0xff, шина SPI не работает. Если значения выглядят осмысленно, но связи всё равно нет, проблема в пине CE, настройках или питании.
- Укороти провода и снизь скорость SPI: при длинных или болтающихся проводах напиши RF24 radio(9, 10, 4000000), чтобы снизить скорость SPI с 10 MHz по умолчанию до 4 MHz.
- Замени модуль: если всё остальное в порядке, попробуй запасной модуль; в дешёвых наборах по несколько штук может попасться неисправный.
Данные не приходят или приходят с перебоями: частые проблемы
| Симптом | Вероятная причина | Решение |
|---|---|---|
| begin() возвращает true, но до приёмника ничего не доходит | Канал, скорость, адрес или размер полезной нагрузки различаются на двух сторонах | Сравни четыре настройки рядом в обоих скетчах |
| Нет данных от Uno к ESP32 | Разный размер структуры (5 и 6 байт) | Используй типы фиксированного размера и __attribute__((packed)) |
| write() возвращает false, но приёмник данные получает | ACK приёмника не доходит до передатчика, обычно из-за питания приёмника | Добавь конденсатор 10 µF и на модуль приёмника |
| На экране постоянно пустые или мусорные данные | Плохо сидящий провод SPI или оборванное соединение MISO | Замени провода и снизь скорость SPI до 4 MHz |
| Рядом не работает, а если разнести — работает | Приёмник перегружен на полной мощности | Используй setPALevel(RF24_PA_LOW) или RF24_PA_MIN |
| Работает лучше, если потрогать | Нестабильное питание или неэкранированный PA+LNA | Конденсатор, отдельный стабилизатор и экранирование фольгой |
| Связь пропадает через несколько метров | Скорость 2 Mbps, слабое питание или помехи от Wi-Fi | 250 kbps, чистое питание, канал от 74 до 83 |
Идеи проектов с nRF24L01
- Беспроводной пульт для робот-машинки: управляй робот-машинкой с расстояния в десятки метров пультом с двумя джойстиками.
- Садовая станция датчиков: отправляй данные датчика влажности почвы и температуры с передатчика на батарейках на дисплей в доме. С radio.powerDown() модуль во сне потребляет около 900 nA; время работы от батареи можно прикинуть утилитой «Время работы от батареи».
- Беспроводная сигнализация двери и движения: включай зуммер на хабе, когда срабатывает PIR-датчик или геркон.
- Температурная сеть на несколько комнат: собирай показания датчиков из шести комнат на одном приёмнике по шести трубам.
- Шлюз на ESP32: пересылай данные с узлов nRF24L01 в интернет, на телефон или на панель мониторинга через ESP32.
- Беспроводное табло: обновляй 7-сегментное табло в спортзале с пультов с кнопками.
Несмотря на низкую цену, nRF24L01 по сравнению с Bluetooth даёт большую дальность, меньшую задержку и поддержку многих устройств; взамен он требует лишь чистого питания 3,3 V и одинаковых настроек с обеих сторон. Если нужно управление с телефона, лучше подойдёт Bluetooth-модуль HC-05, а для дальности в километры — LoRa; сравнение вариантов — в статье Модули беспроводной связи для Arduino. В приложении BlueGrays есть проекты вроде связи между двумя Arduino, управления сервоприводом и светодиодом с джойстика и машинки с дистанционным управлением — пошагово, со схемами и готовым кодом.
Частые вопросы
Какая дальность у nRF24L01?
Стандартный nRF24L01+ с печатной антенной на 250 kbps достаёт примерно на 50–100 метров на открытом пространстве и на 10–30 метров в помещении в зависимости от стен. Версия nRF24L01+PA+LNA с внешней антенной на открытом пространстве без препятствий может достать на 800–1100 метров. Чтобы получить такие цифры, нужны чистое питание 3,3 V, конденсатор 10 µF и низкая скорость передачи.
Может ли nRF24L01 работать от 5V?
Нет. Пин VCC работает в пределах от 1,9 до 3,6 V, и 5 V могут уничтожить чип. Зато входные пины CE, CSN, SCK и MOSI выдерживают 5 V, поэтому их можно подключать к пинам SPI у Arduino Uno без преобразователя уровней. Если хочешь питать модуль от 5 V, используй плату-адаптер со стабилизатором AMS1117-3.3.
Почему появляется ошибка «radio hardware is not responding»?
Это сообщение выводится, когда radio.begin() возвращает false, и означает, что Arduino не может общаться с модулем по SPI. Самые частые причины — перепутанные MOSI и MISO, пины CE и CSN, не совпадающие с кодом, слабое питание или питание 5 V и болтающиеся перемычки. Проверь подключение и посмотри вывод printPrettyDetails(), чтобы сузить круг поиска.
nRF24L01 или Bluetooth HC-05: что выбрать?
Если между Arduino нужны большая дальность, малая задержка и несколько устройств, лучший выбор — nRF24L01. Если хочешь управлять с телефона, выбирай Bluetooth-модуль вроде HC-05 или ESP32, ведь телефоны не понимают протокол nRF24L01. HC-05 обычно достаёт примерно на 10 метров, а nRF24L01 за сопоставимую цену — гораздо дальше.
Сколько передатчиков может слушать один приёмник nRF24L01?
Приёмник может одновременно слушать 6 труб, так что напрямую собирает данные с 6 передатчиков. Трубы 2–5 делят основную часть адреса трубы 1 и отличаются лишь одним байтом. Для большего числа узлов можно опрашивать передатчики по очереди или строить гораздо более крупные сети с библиотеками RF24Network и RF24Mesh.
Можно ли подключить nRF24L01 к телефону?
Напрямую нет. Хотя nRF24L01 работает в том же диапазоне 2,4 GHz, он не использует протоколы Wi-Fi или Bluetooth. Если нужно управление с телефона, поставь в центр сети nRF24L01 плату ESP32 и передавай данные на телефон по Wi-Fi или Bluetooth. Тогда удалённые узлы общаются по nRF24L01, а телефон — с ESP32.
Что собрать после прочтения
Все проекты
Односторонняя связь между двумя Arduino
Ты заставляешь две Arduino разговаривать по одному проводу: нажми кнопку на одной, и на другой загорится светодиод, нажми снова — погаснет. Плата-передатчик сообщает о нажатии кнопки коротким сообщени

Двусторонняя связь между двумя Arduino
Две Arduino соединены проводами и разговаривают друг с другом: нажми кнопку на одной, и на другой загорится свет, нажми снова — погаснет. На обеих платах одна и та же программа, поэтому каждая и отпра

Управление светодиодами джойстиком
Наклони рычажок джойстика до упора в любую сторону, и загорится светодиод этого направления: вправо, влево, вверх и вниз — четыре разных цвета. Отпусти рычажок, он вернётся в центр, и все светодиоды п

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

Машинка на L298N с управлением по Bluetooth
Преврати телефон в пульт и управляй своей машинкой-роботом. Arduino получает команды из приложения-пульта на телефоне через Bluetooth-модуль и вращает колёса через драйвер моторов; машинка едет вперёд

Управление светодиодом с телефона по Bluetooth
Небольшая репетиция того, как включать и выключать свет в комнате с телефона. Bluetooth-модуль передаёт в Arduino буквы, отправленные с телефона; одна буква включает красный светодиод, другая — зелёны

Включение светодиода ИК-приёмником и пультом
Как будто управляешь тремя отдельными лампами, не вставая с кресла: клавиши 1, 2 и 3 на пульте включают синий, красный и зелёный светодиоды, а клавиши 4, 5 и 6 выключают их в том же порядке. Клавиша п

Универсальный ИК-пульт на ESP32 (ИК-приёмник + пульт + 3 светодиода + зуммер + OLED)
С ESP32 можно читать обычный ИК-пульт и управлять с него своим устройством! В этом проекте инфракрасный приёмник (протокол NEC, 38 kHz) ловит сигналы 20-кнопочного ИК-пульта. Каждой кнопке задано своё действие: кнопки 1, 2 и 3 переключают три отдельных светодиода, кнопка PWR выключает все, а цифры 4–9 показывают на OLED особые символы. OLED-дисплей SSD1306 крупно показывает последнюю нажатую кнопку и описание действия.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

