Найти тему
Радиотехника

Радио модули NRF24L01 (ARDUINO)

Радио модули NFR24L01 работают в диапазоне частот 2.4-2.5 ГГц, поддерживают передачу данных до 2 Мбит/с и могут работать на 125 каналах. Радио модули выпускаются малой мощности (до 100 метров или около 30 метров в помещении) и с усилителем к которому можно подключить внешнюю антенну (до 1000 м).

Один модуль способен поддерживать связь сразу с шестью приемниками или передатчиками, то есть можно объединить сразу семь устройств в общую радиосеть на частоте 2,4 ГГц. Скорость беспроводного соединения можно настраивать: 250kbps, 1Mbps или 2Mbps, а так же можно изменять мощность в пережиме передатчика от -18dBm до 0dBm.

Основные параметры радио модуля NRF24L01

  • Напряжение питания от 1.9 В до 3.6 В
  • Потребляемый ток при мощности 0dBm 11.3 мА
  • Потребляемый ток при передачи 2 Мбит 13.5 мА
  • Частота 2,4 – 2,525 ГГц
  • Скорость передачи: 250 Кбит, 1 Мбит или 2Mбит
  • Программируемая выходная мощность: 0, -6, -12 и -18 dBm

Схема подключения

-2

При передачи сигнала радио модуль NRF24L01 кратковременно может потреблять большой ток, поэтому рекомендуется по питанию установить электролитический конденсатор емкость от 10 до 220 мкФ.

В статье будет рассмотрено несколько простых примеров использования радио модулей, возможности радио модулей NRF24L01 достаточно большие и они могут применяться в различных системах беспроводной связи, беспроводного контроля доступа, в охранных системах, домашней автоматике и тд.

Перед загрузкой скетчей Вам понадобятся следующие библиотеки:

Тестовый скетч

В этом примере один радио модуль работает в качестве передатчика, а другой в качестве приемника. Передатчик передает два числа, а приемник принимает сигнал и выводит в монитор порта эти числа.

ПЕРЕДАТЧИК

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

int data[2];

void setup(){

radio.begin();

radio.setChannel(5); // канал от 0 до 125

radio.setDataRate (RF24_1MBPS); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

radio.setPALevel (RF24_PA_HIGH); // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm

radio.openWritingPipe (0xA0A0A0A001);

}

void loop(){

data[0] = 1234;

data[1] = 5678;

radio.write(&data, sizeof(data));

delay(1000);

}

ПРИЕМНИК

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

int data[2];

void setup(){

delay(1000);

Serial.begin(9600);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

radio.setDataRate (RF24_1MBPS); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

radio.setPALevel (RF24_PA_HIGH); // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm

radio.openReadingPipe (1, 0xA0A0A0A001);

radio.startListening ();

// radio.stopListening ();

}

void loop(){

if(radio.available()){

radio.read(&data, sizeof(data));

Serial.println(data[0]);

Serial.println(data[1]);

}

}

-3

Управление 4-я реле

В этом примере можно управлять включением и выключением 4-х реле или других исполнительных уст-в. В передатчике используются 4 кнопки, при нажатии на кнопку в приемнике меняет логическое состояние один их выходов к которому можно подключить модуль реле.

-4

ПЕРЕДАТЧИК

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

int data_reg;

bool w1,w2,w3,w4;

void setup(){

delay(1000);

Serial.begin(9600);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

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(0xA1A1A1A102);

pinMode(2,INPUT_PULLUP);

pinMode(3,INPUT_PULLUP);

pinMode(4,INPUT_PULLUP);

pinMode(5,INPUT_PULLUP);

}

void loop(){

if(digitalRead(2)==LOW && w1==0){w1=1;data_reg |= (1<<0);delay(200);}

if(digitalRead(2)==LOW && w1==1){w1=0;data_reg &=~(1<<0);delay(200);}

if(digitalRead(3)==LOW && w2==0){w2=1;data_reg |= (1<<1);delay(200);}

if(digitalRead(3)==LOW && w2==1){w2=0;data_reg &=~(1<<1);delay(200);}

if(digitalRead(4)==LOW && w3==0){w3=1;data_reg |= (1<<2);delay(200);}

if(digitalRead(4)==LOW && w3==1){w3=0;data_reg &=~(1<<2);delay(200);}

if(digitalRead(5)==LOW && w4==0){w4=1;data_reg |= (1<<3);delay(200);}

if(digitalRead(5)==LOW && w4==1){w4=0;data_reg &=~(1<<3);delay(200);}

radio.write(&data_reg, sizeof(data_reg));

Serial.println(data_reg);

delay(100);

}

ПРИЕМНИК

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

int data_old,data;

unsigned long times;

void setup(){

delay(1000);

Serial.begin(9600);

pinMode(2,OUTPUT);pinMode(3,OUTPUT);pinMode(4,OUTPUT);pinMode(5,OUTPUT);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

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.openReadingPipe(1, 0xA1A1A1A102);

radio.startListening();

}

void loop(){

if(radio.available()){

radio.read(&data, sizeof(data));

Serial.println(data);

if(((data >> 0) & 1) ==1){digitalWrite(2,HIGH);}else{digitalWrite(2,LOW);}

if(((data >> 1) & 1) ==1){digitalWrite(3,HIGH);}else{digitalWrite(3,LOW);}

if(((data >> 2) & 1) ==1){digitalWrite(4,HIGH);}else{digitalWrite(4,LOW);}

if(((data >> 3) & 1) ==1){digitalWrite(5,HIGH);}else{digitalWrite(5,LOW);}

}

}

Электронный термометр DS18B20

В следующем примере к передатчику подключен цифровой датчик температуры DS18B20, передатчик передает температуру, а приемник выводит ее на дисплей LCD1602_I2C. В момент получения информации на экран выводится символ «*».

-5
-6
-7

ПЕРЕДАТЧИК

#include <SPI.h>

#include <nRF24L01.h>

#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

OneWire ds(2); // Вход датчика 18b20

int data_t;

void setup(){

radio.begin();

radio.setChannel(5); // канал от 0 до 125

radio.setDataRate (RF24_1MBPS); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

radio.setPALevel (RF24_PA_HIGH); // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm

radio.openWritingPipe (0xA0A0A0A001);

}

void loop(){

data_t = dsRead(0)*100;

radio.write(&data_t, sizeof(data_t));

delay(1000);

}

float dsRead(byte x) {

byte data[2], addr[8][8], kol = 0;

while (ds.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков

kol++;

}

ds.reset_search(); // Сброс поиска датчика

ds.reset(); // Инициализация, выполняется сброс шины

ds.select(addr[x]); // Обращение к датчику по адресу

ds.write(0x44, 0); // Измерение температуры с переносом данных в память

ds.reset(); // Инициализация, выполняется сброс шины

ds.select(addr[x]); // Обращение к датчику по адресу

ds.write(0xBE); // Обращение памяти

data[0] = ds.read();// Чтение памяти byte low

data[1] = ds.read();// Чтение памяти byte high

float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод

}

ПРИЕМНИК

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <Wire.h>

RF24 radio(9, 10); // (CE, CSN)

LiquidCrystal_I2C lcd(0x27,16,2);

int data;

byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};

byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};

byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};

byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};

byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};

byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};

byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};

byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};

byte d1,d2,d3,d4,d5,d6,e1,e2,e3,a[6],x;

void setup(){

delay(1000);

Serial.begin(9600);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

radio.setDataRate (RF24_1MBPS); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

radio.setPALevel (RF24_PA_HIGH); // RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm

radio.openReadingPipe (1, 0xA0A0A0A001);

radio.startListening ();

// radio.stopListening ();

Wire.begin();lcd.init();lcd.backlight();

lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);

lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);

}

void loop(){

if(radio.available()){

radio.read(&data, sizeof(data));

Serial.println((float)data/100);

a[0]=data/1000;

a[1]=data/100%10;

a[2]=data/10%10;

a[3]=data%10;

if(data<1000){a[0]=10;}

if(data<100){a[1]=10;}

for(x=0;x<4;x++){

switch(x){

case 0: e1=0;e2=1,e3=2;break;

case 1: e1=3,e2=4,e3=5;break;

case 2: e1=7,e2=8,e3=9;break;

case 3: e1=10,e2=11,e3=12;break;

}digit();}

lcd.setCursor(6,1);lcd.print(".");

lcd.setCursor(14,1);lcd.write((uint8_t)223);;lcd.print("C");

lcd.setCursor(15,0);lcd.print("*");

delay(200);

}

else{lcd.setCursor(15,0);lcd.print(" ");}

}

void digit(){

switch(a[x]){

case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;

case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;

case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;

case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;

case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;

case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;

case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;

case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;

case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;

case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;

case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break;

}

lcd.setCursor(e1,0);lcd.write((uint8_t)d1);

lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);lcd.setCursor(e1,1);

lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}

Терморегулятор

-8

Во всех выше показанных примерах радио модули разделены на приемники и передатчики, в это примере каждый радио модуль работает как приемопередатчик.

Базовый модуль терморегулятора содержит дисплей LCD1602 с модулем I2C и энкодер для установки температуры регулирования. Модуль датчика и управления нагревательным элементом измеряет температуру и каждые 2 секунды передает ее значение в базовый модуль, базовый модуль получает значение температуры и выводит ее на дисплей, при помощи энкодера в базовом модуле можно изменить температуру регулирования, температура регулирования каждые 2 секунды передается в модуль датчика. Оба модуля основное время работают как приемники и раз в 2 секунды переходят в режим передатчика передавая необходимую информацию. Модуль датчика в зависимости от текущей температуры и температуры регулирования управляет цифровым выходом D3 к который может управлять нагревательным элементом.

-9
  1. Температура регулирования
  2. Индикатор получения информации (в момент приема выводится символ *)

БАЗА

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <Wire.h>

#include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <EEPROM.h>

#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
RF24 radio(9, 10); // (CE, CSN)

LiquidCrystal_I2C lcd(0x27,16,2);

Encoder myEnc(A2, A1);// DT, CLK

int data,data_reg;

unsigned long times,times_eeprom,oldPosition = -999,newPosition;

bool w;

byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};

byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};

byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};

byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};

byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};

byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};

byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};

byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};

byte d1,d2,d3,d4,d5,d6,e1,e2,e3,a[6],x;

void setup(){

delay(1000);

Serial.begin(9600);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

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.openReadingPipe(1, 0xA0A0A0A001);

radio.openWritingPipe(0xA1A1A1A102);

radio.startListening ();

Wire.begin();lcd.init();lcd.backlight();

lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);

lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);

MsTimer2::set(3, to_Timer);MsTimer2::start();

if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении

data_reg = EEPROM.read(0);

}

void loop(){

if(radio.available() && w==0){

radio.read(&data, sizeof(data));

Serial.println((float)data/100);

a[0]=data/1000;

a[1]=data/100%10;

a[2]=data/10%10;

a[3]=data%10;

if(data<1000){a[0]=10;}

if(data<100){a[1]=10;}

for(x=0;x<4;x++){

switch(x){

case 0: e1=0;e2=1,e3=2;break;

case 1: e1=3,e2=4,e3=5;break;

case 2: e1=7,e2=8,e3=9;break;

case 3: e1=10,e2=11,e3=12;break;

}digit();}

lcd.setCursor(6,1);lcd.print(".");

lcd.setCursor(13,1);lcd.write((uint8_t)223);;lcd.print("C");

lcd.setCursor(15,1);lcd.print("*");

delay(200);

}

else{lcd.setCursor(15,1);lcd.print(" "); }

if (newPosition != oldPosition){oldPosition = newPosition;data_reg=data_reg+newPosition;myEnc.write(0);newPosition=0;times_eeprom=millis();w=1;

if(data_reg>9){lcd.setCursor(14,0);}else{lcd.setCursor(15,0);}lcd.print(data_reg);}

if(millis()-times>2000 && w==0){times=millis();

radio.stopListening();

radio.write(&data_reg, sizeof(data_reg));

radio.startListening();

}

if(millis()-times_eeprom>5000 && w==1){EEPROM.update(0,data_reg);w=0;}

}

void to_Timer(){newPosition = myEnc.read()/4;}

void digit(){

switch(a[x]){

case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;

case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;

case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;

case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;

case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;

case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;

case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;

case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;

case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;

case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;

case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break;

}

lcd.setCursor(e1,0);lcd.write((uint8_t)d1);

lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);lcd.setCursor(e1,1);

lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}

ДАТЧИК

#include <SPI.h>

#include <nRF24L01.h>

#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <RF24.h>

RF24 radio(9, 10); // (CE, CSN)

OneWire ds(2); // Вход датчика 18b20

int data_t,data;

unsigned long times;

int gis = 50;// 0.5 гр.Цельсия

void setup(){

delay(1000);

Serial.begin(9600);

pinMode(3,OUTPUT);

radio.begin();

radio.setChannel(5); // канал от 0 до 125

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.openReadingPipe(1, 0xA1A1A1A102);

radio.openWritingPipe(0xA0A0A0A001);

radio.startListening();

}

void loop(){

if(radio.available()){

radio.read(&data, sizeof(data));

Serial.println(data);

}

if(millis()-times>2000){times=millis();

data_t = dsRead(0)*100;

radio.stopListening();

radio.write(&data_t, sizeof(data_t));

radio.startListening();

}

if(data*100 >= data_t + gis){digitalWrite(3,HIGH);}

if(data*100 <= data_t - gis){digitalWrite(3,LOW);}

}

float dsRead(byte x) {

byte data[2], addr[8][8], kol = 0;

while (ds.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков

kol++;

}

ds.reset_search(); // Сброс поиска датчика

ds.reset(); // Инициализация, выполняется сброс шины

ds.select(addr[x]); // Обращение к датчику по адресу

ds.write(0x44, 0); // Измерение температуры с переносом данных в память

ds.reset(); // Инициализация, выполняется сброс шины

ds.select(addr[x]); // Обращение к датчику по адресу

ds.write(0xBE); // Обращение памяти

data[0] = ds.read();// Чтение памяти byte low

data[1] = ds.read();// Чтение памяти byte high

float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод

}

Радио модули NRF24L01 (ARDUINO) — rcl-radio.ru