Как подключить и использовать NRF24L01 с Arduino
Для проекта нам понадобятся:
- Ардуино UNO (или совместимая плата);
- приёмопередатчик NRF24L01 или аналог;
- макетная плата;
- соединительные провода (вот такие);
- плата с микросхемой FT2232 (опционально);
- персональный компьютер или ноутбук.
1Описание и характеристики приёмопередатчика NRF24L01
NRF24L01 – миниатюрный (4×4 мм) приёмопередатчик на одном чипе. Он очень дешёвый, при этом обеспечивает устойчивую радиосвязь на расстояниях в десятки метров (а при усилении и с хорошей антенной – сотни метров в зоне прямой видимости), и поэтому получил широкое распространение среди радиолюбителей. Основные технические характеристики чипа nRF24L01:
- частота ~2,4 ГГц, 126 радиоканалов;
- программируемая выходная мощность передатчика 0, -6, -12 или -18 дБм;
- 3 скорости передачи: 250 кбит/с, 1 Мб/с и 2 Мб/с;
- автоматическая обработка пакетов;
- частотная модуляция GFSK радиосигнала;
- ультранизкое потребление;
- напряжение питания 1,9…3,6 В;
- порты ввода-вывода толерантны к 5 В;
- совместимость с nRF2401A, nRF2402, nRF24E1 и nRF24E2;
- управление по цифровому 4-проводному интерфейсу SPI, скорость до 10 Мб/с.
NRF24L01 можно приобрести в составе готового модуля. Назначение выводов модуля показано на иллюстрации. На обратной стороне модуля радиоэлементов нет.
Для организации приёма и передачи понадобятся как минимум два подобных модуля с nRF24L01.
Название | Назначение | Примечание |
---|---|---|
GND | Земля | |
VDD | Питание | 1,9…3,6 В. Если сигнал на MOSI/MISO >3,6 В, то питание не более 2,7…3,3 В. |
CE | Цифровой вход | Chip Enable. Активирует режим приёма или передачи. Активный уровень "1" (HIGH). |
CSN | Цифровой вход | SPI Chip Select. Режим выбора устройства SPI. Активный "0" (LOW). |
SCK | Цифровой вход | SPI Clock. Линия синхронизации SPI. |
MOSI | Цифровой вход | Вход данных SPI от контроллера к nRF24L01. Толерантность к 5 В. |
MISO | Цифровой выход | Выход данных SPI от nRF24L01 к контроллеру. Толерантность к 5 В. |
IRQ | Цифровой выход | Пин прерывания. Активный "0" (LOW). |
По традиции, сначала подключим nRF24L01 к Arduino и проверим его работоспособность, используя существующие библиотеки. А затем детально рассмотрим протокол управления и научимся работать с приёмопередатчиком без библиотек.
2Подключение приёмопередатчика nRF24L01к Arduino
Подключим модули к Arduino, как показано на рисунке. Каждый модуль к своему контроллеру.
Модули подключаются одинаково, как можно догадаться. А программы в Ардуино будут разные. Один модуль будет работать в режиме приёмника, а другой – передатчика. Но сначала необходимо загрузить библиотеку для nRF24L01 и установить её обычным способом. Библиотека прилагается также в конце статьи.
Напишем для передатчика простейший скетч, который раз в секунду будет отправлять сообщение и инкрементируемый счётчик. Загрузим в одну из плат Arduino скетч передатчика:
Скетч передатчика nRF24L01 (разворачивается)
#include "SPI.h" // подключаем библиотеку для работы с шиной SPI #include "RF24.h" // подключаем библиотеку для работы с nRF24L01 const int CE = 9; const int CSN = 10; RF24 radio(CE, CSN); // создаём объект для работы с библиотекой RF24, указывая номера выводов nRF24L01 byte tx_data[32] = { 0x48,0x65,0x6C,0x6C,0x6F,0x2C,0x20,0x53, 0x6F,0x6C,0x74,0x61,0x75,0x2E,0x72,0x75, 0x21,0x20,0x52,0x46,0x32,0x34,0x20,0x74, 0x65,0x73,0x74,0x69,0x6E,0x67,0x20,0x20 }; // массив для передачи данных int cnt = 0; // счётчик void setup() { Serial.begin(57600); radio.begin(); // инициализация nRF24L01 radio.setChannel(115); // задаём канал передачи данных (0...127) radio.setDataRate(RF24_250KBPS); // задаём скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS) radio.setPALevel(RF24_PA_MIN); // задаём минимальную мощность усилителя передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm) radio.openWritingPipe(0x0123456789LL); // открываем "трубу" с заданным 40-разрядным адресом для передачи данных Serial.println("Transmitter started"); } void loop() { tx_data[31] = cnt; // последнее число массива - инкрементируемый счётчик if (radio.write(&tx_data, sizeof(tx_data))) { // отправляем по радио массив, и если успешно, Serial.println((String)cnt + " sent"); // то выводим принятые данные в монитор порта if (cnt < 255) { cnt += 1; } else { cnt = 0; } } else { // в случае отсутствия подтверждения приёма со стороны приёмника Serial.println("No ACK"); } delay(1000); }
В другую Ардуинку загрузим скетч приёмника:
Скетч приёмника nRF24L01 (разворачивается)
#include "SPI.h" // подключаем библиотеку для работы с шиной SPI #include "RF24.h" // подключаем библиотеку для работы с nRF24L01 const int CE = 9; const int CSN = 10; RF24 radio(CE, CSN); // создаём объект для работы с библиотекой RF24, указывая номера выводов nRF24L01 byte rx_data[32]; // буфер для приёма данных void setup(){ Serial.begin(57600); radio.begin(); // инициализация nRF24L01 radio.setChannel(115); // задаём канал передачи данных такой же, как у передатчика radio.setDataRate(RF24_250KBPS); // задаём скорость передачи данных как у передатчика radio.setPALevel(RF24_PA_MIN); // задаём минимальную мощность усилителя radio.openReadingPipe(0, 0x0123456789LL); // открываем "трубу" с заданным 40-разрядным адресом как у передатчика radio.startListening(); // включаем приёмник и начинаем прослушивать открытую "трубу" Serial.println("Receiver started"); } void loop() { if (radio.available()) { // если в приёмном буфере имеются принятые данные Serial.println("Data received: "); radio.read(&rx_data, sizeof(rx_data)); // сохраняем данные в массив for (int i=0; i<sizeof(rx_data); i++) { // и выводим в монитор порта Serial.print(rx_data[i], HEX); Serial.print(" "); } Serial.println(); } }
В моём случае макет с подключёнными модулями выглядит так:
Часто пользователи сообщают о проблемах в питании данных модулей nRF24L01. Это проявляется в том, что приёма нет. В таком случае попробуйте припаять на свободное место модуля конденсатор ёмкостью 1…2 пФ.
Запустим монитор последовательного порта для платы Arduino, которая управляет приёмником nRF24L01. В мониторе мы увидим, что 1 раз в секунду нам приходят пакеты, 31 байт в которых не меняется, а последний, 32-ой, байт содержит увеличивающийся счётчик.
Мы убедились, что модули работают, и что мы можем с помощью них передавать и принимать данные по радиоканалу. Теперь залезем под «капот» и разберёмся, как же управлять приёмопередатчиком nRF24L01.
3Режимы работы и управление приёмопередатчиком nRF24L01
Приёмопередатчик может находиться в четырёх состояниях: выключен, ожидание, приём, передача. Чип nRF24L01 имеет встроенную машину состояний, которая обеспечивает корректный переход между этими состояниями. Пользователь управляет состояниями, загружая в управляющие регистры специальные команды.
Режим выключения (power down mode)
В этом режиме чип потребляет минимальный ток, но может принимать команды по SPI от контроллера.
Режим ожидания (standby mode)
Есть два режима ожидания.
Первый режим ожидания (Standby-I) используется для снижения потребления. В этом режиме чип принимает команды по SPI, быстро переходит в режим передачи, и так же быстро возвращается обратно в режим ожидания 1. Для перехода в этот режим нужно подать на CE "HIGH" и в регистре CONFIG установить бит PWR_UP в "1".
Второй режим ожидания (Standby-II) более энергозатратен по сравнению с первым: чип работает полностью, и устройство готово к приёму и передаче практически моментально (около 130 мкс). Как только в передающем буфере оказываются данные, микросхема nRF24L01 начинает передачу. Для перехода в этот режим нужно держать CE в "HIGH" и в регистре CONFIG должен быть установлен бит PWR_UP в "1".
Режим приёма (RX mode)
Это режим, в котором чип nRF24L01 используется как приёмник. При этом он постоянно сканирует эфир на наличие валидных пакетов. Как только валидный пакет будет найден, он помещается в свободный слот приёмного буфера. Если буфер полностью заполнен, то пакет игнорируется.
Для перехода в режим приёма нужно установить биты PWR_UP и PRIM_RX в "1", и вывод CE установить в "HIGH". Режим будет держаться до тех пор, пока контроллер не переключит его в другой (например, режим ожидания или выключения).
Режим передачи (TX mode)
Режим передачи используется для передачи данных.
Для перехода в режим приёма нужно установить бит PWR_UP в "1", бит PRIM_RX в "0", и вывод CE установить в "HIGH". Данные передаются пакетами максимальной длиной по 32 байта. Режим будет держаться до тех пор, пока передаётся пакет. По окончанию передачи пакета чип перейдёт в режим ожидания 2 (standby-II).
Важно не держать nRF24L01 в режиме передачи дольше 4 мс! Чип поддерживает расширенный режим Enhanced ShockBurst, который соблюдает это требование. Кроме того, этот режим обеспечивает автоматическую обработку пакетов.
В таблице ниже сведены все условия для управления режимами чипа.
Режим | Регистр PWR_UP | Регистр PRIM_RX | Вывод CE | Состояние буфера |
---|---|---|---|---|
Передача | 1 | 1 | 1 | Не важно |
Приём | 1 | 0 | 1 | Передача всех данных из передающего буфера. |
Приём | 1 | 0 | 1, импульсом минимум на 10 мкс | Передача 1 пакета данных из передающего буфера. |
Ожидание-2 | 1 | 0 | 1 | Буфер передачи пуст |
Ожидание-1 | 1 | Не важно | 0 | Нет данных для передачи |
Выключен | 0 | Не важно | Не важно | Не важно |
Продолжение следует...
Download attachments:
- Техническое описание (datasheet) nRF24L01 (900 Downloads)
- Библиотека RF24 для Arduino (1442 Downloads)