База знаний · Датчики и модули
Радиомодули и Arduino: nRF24L01+, 433 МГц, HC-12 и LoRa
Пять вольт убивают nRF24, антенна на 433 МГц длиной 172 мм, а заводские настройки HC-12 выходят за разрешённую полосу.
Слово «радиомодуль» в поиске означает три совершенно разные вещи. Первая — приёмопередатчик на 2,4 ГГц, который сам собирает пакет, сам ждёт подтверждения и сам повторяет посылку. Вторая — пара деталей на 433 МГц за полторы сотни рублей, где всю работу делает плата, а модуль только включает и выключает несущую. Третья — LoRa, радио для километров и одной посылки в минуту. Разбираем все три: что покупать, как подключать, что писать и почему оно молчит.
Три семейства, между которыми выбирают
Выбор проще, чем кажется. Нужны две платы рядом и надёжный обмен — берите 2,4 ГГц. Нужна одна кнопка через стену за копейки — 433 МГц. Нужно, чтобы «просто работало как провод», — HC-12.
| Модуль | Частота | Что это | Скорость | Дальность | Цена | Чем платите |
|---|---|---|---|---|---|---|
| nRF24L01+ | 2,4 ГГц | приёмопередатчик с подтверждением | 250 кбит/с … 2 Мбит/с | до 100 м | 162 ₽ | только 3,3 В и занятая шина SPI |
| FS1000A + MX-RM-5V | 433,92 МГц | отдельно передатчик, отдельно приёмник | до 5 кбит/с | до 100 м с антенной | 144 ₽ пара | нет подтверждения, плата отбивает биты сама |
| HC-12 | 433,4 … 473 МГц | провод по воздуху, обычный UART | 1200 … 115200 бод | до 1 км | 711 ₽ | из коробки светит мощнее, чем разрешено |
| LoRa на SX1276 | 433 или 868 МГц | дальняя связь редкими короткими посылками | сотни бит/с | километры | у нас нет | цена и скорость улитки |
Сначала про закон, потом про провода
Эфир — общий, и полосы в нём поделены. Радиолюбительские модули работают в участках, открытых для устройств малого радиуса действия: по решению ГКРЧ это 433,075 … 434,79 МГц с мощностью около 20 мВт и 2400 … 2483,5 МГц с мощностью до 100 мВт. Разрешение при этом не нужно.
Неприятность в том, что модули умеют заметно больше разрешённого. Чип nRF24L01+ по паспорту Nordic перестраивается от 2400 до 2525 МГц — и сам паспорт добавляет: «какой участок вам доступен, определяют правила регулятора». HC-12 из ста своих каналов попадает в разрешённую полосу только первыми четырьмя. А совет из интернета «уйдите на канал 100, там нет Wi-Fi» означает выход за границу полосы.
С мощностью история такая же. Библиотека LoRa по умолчанию ставит 17 дБм, то есть 50 мВт. HC-12 приезжает с завода на восьмом уровне — это 100 мВт. Для полосы 433 МГц и то и другое многовато: разрешено около двадцати. Лечится одной строкой в скетче, и на дальности в комнате это никак не скажется.
nRF24L01+: проблема не в радио, а в питании
Это самый популярный модуль из трёх, и почти все жалобы на него — про питание. На плате стоит чип с рабочим напряжением 1,9 … 3,6 В. Пять вольт на выводе VCC выводят его из строя сразу и навсегда. Зато сигнальным ножкам пятивольтовая логика не страшна: паспорт разрешает на входах до 5,25 В — но только пока на самом VCC не больше 3,3 В. Поэтому Uno общается с модулем напрямую, без всяких преобразователей уровней.
| Параметр | Значение | Что это значит |
|---|---|---|
| Питание модуля | 1,9 … 3,6 В | 5 В убивают модуль |
| Уровни на сигнальных ножках | до 5,25 В | но только пока VCC не выше 3,3 В |
| Ток передачи | 11,3 мА | на максимальной мощности 0 дБм |
| Ток приёма | 13,5 мА | на скорости 2 Мбит/с |
| Ток в спячке | 900 нА | меньше, чем утечка обычного светодиода |
| Данных в пакете | 0 … 32 байта | жёсткий предел, длина занимает 6 бит |
| Каналов | 126 штук с шагом 1 МГц | разрешены только 0 … 83 |
Цифры тока маленькие — 11,3 мА в передаче, 13,5 мА в приёме. И всё же питание от вывода 3V3 самой Arduino работает через раз. Дело не в среднем токе, а в том, что модуль переключается между приёмом и передачей за микросекунды, и слабому стабилизатору не хватает скорости: напряжение проседает, чип теряет настройки. Два рабочих решения: конденсатор на 10 мкФ, впаянный прямо на ножки VCC и GND модуля, либо переходник с собственным стабилизатором — заодно он превращает неудобную двухрядную гребёнку в обычную однорядную.
Отдельная ловушка — SPI. Это не UART: линии здесь не перекрещиваются. MISO модуля идёт к MISO платы, MOSI к MOSI. Ошибка встречается постоянно именно потому, что рядом, в разделе про Bluetooth, всё наоборот.
Одна программа на две платы
Обычно для радио пишут два скетча — «передатчик» и «приёмник» — и путаются, какой куда залит. Проще залить в обе платы одно и то же, а роль выбирать перемычкой: замкнули вывод 2 на землю — эта плата передаёт, оставили свободным — принимает.
#include <SPI.h>
#include <RF24.h>
// Одна и та же программа заливается в ОБЕ платы. Роль выбирает перемычка:
// вывод 2 замкнут на GND — плата передаёт, вывод свободен — принимает.
const uint8_t PIN_CE = 9;
const uint8_t PIN_CSN = 10;
const uint8_t PIN_ROLE = 2;
RF24 radio(PIN_CE, PIN_CSN);
// Адрес трубы: пять байт, одинаковые на обеих платах.
const uint8_t ADDRESS[5] = {'T', 'r', 'e', 'm', 'a'};
// Передаём не строку, а структуру: приёмник получит те же поля целыми.
struct Message {
uint16_t number;
int16_t value;
};
Message message;
bool transmitter = false;
unsigned long lastSend = 0;
void setup() {
Serial.begin(9600);
pinMode(PIN_ROLE, INPUT_PULLUP);
transmitter = digitalRead(PIN_ROLE) == LOW;
// begin возвращает false, если модуль не отозвался по SPI. Причин почти
// всегда две: на VCC пришло 5 В вместо 3,3 В или перепутаны MISO и MOSI.
while (!radio.begin()) {
Serial.println("Модуль не отвечает: проверьте питание 3,3 В и провода");
delay(2000);
}
radio.setDataRate(RF24_250KBPS); // самая дальнобойная скорость
radio.setPALevel(RF24_PA_LOW); // на столе большая мощность не нужна
radio.setChannel(76); // 2476 МГц — внутри разрешённой полосы
radio.setPayloadSize(sizeof(Message));
if (transmitter) {
radio.openWritingPipe(ADDRESS);
radio.stopListening();
Serial.println("Эта плата передаёт");
} else {
radio.openReadingPipe(1, ADDRESS);
radio.startListening();
Serial.println("Эта плата принимает");
}
}
void loop() {
if (transmitter) {
if (millis() - lastSend >= 500) {
lastSend = millis();
message.number++;
message.value = analogRead(A0);
// write ждёт подтверждения от приёмника и вернёт false, если его нет.
if (radio.write(&message, sizeof(message))) {
Serial.println("Посылка " + String(message.number) + " принята");
} else {
Serial.println("Посылка " + String(message.number) + " ушла впустую");
}
}
} else if (radio.available()) {
radio.read(&message, sizeof(message));
Serial.println("Номер " + String(message.number) +
", значение " + String(message.value));
}
}
Что здесь важно, кроме проводов.
Адрес. Пять байт, одинаковых на обеих платах. Это не шифрование, а фильтр: модуль просто не разбудит плату, если посылка адресована не ему. Соседский модуль с другим адресом вам не помешает, даже если сидит на том же канале.
Скорость. В библиотеке по умолчанию 1 Мбит/с. Строка с 250 кбит/с делает связь заметно дальнобойнее: чувствительность приёмника растёт с −85 до −94 дБм, а девять децибел — это примерно втрое большее расстояние в чистом поле. Плата за это — пакет летит вчетверо дольше.
Подтверждение. Метод write() возвращает true только если приёмник ответил. Библиотека сама повторит посылку до пятнадцати раз с паузой 1500 мкс — то есть при пропавшей связи скетч простоит на этой строке около двадцати миллисекунд, а если модуль вообще отвалился по SPI, библиотека сдастся через 95 мс. Знать это полезно: «плата иногда подтормаживает» — обычно про это.
433 МГц: две детали и много ручной работы
Комплект из передатчика FS1000A и приёмника MX-RM-5V стоит дешевле обеда и устроен предельно просто. Передатчик — это генератор, который включается, когда на его вход подан единичный уровень. Приёмник — наоборот: выдаёт единицу, пока слышит несущую. Никакого протокола, адресов и подтверждений внутри нет. Всё это должна придумать плата.
Отсюда три следствия, о которых стоит знать до покупки.
Без антенны дальность метры. Длина волны на 433,92 МГц — 691 мм, четверть волны — 172 мм. Ровно такой кусок обычного монтажного провода, припаянный в отверстие ANT, превращает «работает на столе» в «работает через две стены».
Приёмник всегда что-то «слышит». В нём есть автоматическая регулировка усиления: когда сигнала нет, она выкручивает чувствительность на максимум и на выходе появляется случайная чересполосица. Это нормально. Мусор отсеивает контрольная сумма — но плата всё равно тратит время на каждый ложный фронт.
Приёмник боится пульсаций питания. Сервопривод, мигающая лента или преобразователь рядом — и приёмник примет их за сигнал. Помогает отдельное питание или конденсатор по шине.
Библиотеки для 433 МГц: своя и чужая
В каталоге лежат обе. Наша iarduino_RF433 ловит фронты внешним прерыванием, чужая RadioHead — по таймеру, восемь прерываний на каждый бит. На скорости 2000 бит/с это шестнадцать тысяч прерываний в секунду, и заодно занят таймер 1: на Uno перестаёт работать ШИМ на выводах 9 и 10, а вместе с ним — библиотека Servo.
| Библиотека | Модуль | ОЗУ, байт | Флеш, байт | Что ещё забирает |
|---|---|---|---|---|
| RF24 1.6.2 | nRF24L01+ | 63 | 2 214 | шина SPI целиком |
| iarduino_RF433 1.0.2, передатчик | FS1000A | 130 | 1 612 | скетч стоит на время передачи |
| iarduino_RF433 1.0.2, приёмник | MX-RM-5V | 129 | 2 360 | вывод прерывания: на Uno это 2 или 3 |
| RadioHead 1.143.1, RH_ASK | FS1000A и MX-RM-5V | 552 | 6 006 | таймер 1: пропадает ШИМ на выводах 9 и 10 |
| LoRa 0.8.0 | SX1276 | 71 | 2 202 | шина SPI и отдельный вывод прерывания |
| SoftwareSerial | HC-12 | 132 | 2 380 | приём и передача не одновременно |
Замеры сделаны одинаково: минимальный скетч, плата Uno, пустой скетч для сравнения весит 9 байт ОЗУ и 444 байта флеша. Разница между двумя библиотеками для одного и того же комплекта деталей — четыре раза по памяти и почти четыре по программе. Один объект RH_ASK занимает 256 байт: восьмая часть всей памяти Uno уходит на буферы.
Честности ради, у нашей библиотеки тоже есть особенность. Блок приёмника — 105 байт с двумя буферами — заводится в памяти всегда, даже если скетч только передаёт. Поэтому передающий скетч и принимающий весят почти одинаково.
Пример: тот же обмен, но на 433 МГц
Скетч устроен так же, как предыдущий: одна программа на обе платы, роль выбирает перемычка. Названия методов у нашей библиотеки специально повторяют RF24 — если вы уже разобрались с 2,4 ГГц, читать нечего.
#include <iarduino_RF433_Transmitter.h>
#include <iarduino_RF433_Receiver.h>
// Одна программа на обе платы, роль выбирает перемычка на выводе 5.
// Передатчик FS1000A сидит на выводе 4, приёмник MX-RM-5V — на выводе 2:
// приёмнику нужен вывод внешнего прерывания, на Uno это только 2 и 3.
const uint8_t PIN_TX = 4;
const uint8_t PIN_RX = 2;
const uint8_t PIN_ROLE = 5;
iarduino_RF433_Transmitter radioTX(PIN_TX);
iarduino_RF433_Receiver radioRX(PIN_RX);
struct Message {
uint16_t number;
int16_t value;
};
Message message;
bool transmitter = false;
unsigned long lastSend = 0;
void setup() {
Serial.begin(9600);
pinMode(PIN_ROLE, INPUT_PULLUP);
transmitter = digitalRead(PIN_ROLE) == LOW;
if (transmitter) {
radioTX.begin(1000); // 1000 бит в секунду: медленно, зато цепко
radioTX.openWritingPipe(3); // труба — это адрес, у обеих плат один
Serial.println("Эта плата передаёт");
} else {
radioRX.begin(1000);
radioRX.openReadingPipe(3);
radioRX.startListening();
Serial.println("Эта плата принимает");
}
}
void loop() {
if (transmitter) {
if (millis() - lastSend >= 500) {
lastSend = millis();
message.number++;
message.value = analogRead(A0);
// Отправка четырёх байт на скорости 1000 бит/с занимает 67 мс, и всё
// это время скетч стоит: библиотека отбивает импульсы сама.
radioTX.write(&message, sizeof(message));
}
} else {
uint8_t pipe = 0;
// Номер трубы стоит спрашивать всегда: так видно, кто прислал посылку.
if (radioRX.available(&pipe)) {
radioRX.read(&message, sizeof(message));
Serial.println("Труба " + String(pipe) +
", номер " + String(message.number) +
", значение " + String(message.value));
}
}
}
«Труба» здесь — это адрес, только очень короткий: три бита, то есть восемь возможных значений. Ещё пять бит того же байта хранят длину посылки — отсюда предел в 32 байта за раз, ровно как у nRF24, хотя причины совсем разные. Достоверность проверяется контрольной суммой CRC16, её библиотека считает и на передаче, и на приёме.
Главная особенность — время. Библиотека выдаёт каждый полубит вручную, а значит на время передачи скетч не делает ничего другого. Сколько именно это длится, легко посчитать по её же исходнику:
| Отправляем | На 1000 бит/с | На 2000 бит/с | На 5000 бит/с |
|---|---|---|---|
| 4 байта | 67 мс | 33,5 мс | 13,4 мс |
| 16 байт | 163 мс | 81,5 мс | 32,6 мс |
| 32 байта | 291 мс | 145,5 мс | 58,2 мс |
Четыре байта на самой медленной скорости — это 67 миллисекунд молчания платы. Если в примере отправлять посылку каждые 200 мс, треть времени плата занята радио. Полные 32 байта на той же скорости — почти треть секунды. Поэтому на 433 МГц шлют коротко и редко: команду, а не поток.
И одно замечание про вызов available. У него есть форма без параметра — не пользуйтесь ею. В версии 1.0.2 библиотека всё равно пытается записать номер трубы по указателю, которого нет. Форма с переменной, как в примере, и безопаснее, и полезнее: сразу видно, какой передатчик прислал посылку.
HC-12: радио, которое притворяется проводом
Если возиться с пакетами не хочется, есть третий путь. HC-12 — это модуль с обычным портом UART: что отправили в него на одной плате, то и появится из второго модуля на другой. Никаких библиотек, адресов и контрольных сумм — всё внутри. По паспорту до километра связи и чувствительность до −117 дБм, то есть заметно дальше, чем у пары за 144 рубля.
Настраивается модуль AT-командами, и для этого на выводе SET должен быть низкий уровень. Пока он там — модуль слушает команды и в эфир ничего не отдаёт.
#include <SoftwareSerial.h>
// HC-12 — это провод по воздуху: что отправили в его порт на одной плате,
// то и вылезет из порта на другой. Обе платы получают эту программу.
const uint8_t PIN_RX = 10; // к выводу TXD модуля
const uint8_t PIN_TX = 11; // к выводу RXD модуля
const uint8_t PIN_SET = 9; // низкий уровень — модуль слушает AT-команды
SoftwareSerial radio(PIN_RX, PIN_TX);
unsigned long lastSend = 0;
// Отправляем модулю команду и показываем его ответ в мониторе порта.
void command(const char *text) {
radio.println(text);
delay(100);
while (radio.available()) {
Serial.write(radio.read());
}
}
void setup() {
Serial.begin(9600);
radio.begin(9600);
pinMode(PIN_SET, OUTPUT);
digitalWrite(PIN_SET, LOW);
delay(50);
command("AT+C001"); // канал 1 — это 433,4 МГц, шаг каналов 400 кГц
command("AT+P5"); // 11 дБм вместо заводских 20 дБм
command("AT+FU3"); // обычный режим работы
command("AT+RX"); // показать все настройки разом
digitalWrite(PIN_SET, HIGH);
delay(100);
Serial.println("Модуль настроен");
}
void loop() {
// Всё, что пришло по радио, показываем в мониторе порта.
while (radio.available()) {
Serial.write(radio.read());
}
// Раз в секунду отправляем строку в эфир.
if (millis() - lastSend >= 1000) {
lastSend = millis();
radio.println("Привет от соседней платы");
}
}
Две команды в этом скетче важнее остальных. AT+C001оставляет модуль на 433,4 МГц: каналы идут с шагом 400 кГц, и уже пятый выходит за разрешённую полосу. AT+P5 снижает мощность с заводских 20 дБм до 11 — то есть со ста милливатт до двенадцати с половиной. На дальность в квартире это не влияет никак.
| Режим | Ток покоя | Скорость в эфире | Дальность | Задержка посылки |
|---|---|---|---|---|
| FU1 | 3,6 мА | 250 кбит/с в эфире | около 100 м | 15 … 25 мс |
| FU2 | 80 мкА | 250 кбит/с в эфире | около 100 м | 500 мс |
| FU3 | 16 мА | подстраивается | до 1 км | 4 … 80 мс |
| FU4 | 16 мА | 500 бит/с в эфире | до 1,8 км | 1000 мс |
Заводской режим FU3 — компромисс: он подстраивает скорость эфира под скорость порта. Если нужна максимальная дальность, есть FU4, но там между посылками придётся выдерживать больше двух секунд. Если нужно питание от батарейки — FU2 с током покоя 80 мкА, ценой полусекундной задержки.
LoRa: когда нужны километры
LoRa решает другую задачу. Вместо того чтобы передавать быстро, она размазывает сигнал по полосе и передаёт медленно — зато приёмник вылавливает его из-под уровня собственных шумов. Чувствительность SX1276 доходит до −148 дБм при бюджете линии 168 дБ. Для сравнения: лучшее, что может nRF24L01+, это −94 дБм. Разница в 54 децибела — это уже не «подальше», а другой класс задач: датчик на дальнем поле, счётчик в подвале, метка на пасеке.
Платят за это скоростью: реальный поток измеряется сотнями бит в секунду, а посылки шлют раз в минуту или реже. И ценой: модуль стоит дороже, чем плата, к которой его подключают.
В нашем магазине LoRa-модулей нет, поэтому ссылок на товар в этом разделе не будет. Но библиотека в каталоге лежит — LoRa 0.8.0, самая распространённая, и она удивительно скромная: 71 байт ОЗУ и 2202 байта программы. Если возьмётесь, помните про мощность: по умолчанию библиотека выставляет 17 дБм, а для полосы 433 МГц это втрое больше разрешённого.
Что купить
Минимальный комплект для 2,4 ГГц — два модуля nRF24L01+ (арт. 83, 162 ₽) и, если не хочется паять конденсаторы, два переходника со стабилизатором (арт. 688, 144 ₽). Тот же модуль в формате Trema с готовым питанием — арт. 1083, 342 ₽. Если нужна дальность за пределами квартиры — версия с усилителем и внешней антенной, арт. 352, 491 ₽; только следите, чтобы излучаемая мощность осталась в разрешённых ста милливаттах.
Для 433 МГц берут комплект передатчик плюс приёмник (арт. 351, 144 ₽) — для двусторонней связи нужны два таких комплекта, по одному на каждую сторону. Вариант «просто чтобы работало» — HC-12 (арт. 1188, 711 ₽), антенна в комплекте.
Не работает — что проверить
| Что видно | Почему | Что делать |
|---|---|---|
| begin() вернул false, модуль не отзывается | на VCC пришло 5 В или перепутаны MISO и MOSI | питание строго 3,3 В, MISO к MISO, MOSI к MOSI |
| Связь есть на 10 см и пропадает дальше | модуль питается от вывода 3V3 самой платы | конденсатор 10 мкФ прямо на ножки модуля или адаптер со стабилизатором |
| Приёмник ничего не слышит, хотя всё собрано | у плат разные адрес, канал или скорость | три настройки должны совпадать байт в байт |
| write() всегда возвращает false | вторая плата не перешла в режим прослушивания | на приёмнике нужны openReadingPipe и startListening |
| Плата замирает на четверть секунды | передача на 433 МГц занимает скетч целиком | поднять скорость или отправлять реже и короче |
| Приёмник 433 МГц сыплет мусором | так и должно быть: без сигнала АРУ усиливает шум эфира | ничего не чинить, мусор отсеет проверка CRC |
| Дальность на 433 МГц два метра | не припаяна антенна | кусок провода 172 мм на передатчик и такой же на приёмник |
| Пропал ШИМ на выводах 9 и 10 | RadioHead забрал таймер 1 | перейти на iarduino_RF433: она работает на прерывании |
| Серво дёргается, когда работает радио 433 МГц | библиотека Servo и RadioHead делят один таймер | то же лечение: сменить библиотеку радио |
| HC-12 не отвечает на AT-команды | на выводе SET нет нуля или после него не выждали паузу | подать ноль, подождать 40 мс и только потом слать команду |
| Связь рвётся рядом с Wi-Fi роутером | канал nRF24 попал в полосу Wi-Fi | сменить канал, оставаясь в пределах 0 … 83 |
Общее правило для всех трёх семейств: сначала проверяют питание, потом настройки, и только потом грешат на эфир. Радио почти никогда не виновато.
Частые вопросы
Какой радиомодуль выбрать для связи двух Arduino?
Для надёжного обмена между двумя платами рядом — nRF24L01+ на 2,4 ГГц: он сам подтверждает приём и повторяет потерянные посылки. Для одной команды через стену за копейки — пара FS1000A и MX-RM-5V на 433 МГц. Если хочется, чтобы радио вело себя как обычный провод и не требовало библиотек, — HC-12.
Можно ли подключить nRF24L01+ к пятивольтовой Arduino?
Да, напрямую. Сигнальные выводы модуля выдерживают до 5,25 В по паспорту Nordic, но только пока на выводе VCC не больше 3,3 В. Питание строго 3,3 В: пять вольт на VCC выводят модуль из строя сразу.
Почему радиомодуль работает только вплотную?
У nRF24L01+ причина обычно в питании от вывода 3V3 самой платы: при переключении приёма и передачи напряжение проседает. Помогает конденсатор 10 мкФ прямо на ножках модуля или переходник со своим стабилизатором. У модулей 433 МГц причина другая — не припаяна антенна: нужен кусок провода длиной 172 мм.
Какой канал выбрать, чтобы радио не мешало Wi-Fi?
Любой из разрешённых 0…83, лучше за пределами полосы 2412…2472 МГц, где работают каналы Wi-Fi. Совет уходить на канал 100 и выше вреден: там уже не разрешённая для устройств малого радиуса действия полоса, которая заканчивается на 2483,5 МГц.
Нужна ли антенна модулям 433 МГц?
Обязательно. Длина волны на 433,92 МГц — 691 мм, четверть волны — 172 мм. Ровно такой кусок монтажного провода, впаянный в отверстие ANT передатчика и приёмника, поднимает дальность с нескольких метров до десятков.
Сколько байт можно передать за одну посылку?
У nRF24L01+ — не больше 32 байт: длина хранится в шести битах поля управления. У библиотеки iarduino_RF433 для модулей 433 МГц предел тот же, 32 байта, потому что длина занимает пять бит заголовка. Больше данных отправляют несколькими посылками.
Законно ли пользоваться такими модулями в России?
Да, если оставаться в полосах для устройств малого радиуса действия: 433,075…434,79 МГц с мощностью около 20 мВт и 2400…2483,5 МГц с мощностью до 100 мВт, разрешение при этом не требуется. Следить нужно за настройками: HC-12 приезжает с завода со ста милливаттами, а библиотека LoRa по умолчанию ставит пятьдесят.
Читайте также
Обновлено: 25 августа 2026
