NRF24L01

158 руб.

10 в наличии

Артикул: 66 Категория:

Описание

Обзор Модули 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 передатчиков).

Подключение nRF24L01 к плате Arduino

Подключение радиомодуля NRF24L01 к Arduino осуществляется по SPI-интерфейсу, что предполагает использование 5 проводов не считая выводов питания. Для разных линеек Arduino номера выводов, на которые завязан аппаратный  SPI-интерфейс, могут отличаться. На рисунке №5 показана карта подключения NRF24L01 к различным сериям Arduino.

 

Рисунок №5 – карта подключения NRF24L01 к различным сериям Arduino.

 

Выводы CE  и CSN могут быть соединены с любыми цифровыми пинами Arduino. Единственное что потребуется – указать их номера при написании скетча. Что касается программирования, то для взаимодействия с NRF24L01 существует несколько библиотек, но наиболее популярной и стабильной является библиотека RF24.

Как правило, большинство любительских проектов начального уровня предусматривают использование двух модулей NRF24L01, один из которых работает в режиме передатчика, а другой как приёмник на одинаковой частоте. Но что делать, когда на одном канале необходимо контролировать сразу несколько датчиков, например температуру в разных комнатах? В этом случае, функциональные возможности радиомодуля NRF24L01 предусматривают возможность организации мини-сети. А именно, на одной частоте или канале могут работать до 6 передатчиков и 1 приёмник. При этом каждому передатчику присваивается свой уникальный идентификатор («Pipe ID» или «Идентификатор трубы»), а приёмнику необходимо присвоить все идентификаторы тех передатчиков, от которых он будет принимать данные.

Каждый идентификатор представляет из себя произвольное число, состоящее из 5 байт, но он должен задаваться по определённым правилам, а именно:

  • На одном и том же канале идентификатор каждого передатчика должен быть обязательно уникальным;
  • Чтобы приёмник мог принимать данные от передатчиков, ему должны быть указаны их идентификаторы;
  • Идентификаторы труб Pipe0 и Pipe1 должны отличаться всеми пятью байтами, например Pipe0 = 0x7878787878, а Pipe1 = 0xB4B5B6B7F1;
  • Идентификаторы труб Pipe2 – Pipe5 должны отличаться от Pipe1 только последним байтом, например: Pipe1 = 0xB4B5B6B7F1; Pipe2 = 0xB4B5B6B7CD; Pipe3 = 0xB4B5B6B7A3; Pipe4 = 0xB4B5B6B70F; Pipe5 = 0xB4B5B6B705;

Рисунок №6 наглядно демонстрирует вышеизложенное.

Рисунок №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 – проект удалённого контроля температуры и влажности

Arduino1 будет один раз в 2 секунды считывать показания датчика DHT11 и отправлять данные по радиоканалу на Arduino2, которая выведет их на дисплей. В данном проекте использован символьный ЖКИ-дисплей с конвертером I2C, что позволяет использовать всего 2 провода для его подключения. Также понадобятся несколько библиотек для работы с датчиком влажности и самим дисплеем по шине 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.

Каждые 10 секунд получаем показания влажности воздуха и температуры на плате Arduino с датчика DHT11 и передаем по радиоканалу на другую плату Arduino для отображения на дисплее. Выбираем мощность передатчика, скорость передачи, канал 0x55:

Содержимое скетча для платы 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-устройства и даже некоторые СВЧ-печи. Весть этот промышленный шум может препятствовать прохождению сигналов на некоторых каналах. При обнаружении подобных проблем рекомендуется просто сменить канал связи на другой.

 

   Вопрос: Как прописать в коде приёмника получение данных с нескольких передатчиков?

   Ответ: Для этого необходимо указать уникальный ID каждого передатчика, который будет вещать на частоте приёмника, например.

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-го передатчика
}
}
}