- Обзор
- Технические характеристики модуля
- Пример использования 1
- Пример использования 2
- Часто задаваемые вопросы FAQ
Обзор Модули nRF24L01
При разработке электронных устройств нередко возникает потребность в передаче каких-либо данных на некоторое расстояние. Например термодатчик, расположенный на улице, должен передавать значение температуры центральному устройству, а датчик движения – отдавать команду на включение сирены, расположенной в отдельном помещении. Подобных задач существует множество, как и методов их решения. В тех случаях, когда организовать проводную связь не представляется возможным, на помощь приходят радиомодули NFR24L01, работающие в диапазоне частот 2.4-2.5 ГГц. Их простота и надёжность обеспечила модулям огромную популярность среди радиолюбительских конструкций. NFR24L01 можно встретить в таких устройствах, как:
- Беспроводная клавиатура, мышь, джойстик;
- Система беспроводного доступа;
- Сетевая система сбора данных;
- Беспроводные охранные системы;
- Домашняя автоматика;
- Всевозможные системы наблюдения и мониторинга;
- Системы автоматики и телемеханики;
- Игрушки на радиоуправлении и многое другое.
В общем, область применения данных радиомодулей ограничивается лишь фантазией разработчика, а их невысокая стоимость является приятным дополнением к прочим достоинствам. На рисунке №1 показан внешний вид радиомодуля NRF24L01 с распиновкой выводов.
Рисунок №1 – внешний вид NRF24L01
Как видно из вышеприведенного рисунка, комплектация платы является базовой и содержит сам чип, штыревую колодку и антенну в виде извилистой дорожки. Такой набор обеспечивает дальность связи до 100м при прямой видимости или до 30м в помещении. Если этого недостаточно, то есть возможность приобрести такие же модули, только с дополнительным усилителем и внешней антенной (рисунок №2). В таком случае дальность связи можно увеличить до 1000м.
Рисунок №2 - NRF24L01 с усилителем и внешней антенной
Организация питания радиомодулей требует повышенного внимания, так как большинство начинающих пользователей сталкивается с проблемами при их запуске. Дело в том, что в момент инициализации NRF24L01 потребляют значительный ток, который не может обеспечить стандартный 3-вольтовый преобразователь Arduino. Как следствие, наблюдаются сбои в работе радиосвязи. Исключить эту неприятную ситуацию поможет электролитический конденсатор, ёмкостью около 100 мкФ. Его необходимо подпаять параллельно выводам GROUND и VCC модуля. Дополнительная ёмкость поможет сгладить пульсации при старте и обеспечит достаточный запас энергии.
Ещё одним вариантом решения проблемы запуска, является использование дополнительного адаптера со встроенным стабилизатором напряжения. В таком случае для NRF24L01 можно использовать внешнее питание от 4.8В до 12В, а максимальный выходной ток составит 800мА. Внешний вид такого адаптера показан на рисунке №3.
Рисунок №3 – Дополнительный адаптер для NRF24L01
И наконец, для тех, кто хочет углубиться в строение самого радиомодуля NRF24L01, на рисунке №4 приведена его электрическая схема.
Рисунок №4 – электрическая схема NRF24L01
Технические характеристики Модули nRF24L01
- Напряжение питания: 1,9В – 3,6В;
- Интерфейс обмена данными: SPI;
- Частота приёма и передачи: 2,4 ГГц;
- Количество каналов: 128 с шагом 1МГц;
- Тип модуляции: GFSK;
- Скорость передачи данных: 250kbps, 1Mbps и 2Mbps;
- Чувствительность приёмника: -82 dBm;
- Расстояние приёма/передачи данных: 100м – прямая видимость; 30м – помещение;
- Коэффициент усиления антенны: 2dBm;
- Диапазон рабочей температуры: -40оС…+85оС;
- Организация сети на одном канале: 7 модулей (1 приёмник и 6 передатчиков).
Купить модули arduino по доступной цене можно в нашем магазине 3DIY!
Подключение nRF24L01 к плате Arduino
Подключение радиомодуля NRF24L01 к Arduino осуществляется по SPI-интерфейсу, что предполагает использование 5 проводов не считая выводов питания. Для разных линеек Arduino номера выводов, на которые завязан аппаратный SPI-интерфейс, могут отличаться. На рисунке №5 показана карта подключения NRF24L01 к различным сериям Arduino.
Рисунок №5 - карта подключения NRF24L01 к различным сериям Arduino.
Выводы CE и CSNмогут быть соединены с любыми цифровыми пинами Arduino. Единственное что потребуется – указать их номера при написании скетча. Что касается программирования, то для взаимодействия с NRF24L01 существует несколько библиотек, но наиболее популярной и стабильной является библиотека RF24.
Как правило, большинство любительских проектов начального уровня предусматривают использование двух модулей NRF24L01, один из которых работает в режиме передатчика, а другой как приёмник на одинаковой частоте. Но что делать, когда на одном канале необходимо контролировать сразу несколько датчиков, например температуру в разных комнатах? В этом случае, функциональные возможности радиомодуля NRF24L01 предусматривают возможность организации мини-сети. А именно, на одной частоте или канале могут работать до 6 передатчиков и 1 приёмник. При этом каждому передатчику присваивается свой уникальный идентификатор («PipeID» или «Идентификатор трубы»), а приёмнику необходимо присвоить все идентификаторы тех передатчиков, от которых он будет принимать данные.
Каждый идентификатор представляет из себя произвольное число, состоящее из 5 байт, но он должен задаваться по определённым правилам, а именно:
На одном и том же канале идентификатор каждого передатчика должен быть обязательно уникальным;
Чтобы приёмник мог принимать данные от передатчиков, ему должны быть указаны их идентификаторы;
Идентификаторы труб Pipe0 и Pipe1 должны отличаться всеми пятью байтами, например Pipe0 = 0x7878787878, а Pipe1 = 0xB4B5B6B7F1;
Идентификаторы труб Pipe2 – Pipe5 должны отличаться от Pipe1 только последним байтом, например: Pipe1 = 0xB4B5B6B7F1; Pipe2 = 0xB4B5B6B7CD; Pipe3 = 0xB4B5B6B7A3; Pipe4 = 0xB4B5B6B70F; Pipe5 = 0xB4B5B6B705;
Рисунок №6 – Приём данных от 6 передатчиков
Для закрепления материала, создадим проект, где 2платы Arduino будут соединены между собой по радиоканалу. К первой Arduino подсоединим потенциометр, а ко второй – светодиод. Путём вращения ручки потенциометра будем регулировать яркость светодиода по радиоканалу. Схема проекта показана на рисунке №7.
Рисунок №7 – соединение 2-х Arduinoпо радиоканалу
Программный код для передатчика:#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include <nRF24L01.h> // Подключаем файл конфигурации из библиотеки RF24 #include <RF24.h> // Подключаем библиотеку для работа для работы с модулем NRF24L01 #define PIN_POT A7 // Номер пина Arduino, к которому подключен потенциометр #define PIN_CE 10 // Номер пина Arduino, к которому подключен вывод CE радиомодуля #define PIN_CSN 9 // Номер пина Arduino, к которому подключен вывод CSN радиомодуля RF24 radio(PIN_CE, PIN_CSN); // Создаём объект radio с указанием выводов CE и CSN int potValue[1]; // Создаём массив для передачи значений потенциометра void setup() { radio.begin(); // Инициализация модуля NRF24L01 radio.setChannel(5); // Обмен данными будет вестись на пятом канале (2,405 ГГц) radio.setDataRate (RF24_1MBPS); // Скорость обмена данными 1 Мбит/сек radio.setPALevel(RF24_PA_HIGH); // Выбираем высокую мощность передатчика (-6dBm) radio.openWritingPipe(0x7878787878LL); // Открываем трубу с уникальным ID } void loop() { potValue[0] = analogRead(PIN_POT); // Считываем показания потенциометра radio.write(potValue, 1); // Отправляем считанные показания по радиоканалу }
Программный код для приёмника:#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include <nRF24L01.h> // Подключаем файл конфигурации из библиотеки RF24 #include <RF24.h> // Подключаем библиотеку для работа для работы с модулем NRF24L01 #define PIN_LED 3 // Номер пина Arduino, к которому подключен светодиод #define PIN_CE 10 // Номер пина Arduino, к которому подключен вывод CE радиомодуля #define PIN_CSN 9 // Номер пина Arduino, к которому подключен вывод CSN радиомодуля RF24 radio(PIN_CE, PIN_CSN); // Создаём объект radio с указанием выводов CE и CSN int potValue[1]; // Создаём массив для приёма значений потенциометра void setup() { pinMode(PIN_LED, OUTPUT); // Настраиваем на выход пин светодиода radio.begin(); // Инициализация модуля NRF24L01 radio.setChannel(5); // Обмен данными будет вестись на пятом канале (2,405 ГГц) radio.setDataRate (RF24_1MBPS); // Скорость обмена данными 1 Мбит/сек radio.setPALevel(RF24_PA_HIGH); // Выбираем высокую мощность передатчика (-6dBm) radio.openReadingPipe (1, 0x7878787878LL); // Открываем трубу ID передатчика radio.startListening(); // Начинаем прослушивать открываемую трубу } void loop() { if(radio.available()){ // Если в буфер приёмника поступили данные radio.read(&potValue, sizeof(potValue)); // Читаем показания потенциометра analogWrite(PIN_LED, map(potValue[0],0,1023,0,255)); // Регулируем яркость диода } }
Как видно из вышеприведенного кода передатчика и приёмника, в обоих случаях задаётся одинаковая мощность и скорость обмена данными. Для этих целей используются предопределённые литерные константы. Рассмотрим значение каждой из них в паре со своей функцией.- Функция setDataRate() устанавливает скорость обмена данными и может принимать следующие значения:
-RF24_250KBPS – скорость 250 кбит/сек;
-RF24_1MBPS – скорость 1Мбит/сек;
-RF24_2MBPS – скорость 2Мбит/сек;
- Функция setPALevel() определяет мощность передатчика и может принимать следующие значения:
-RF24_PA_MIN – мощность -18dBm;
-RF24_PA_LOW – мощность -12dBm;
-RF24_PA_HIGH – мощность -6dBm;
-RF24_PA_MAX – мощность 0dBm;
Пример использования №1
Так как основной областью применения радиомодулей NRF24L01 являются различные системы удалённого мониторинга, создадим небольшой проект, суть которого передавать по радиоканалу температуру и влажность с датчика DHT11. На стороне приёма данная информация будет выводиться на символьный LCD-дисплей 16х2. Схема проекта показана на рисунке №8.
Рисунок №8 – проект удалённого контроля температуры и влажности
Также понадобятся несколько библиотек для работы с датчиком влажности и самим дисплеем по шине I2C. Скачать их можно по приведенным ниже ссылкам:
После установки всех необходимых библиотек, можно переходить непосредственно к программированию. Ниже приведены 2 скетча с комментариями для передатчика и приёмника.
Программный код для передатчика:
#include <iarduino_DHT.h> // Библиотека для работы с датчиком DHT11/DHT22 iarduino_DHT sensor(3); // Датчик подключен к 3 пину Arduino #include <SPI.h>; // Библиотека для работы с шиной SPI #include <nRF24L01.h>; // Файл конфигурации для библиотеки RF24 #include <RF24.h>; // Библиотека для работы с модулем NRF24L01 #define PIN_CE 10 // Номер пина Arduino, к которому подключен вывод CE радиомодуля #define PIN_CSN 9 // Номер пина Arduino, к которому подключен вывод CSN радиомодуля RF24 radio(PIN_CE, PIN_CSN); // Создаём объект radio с указанием выводов CE и CSN int DHT_value[2]; // Массив для передачи данных о температуре и влажности void setup() { Serial.begin(9600); // Инициализация серийного порта для отладки radio.begin(); // Инициализация радиомодуля NRF24L01 radio.setChannel(5); // Обмен данными будет вестись на пятом канале (2,405 ГГц) radio.setDataRate (RF24_1MBPS); // Скорость обмена данными 1 Мбит/сек radio.setPALevel(RF24_PA_HIGH); // Выбираем высокую мощность передатчика (-6dBm) radio.openWritingPipe (0x7878787878LL); // Открываем трубу с уникальным ID delay(2000); // Задержка на инициализацию датчика DHT } void loop() { if(sensor.read() == DHT_OK) { // Если датчик выполнил преобразования DHT_value[0] = sensor.tem; // Запоминаем температуру DHT_value[1] = sensor.hum; // Запоминаем влажность radio.write(DHT_value, sizeof(DHT_value)); // Передаём данные по радиоканалу // Паралельно выводим считанные значения в терминал Serial.print("t="); Serial.print(DHT_value[0]); Serial.println("oC"); Serial.print("h="); Serial.print(DHT_value[1]); Serial.println("%"); } delay(2000); // Задержка на время преобразований датчика DHT }
Программный код для приёмника:#include <SPI.h>; // Библиотека для работы с шиной SPI #include <nRF24L01.h>;; // Файл конфигурации для библиотеки RF24 #include <RF24.h>; // Библиотека для работы с модулем NRF24L01 #define PIN_CE 10 // Номер пина Arduino, к которому подключен вывод CE радиомодуля #define PIN_CSN 9 // Номер пина Arduino, к которому подключен вывод CSN радиомодуля RF24 radio(PIN_CE, PIN_CSN); // Создаём объект radio с указанием выводов CE и CSN #include <Wire.h> // Библиотека для работы с шиной 1-Wire #include <LiquidCrystal_I2C.h> // Библиотека для работы с ЖКИ // Создаём объект lcd для работы с дисплеем // (I2C_ADDR, En_pin, Rw_pin, Rs_pin ,D4_pin, D5_pin, D6_pin, D7_pin) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); int DHT_value[2]; // Массив для передачи данных о температуре и влажности void setup() { lcd.begin(16, 2); // Инициализация ЖКИ lcd.backlight(); // Включаем подсветку radio.begin(); // Инициализация радиомодуля NRF24L01 radio.setChannel(5); // Обмен данными будет вестись на пятом канале (2,405 ГГц) radio.setDataRate (RF24_1MBPS); // Скорость обмена данными 1 Мбит/сек radio.setPALevel(RF24_PA_HIGH); // Выбираем высокую мощность передатчика (-6dBm) radio.openReadingPipe(1, 0x7878787878LL); // Открываем трубу с ID передатчика radio.startListening(); // Включаем прослушивание открытой трубы } void loop() { if(radio.available()){ // Если по рпдиоканалу поступили данные radio.read(&DHT_value, sizeof(DHT_value)); // Чтение данных и запись в массив // Выводим принятые данные на ЖКИ по координатам lcd.setCursor(0, 0); lcd.print("Temperature="); lcd.print(DHT_value[0]); lcd.print("oC"); lcd.setCursor(0, 1); lcd.print("Humidity="); lcd.print(DHT_value[1]); lcd.print("%"); } }
При повторении проекта может возникнуть проблема с выводом информации на экран дисплея. Дело в том, что дополнительные модули, предоставляющие интерфейс I2C могут иметь различные адреса. В моём случае адрес дисплея на шине равен 0x27. Определить адрес вашего дисплея можно специальным скетчем-сканером шины I2C. Найти его на просторах Интернета не составит никакого труда. Результат работы данного проекта на макетной плате показан на рисунке №9.
Рисунок №9 – контроль температуры и влажности по радиоканалу
Пример использования №2
Создадим проект передачи данных с одной плата Arduino на другую по радиоканалу и использованием модулей nRF24L01+.
- Плата Arduino – 2 шт;
- Модуль nRF24L01+ – 2 шт;
- Датчик DHT11 – 1 шт;
- Дисплей WH1602 I2C;
- Провода.
Схема соединений нашего проекта на рис. 10.
Рисунок 10.
Содержимое скетча для платы Arduino c датчиком DHT11 показано в листинге 3.
Листинг 3.
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // Создаём объект RF24 m24l01(7, 8); // Массив для отправки данных byte arr1[4]; // идентификатор канала #define ID 0xF0F0F0F0E2LL // стартовый байт отправки #define SEND_START 55 // стоповый байт отправки #define SEND_STOP 56 #include "DHT.h" // создание DHT DHT snr(6, DHT11); int t; int h; unsigned long millissenddata=0; void setup(){ Serial.begin(9600); m24l01.begin(); m24l01.setPALevel(RF24_PA_HIGH); m24l01.setDataRate(RF24_250KBPS); m24l01.setChannel(0x55); m24l01.openWritingPipe(ID); snr.begin(); } void loop() { // отправка данных if(millis()-millissenddata>10000) { // получение данных с датчика h = snr.readHumidity(); t = snr.readTemperature(); arr1[0] = SEND_START; arr1[1] = h; arr1[2] = t; arr1[3] = SEND_STOP; Serial.println("send"); // отправляем данные m24l01.write(&arr1, sizeof(arr1)); delay(100); millissenddata=millis(); } }
Содержимое скетча для платы Arduino c дисплеем WH1602 I2C показано в листинге 4.
Листинг 4.
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // Создаём объект RF24 m24l01(7, 8); // для получения данных int arr1[4]; // идентификатор канала #define ID 0xF0F0F0F0E2LL #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C dislpl(0x27,16,2); void setup() { Serial.begin(9600); m24l01.begin(); m24l01.setChannel(0x55); m24l01.setDataRate(RF24_250KBPS); m24l01.setPALevel(RF24_PA_HIGH); m24l01.openReadingPipe(1, ID); // режим приема m24l01.startListening (); dislpl.init(); // заголовки на дисплей dislpl.backlight(); dislpl.setCursor(0,0); dislpl.print("H="); dislpl.setCursor(0,1); dislpl.print("T="); } void loop() { if(m24l01.available()) { m24l01.read(&arr1, sizeof(arr1)); // Показания на дисплей dislpl.setCursor(2,0); dislpl.print(arr1[1]); dislpl.setCursor(2,1); dislpl.print(arr1[2]); } }
И результат работы (рис. 11) Рисунок 11.
FAQ. Часто задаваемые вопросы
Ответ: Частотный диапазон, в котором работают данные радиомодули является довольно распространённым. В этой полосе частот работают также wifi-роутеры, Bluetooth-устройства и даже некоторые СВЧ-печи. Весть этот промышленный шум может препятствовать прохождению сигналов на некоторых каналах. При обнаружении подобных проблем рекомендуется просто сменить канал связи на другой.
Вопрос:Как прописать в коде приёмника получение данных с нескольких передатчиков?
void setup() {
// .......
// Первый передатчик имеен идентификатор 0xAABBCCDD11LL
radio.openReadingPipe (1, 0xAABBCCDD11LL);
// Второй передатчик имеен идентификатор 0xAABBCCDD22LL
radio.openReadingPipe (2, 0xAABBCCDD22LL);
radio.startListening();
// .......
}
void loop() {
// Если поступили данные, определяем номер трубы передатчика по ссылке на pipe
if(radio.available(&pipe)) {
radio.read(&data, sizeof(data)); // Считываем данные в массив
if(pipe==1){ // Если данные пришли от 1-го передатчика
// Выполняем какие-либо действия для 1-го передатчика
}
if(pipe==2){ // Если данные пришли от 2-го передатчика
// Выполняем какие-либо действия для 2-го передатчика
}
}
}
Ответ: Преобразователь уровней не требуется, так как информационные входы радиомодуля NRF24L01 толерантны к напряжению 5В.
Вопрос: Какое количество байт можно отправить в буфер передатчика за один раз?
Ответ: За один сеанс можно отправить в буфер 32 байта.