Подключение модуля nRF24L01+ к Arduino — соединяем две arduino по радиоканалу

nRF24L01 один из самых популярных беспроводных модулей для интернета вещей (IoT). Подключение модуля nRF24L01+ к Arduino позволит организовать многоканальную защищенную связь между Arduino и устройствами на расстоянии. Рассмотрим, как наладить связь между двумя или несколько плат Ардуино по радиоканалу.

Содержание

Установка библиотеки RF24

Работать с nRF24L01+ можно с помощью библиотеки RF24 — довольно популярная и удобная библиотека. Скачиваем, распаковываем и закидываем библиотеку RF24 в папку Arduino/libraries. В случае, если на момент добавления библиотеки, Arduino IDE была открытой, перезагружаем среду.

Библиотеку можно установить из самой среды следующим образом:

  1. В Arduino IDE открываем менеджер библиотек: Скетч->Подключить библиотеку->Управлять библиотеками…Подключение модуля nRF24L01+ к Arduino - Управлять библиотеками...
  2. В строке поиска вводим «RF24», находим библиотеку автора TMRh20, выбираем последнюю версию и кликаем Установить.Подключение модуля nRF24L01+ к Arduino - RF24 Установка
  3. Библиотека установлена (INSTALLED).Подключение модуля nRF24L01+ к Arduino - RF24 INSTALLED

Описание методов библиотеки RF24

begin()

Инициализация работы модуля.

bool RF24::begin(void);

Возвращает
bool — результат инициализации (true / false).

startListening()

Начать прослушивание труб, открытых для приёма данных.

void RF24::startListening(void);

stopListening()

Прекратить прослушивание труб и переключиться в режим передатчика.

void RF24::stopListening(void);

available()

Проверить наличие принятых данных доступных для чтения.

bool RF24::available(void);
bool RF24::available(uint8_t * pipe_num);

Параметры
pipe_num — адрес переменной типа uint8_t в которую требуется поместить номер трубы по которой были приняты данные.
Возвращает
bool — флаг наличия принятых данных (true / false).

isAckPayloadAvailable()

Проверить передатчиком наличие данных в ответе приёмника.

bool RF24::isAckPayloadAvailable(void);

Возвращает
bool — флаг наличия принятых данных от приёмника (true / false).

read()

Прочитать принятые данные.

void RF24::read(void * buf, uint8_t len);

Параметры
buf — адрес массива, строки или переменной в которую требуется поместить принятые данные.
len — количество байт занимаемое массивом, строкой или переменной в которую требуется поместить принятые данные.

write()

Отправить данные по радиоканалу.

bool RF24::write(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
Возвращает
bool — результат доставки данных приёмнику (true / false).

writeAckPayload()

Подготовить данные для ответа передатчику.

void RF24::writeAckPayload(uint8_t pipe, const void * buf, uint8_t len);

Параметры
pipe — Номер трубы передатчика которому требуется ответить данными.
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить вместе с ответом передатчику.
len — Размер отправляемых данных в байтах.

openWritingPipe()

Открыть трубу для передачи данных.

void RF24::openWritingPipe(uint64_t address);

Параметры
address — Адрес трубы, состоит из 5 байт (по умолчанию) и может быть представлен числом типа uint64_t или массивом из 5 однобайтных элементов. Адрес трубы передатчика должен совпадать с одним из адресов труб приёмника.

openReadingPipe()

Открыть трубу для приёма данных.

void RF24::openReadingPipe(uint8_t number, const uint8_t * address);
void RF24::openReadingPipe(uint8_t number, uint64_t address);

Параметры
number — Номер трубы (число от 0 до 5).
address — Адрес трубы, состоит из 5 байт (по умолчанию) и может быть представлен числом типа uint64_t или массивом из 5 однобайтных элементов. Адрес трубы приёмника должен совпадать с адресом трубы передатчика.

closeReadingPipe()

Закрыть трубу открытую ранее для прослушивания (приёма данных).

void RF24::closeReadingPipe(uint8_t pipe):

Параметры
number — Номер трубы (число от 0 до 5), которую более не требуется прослушивать.

setChannel()

Установить радиочастотный канал связи. Номер канала определяет частоту на которой работает модуль. Каждый канал имеет шаг в 1 МГц, а каналу 0 соответствует частота 2,4 ГГц = 2400 МГц, следовательно, каналу 1 соответствует частота 2401 МГц, каналу 2 — частота 2402 МГц и т.д. до канала 125 с частотой 2525 МГц.

void RF24::setChannel(uint8_t channel);

Параметры
channel — Номер канала, указывается числом от 0 до 125.

getChannel()

Получить номер текущего радиочастотного канала связи.

uint8_t RF24::getChannel(void);

Возвращает
Номер канала, число от 0 до 125.

setDataRate()

Установить скорость передачи данных по радиоканалу.

bool RF24::setDataRate(rf24_datarate_e speed);

Параметры
speed — Скорость, задаётся одной из констант: RF24_1MBPS — 1 Мбит/сек, RF24_2MBPS — 2 Мбит/сек и RF24_250KBPS — 250 Кбит/сек (только для модуля NRF24L01+PA+LNA).
Возвращает
Флаг успешной установки новой скорости (true / false).

getDataRate()

Получить текущую скорость передачи данных по радиоканалу.

rf24_datarate_e RF24::getDataRate(void);

Возвращает
значение одной из констант сопоставленной скорости:RF24_1MBPS — 1 Мбит/сек, RF24_2MBPS — 2 Мбит/сек и RF24_250KBPS — 250 Кбит/сек (только для модуля NRF24L01+PA+LNA).

setPALevel()

Установить уровень усиления мощности передатчика.

void RF24::setPALevel(uint8_t level);

Параметры
level — Уровень, задаётся одной из констант:

  • RF24_PA_MIN — минимальный уровень усиления = -18 дБм.
  • RF24_PA_LOW — низкий уровень усиления = -12 дБм.
  • RF24_PA_HIGH — высокий уровень усиления = -6 дБм.
  • RF24_PA_MAX — максимальный уровень усиления = 0 дБм.

getPALevel()

Получить текущий уровень усиления мощности передатчика.

uint8_t RF24::getPALevel(void);

Возвращает
значение одной из констант сопоставленной мощности:RF24_PA_MIN — минимальный уровень усиления = -18 дБм.

  • RF24_PA_LOW — низкий уровень усиления = -12 дБм.
  • RF24_PA_HIGH — высокий уровень усиления = -6 дБм.
  • RF24_PA_MAX — максимальный уровень усиления = 0 дБм.
  • RF24_PA_ERROR — уровень усиления не определён.

setCRCLength()

Установить размер CRC (циклически избыточный код).

void RF24::setCRCLength(rf24_crclength_e length);

Параметры
length — Размер, задаётся одной из констант: RF24_CRC_8 — под CRC отводится 8 бит (CRC-8) или RF24_CRC_16 — под CRC отводится 16 бит (CRC-16).

getCRCLength()

Получить текущий размер CRC (циклически избыточный код).

rf24_crclength_e RF24::getCRCLength(void);

Возвращает
значение одной из констант сопоставленной размеру CRC: RF24_CRC_8 — под CRC отводится 8 бит (CRC-8), RF24_CRC_16 — под CRC отводится 16 бит (CRC-16) или RF24_CRC_DISABLED — передача и проверка CRC отключены.

disableCRC()

Отключить передачу CRC передатчиком и проверку данных приёмником.

void RF24::disableCRC(void);

setPayloadSize()

Установить статичный размер блока данных пользователя в байтах.

void RF24::setPayloadSize(uint8_t size);

Параметры
size — Размер блока данных пользователя в байтах.

getPayloadSize()

Получить текущий статичный размер блока данных пользователя в байтах.

uint8_t RF24::getPayloadSize(void);

Возвращает
текущий статичный размер блока данных от 0 до 32 байт.

getDynamicPayloadSize()

Получить размер блока данных в последнем принятом пакете.

uint8_t RF24::getDynamicPayloadSize(void);

Возвращает
размер данных последнего принятого пакета в байтах.

enableDynamicPayloads()

Разрешить динамически изменяемый размер блока данных для всех труб.

void RF24::enableDynamicPayloads(void);

enableDynamicAck()

Разрешить отказываться от запроса пакетов подтверждения приёма.

void RF24::enableDynamicAck(void);

enableAckPayload()

Разрешить размещать данные пользователя в пакете подтверждения приёма.

void RF24::enableAckPayload(void);

setAutoAck()

Управление автоматической отправкой пакетов подтверждения приёма данных.

void RF24::setAutoAck(bool enable);
void RF24::setAutoAck(uint8_t pipe, bool enable);

Параметры
pipe — номер трубы, для которой разрешается / запрещается автоматическая отправка пакетов подтверждения приема. Указывается только на стороне приёмника. Если номер трубы на стороне приёмника не указан, то действие функции распространяется на все трубы.
enable — Флаг разрешающий автоматическую отправку пакетов подтверждения приёма данных. true — разрешить / false — запретить.

setAddressWidth()

Указать длину адресов труб в байтах.

void RF24::setAddressWidth(uint8_t a_width);

Параметры
a_width — Размер адреса трубы в байтах, представлен числом 3, 4 или 5.

setRetries()

Указать максимальное количество попыток отправки данных и время ожидания.

void RF24::setRetries(uint8_t delay, uint8_t count);

Параметры
delay — целое число от 0 до 15 определяющее время ожидания подтверждения приема.
count — целое число от 1 до 15 определяющее максимальное количество попыток доставить данные передатчику.

powerDown()

Перейти в режим пониженного энергопотребления.

void RF24::powerDown(void);

powerUp()

Выйти из режима пониженного энергопотребления.

void RF24::powerUp(void);

isPVariant()

Проверить аппаратную совместимость модуля с функциями nRF24L01.

bool RF24::isPVariant(void);

Возвращает
(true / false) флаг указывающий на совместимость аппаратного обеспечения модуля с функциями чипа nRF24L01+.

writeFast()

Быстро отправить данные по радиоканалу.

bool RF24::writeFast(const void * buf, uint8_t len);
bool RF24::writeFast(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
Возвращает
результат записи данных в буфер для передачи (true / false).

writeBlocking()

Быстро отправить данные по радиоканалу с указанием таймаута.

bool RF24::writeBlocking(const void * buf, uint8_t len, uint32_t timeout);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
timeout — Максимальное время ожидания освобождения буфера FIFO в миллисекундах.
Возвращает
результат записи данных в буфер для передачи (true / false).

startFastWrite()

Начать быструю отправку данных.

void RF24::startFastWrite(const void * buf, uint8_t len, const bool multicast, bool startTx = 1);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.
startTx — флаг перехода в режим TX или STANDBY-II. Если не указан, значит установлен.

startWrite()

Начать отправку данных.

void RF24::startWrite(const void * buf, uint8_t len, const bool multicast);

Параметры
buf — Данные, адрес массива, строки или переменной, данные которой требуется отправить.
len — Размер отправляемых данных в байтах.
multicast — Флаг групповой передачи, установите в true если требуется отправить данные нескольким приёмникам.

txStandBy()

Подождать пока передаются данные и вернуть результат.

bool RF24::txStandBy(void);
bool RF24::txStandBy(uint32_t timeout, bool startTx = 0);

Параметры
timeout — максимальное время ожидания указывается в миллисекундах.
Возвращает
результат передачи данных из буферов FIFO в радиоканал (true / false).

rxFifoFull()

Проверить не заполнены ли все три буфера FIFO.

bool RF24::rxFifoFull(void);

Возвращает
флаг указывающий на то что все буферы FIFO заполнены.

flush_tx()

Очистка буферов FIFO.

uint8_t RF24::flush_tx(void);

reUseTX()

Повторная отправка данных из буфера FIFO, если они там есть.

void RF24::reUseTX(void);

testCarrier()

Проверка наличия несущей частоты на выбранном канале (частоте).

bool RF24::testCarrier(void);

Возвращает
наличие несущей на выбранном канале за все время его прослушивания.

testRPD()

Проверка наличия любого сигнала выше -64 дБм на выбранном канале (частоте).

bool RF24::testRPD(void);

Возвращает
наличие сигнала мощностью выше -64 дБм на выбранном канале за все время его прослушивания.

isValid()

Проверить используется ли модуль или выполняется отладка кода.

bool RF24::isValid(void);

Возвращает
назначение редактируется (true / false).

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

Подключается nRF24L01+ к Arduino по шине SPI (можно использовать как аппаратную так и программную шину). Выводы модуля Vcc и GND подключаются к шине питания 3.3 В постоянного тока. Выводы модуля MISO, MOSI и SCK подключаются к одноименным выводам шины SPI на плате Arduino. Выводы SS (Slave Select) и CE (Chip Enable) назначаются при объявлении объекта библиотеки RF24 и подключаются к любым назначенным выводам Arduino.

Подключить nRF24L01+ к Arduino можно как напрямую, так и через специальный адаптер.

Подключение nRF24L01+ к Arduino напрямую

Подключение nRF24L01+ к Arduino UNO напрямую

Внимание!

  • Необходимо помнить, что модуль работает от 3.3 В и в нем нет защиты от переполюсовки, если не соблюдать два этих правила, можно сжечь модуль!
  • Для стабильной работы модуля NRF24L01+ необходимо припаять конденсатор на 10 мкФ между VCC и GND.

nRF24L01+ - электролитический конденсатор емкостью 100 мкФ

nRF24L01+ Arduino UNO/Pro Mini Arduino MEGA2560
GND GND GND
VCC 3.3V 3.3V
CE 9 9
CSN 10 53
SCK 13 52
MOSI 11 51
MISO 12 50
IRQ

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

Адаптер nRF24L01+ Arduino UNO/Pro Mini Arduino MEGA2560
GND GND GND
VCC 5.0V 5.0V
CE 9 9
CSN 10 53
SCK 13 52
MO/MOSI 11 51
MI/MISO 12 50
IRQ

Примеры

Обмен данными между двумя платами Arduino UNO и Pro Mini через nRF24L01+

Пример 1: Проверочный скетч

/*
  Подключаем файл настроек из библиотеки RF24.
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку для работы с nRF24L01+.
*/
#include <RF24.h>
#include <printf.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  printf_begin();
  /*
    Инициируем работу модуля nRF24L01+.
  */
  radio.begin();
  if (radio.isPVariant()) {
    /*
      Если модуль поддерживается библиотекой RF24,
      то выводим текст «Модуль nRF24L01 подключен».
    */
    Serial.println("Модуль nRF24L01 подключен");
    /*
      Дамп конфигурации RF для отладки
    */
    radio.printDetails();
  } else {
    /*
      Иначе, если модуль не поддерживается,
      то выводи текст «Неизвестный модуль».
    */
    Serial.println("Неизвестный модуль");
  }
}

void loop() {
}

Результат

Подключение модуля nRF24L01+ к Arduino - Проверочный скетч, Результат

Если после загрузки проверочного скетча увидели, в окне монитора последовательного порта, надпись «Модуль nRF24L01 подключен», значит Ваш модуль поддерживается библиотекой RF24. Если Вы увидели надпись «Неизвестный модуль», проверьте подключение модуля к Arduino. В скетче указано что вывод «CE» (Chip Enable) модуля подключается к выводу 7 Arduino, а вывод SS (Slave Select) модуля подключается к выводу 10 Arduino. При необходимости измените выводы на другие. Если модуль подключён правильно, значит он собран на чипе отличном от nRF24L01.

Пример 2: Передача данных

В функции setup() данного примера модулю задаются основные настройки:

  • по умолчанию модуль работает в качестве передатчика;
  • 0x30 канал;
  • скорость 1 Мбит/сек (RF24_1MBPS);
  • максимальная мощности (RF24_PA_MAX);
  • адрес трубы 0x0123456789LL.

На стороне приёмника нужно указать тот же номер канала, скорость передачи, мощность и адрес трубы.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
   Объявляем массив для хранения и передачи данных
   (до 32 байт включительно).
*/
int dataToBeTransmitted[5] = {'0', '1', '2', '3', '4'};

void setup() {
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);

  /*
     Открываем трубу с адресом 0x0123456789LL для передачи данных
     (передатчик может одновременно вещать только по одной трубе).
  */
  radio.openWritingPipe(0x0123456789LL);
}

void loop() {
  /*
     Отправляем данные из массива dataToBeTransmitted
     указывая весь размер массива в байтах.
  */
  radio.write(&dataToBeTransmitted, sizeof(dataToBeTransmitted));
  /*
     Устанавливаем задержку на 1000 мс.
  */
  delay(1000);
}

Пример 3: Получение данных от одного передатчика

В коде setup() приёмника задаются такие же настройки как и передатчику (канал, скорость, мощность передатчика).

  • 0x30 канал;
  • скорость 1 Мбит/сек (RF24_1MBPS);
  • максимальная мощности (RF24_PA_MAX);
  • адрес трубы 0x0123456789LL, для приёма данных.

Чтобы включить прослушивание труб, нужно вызвать startListening(), метод переводит модуль в режим работы приёмника. Если далее вызвать stopListening(), то модуль перейдёт в режим работы передатчика.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
  Объявляем массив для хранения и передачи данных
  (до 32 байт включительно).
*/
int receivedData[5];

/*
  Объявляем переменную в которую будет сохраняться
  номер трубы по которой приняты данные.
*/
uint8_t pipe;

uint8_t i;

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);
  /*
    Открываем 1 трубу с адресом 1 передатчика 0x0123456789LL, для приема данных.
  */
  radio.openReadingPipe(1, 0x0123456789LL);
  /*
    Включаем приемник, начинаем прослушивать открытые трубы.
  */
  radio.startListening();
}

void loop() {
  /*
    Если в буфере имеются принятые данные, то получаем номер трубы
    по которой эти данные пришли в переменную pipe.
  */
  if (radio.available(&pipe)) {
    /*
      Читаем данные из буфера в массив receivedData указывая
      сколько всего байт может поместиться в массив.
    */
    radio.read(&receivedData, sizeof(receivedData));
    /*
      Если данные пришли от 1 передатчика (по 1 трубе),
      то можно выполнить соответствующее действие ...
    */
    Serial.print("Данные [ ");
    for (i = 0; i < 5; i++) {
      Serial.print((char) receivedData[i]);
      Serial.print(' ');
    }
    Serial.print("] пришли по трубе ");
    Serial.println(pipe);
  }
}

Результат

Подключение модуля nRF24L01+ к Arduino - Приём данных, Результат

Пример 4: Передача данных с проверкой их доставки

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
   Объявляем массив для хранения и передачи данных
   (до 32 байт включительно).
*/
uint8_t dataToBeTransmitted[5] = {'0', '1', '2', '3', '4'};

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);

  /*
     Открываем трубу с адресом 0x0123456789LL для передачи данных
     (передатчик может одновременно вещать только по одной трубе).
  */
  radio.openWritingPipe(0x0123456789LL);
}

void loop() {
  /*
     Отправляем данные из массива dataToBeTransmitted
     указывая весь размер массива в байтах.
  */
  if (radio.write(&dataToBeTransmitted, sizeof(dataToBeTransmitted))) {
    /*
       Данные передатчика были корректно приняты приёмником
    */
    Serial.println("Данные были корректно приняты приёмником");
  } else {
    /*
       Данные передатчика не приняты или дошли с ошибкой CRC
    */
    Serial.println("Данные не приняты или дошли с ошибкой CRC");
  }
  /*
     Устанавливаем задержку на 1000 мс.
  */
  delay(1000);
}

Результат

Подключение модуля nRF24L01+ к Arduino - Передача данных с проверкой, РезультатСкетч данного примера отличается от предыдущего только кодом loop() где функция write() вызывается в условии оператора if(). Дело в том, что функция write() не только отправляет данные, но и возвращает true (если данные были доставлены) или false (если данные не доставлены). По умолчанию передача данных реализована так, что передатчик не только отправляет данные, но и запрашивает у приёмника подтверждение их получения, а приёмник получив данные и проверив CRC, возвращает передатчику пакет подтверждения приема данных. Таким образом на стороне передатчика можно контролировать факт доставки данных приёмнику.

Если не нужно определить факт доставки данных приёмнику, можете заменить write() на writeFast().

/*
   Отправляем данные из массива dataToBeTransmitted 
   указывая сколько байт массива мы хотим отправить.
 */
radio.writeFast(&dataToBeTransmitted, sizeof(dataToBeTransmitted));

writeFast() принимает те же параметры что и write(), но возвращает не флаг доставки данных приёмнику, а флаг записи данных в буфер FIFO. Значит в большинстве случаев функция вернёт true даже до того как приёмник получит данные. Если же все три буфера FIFO заполнены, то функция writeFast() ждёт пока один из них не освободится или пока не истечёт время таймаута но и это ожидание на порядок меньше чем у функции write().

Запретить отправку пакетов подтверждения приёма можно и на стороне приёмников, вызвав у них функцию setAutoAck(false) или setAutoAck(номер_трубы, false). Но в таком случае и на стороне передатчика нужно вызвать функцию setAutoAck(false) иначе приёмник не будет понимать что ему прислал передатчик.

Пример 5: Получение данных от одного или нескольких передатчиков

Приёмнику можно задать до 6 труб функцией openReadingPipe(номер, адрес) с номерами труб от 0 до 5 и адресами труб совпадающими с адресами труб передатчиков.

/*...*/
radio.openReadingPipe(0, 0x0123456789LL);
radio.openReadingPipe(1, 0x0123456799LL);
radio.openReadingPipe(2, 0x012345679ALL);
radio.openReadingPipe(3, 0x01234567AALL);
radio.openReadingPipe(4, 0x01234567ABLL);
radio.openReadingPipe(5, 0x01234567BBLL);
/*...*/

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

Методом available() осуществляется проверка получения данных. Метод возвращает true если в буфере есть принятые данные доступные для чтения. В качестве необязательного аргумента можно указать адрес переменной в которую будет помещён номер трубы по которой были приняты данные (в примере используется адрес переменной &pipe), зная номер трубы мы знаем от какого передатчика пришли данные.

if(radio.available(&pipe)) {
  /*...*/
}

Если приемник будет принимать данные только от одного передатчика, то переменную pipe можно не использовать, а метод available() можно вызвать без параметра, так как в этом случае не требуется узнавать от какого передатчика приняты данные.

/*
  Подключаем файл настроек из библиотеки RF24
*/
#include <nRF24L01.h>
/*
  Подключаем библиотеку  для работы с nRF24L01+
*/
#include <RF24.h>

/*
  Создаём объект radio для работы с библиотекой RF24,
  указывая номера выводов модуля (CE, SS).
*/
RF24 radio(7, 10);

/*
  Объявляем массив для хранения и передачи данных
  (до 32 байт включительно).
*/
uint8_t receivedData[5];

/*
  Объявляем переменную в которую будет сохраняться
  номер трубы по которой приняты данные.
*/
uint8_t pipe;

uint8_t i;

void setup() {
  /*
    Инициируем передачу данных по шине UART в монитор
    последовательного порта на скорости 115200 бит/сек.
  */
  Serial.begin(115200);
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x30);
  /*
    Указываем скорость передачи данных
    RF24_250KBPS = 250Кбит/сек
    RF24_1MBPS = 1Мбит/сек
    RF24_2MBPS = 2Мбит/сек
    Скорость должна быть одинакова на приёмнике и передатчике.
    При самой низкой скорости имеем самую высокую чувствительность и дальность.
  */
  radio.setDataRate(RF24_1MBPS);
  /*
    Указываем мощность передатчика
    RF24_PA_MIN=-18dBm
    RF24_PA_LOW=-12dBm
    RF24_PA_HIGH=-6dBm
    RF24_PA_MAX=0dBm
  */
  radio.setPALevel(RF24_PA_MAX);
  /*
    Открываем 1 трубу с адресом 1 передатчика 0x0123456789LL, для приема данных.
  */
  radio.openReadingPipe(1, 0x0123456789LL);
  /*
    Открываем 2 трубу с адресом 2 передатчика 0x0123456799LL, для приема данных.
  */
  radio.openReadingPipe(2, 0x0123456799LL);
  /*
    Включаем приемник, начинаем прослушивать открытые трубы.
  */
  radio.startListening();
}

void loop() {
  /*
    Если в буфере имеются принятые данные, то получаем номер трубы
    по которой эти данные пришли в переменную pipe.
  */
  if (radio.available(&pipe)) {
    /*
      Читаем данные из буфера в массив receivedData указывая
      сколько всего байт может поместиться в массив.
    */
    radio.read(&receivedData, sizeof(receivedData));
    /*
      Если данные пришли от 1 передатчика (по 1 трубе),
      то можно выполнить соответствующее действие ...
    */
    Serial.print("Данные [ ");
    for (i = 0; i < 5; i++) {
      Serial.print((char) receivedData[i]);
      Serial.print(' ');
    }
    Serial.print("] пришли по трубе ");
    Serial.println(pipe);
  }
}

Результат

Подключение модуля nRF24L01+ к Arduino - Получение данных от одного или нескольких передатчиков, Результат

Материалы

Радио модуль NRF24L01+ / PA+LNA 2.4G (Trema-модуль V2.0)
Урок 26.4 Соединяем две arduino по радиоканалу через nRF24L01+
Optimized High Speed NRF24L01+ Driver Class Documenation

Похожие записи

Комментарии 13

  • Спасибо за описание методов. Только здесь нашел.

  • В примере 4 тип данных для отправки uint8_t, а в примере 3 тип данных для приема int. Несколько неожиданно, когда принимается не совсем то что отправляется. ))

    • Да, нужно отправить/получать используя один тип данных, лучше всего использовать uint8_t, но можно использовать любой тип данных, к примеру вам нужно отправить int или double и не хотите вручную преобразовать из 4-х uint8_t в int.

  • вместо RF24 radio(7, 10); должно быть RF24 radio(9, 10);

  • Вовсе не обязательно. Это зависит от того, к каким выводам Ардуино подведены сигналы ce и csn радиомодуля.

  • Спасибо большое! Реально только здесь нашел информацию. Хотелось бы еще увидеть пример с переключением с приема на передачу и обратно.

  • Thanks on your marvelous posting! I seriously enjoyed reading
    it, you are a great author.I will ensure that I bookmark your blog and will often come back in the future.
    I want to encourage you to continue your great writing, have a nice weekend!

  • Hey there! Do you know if they make any plugins to safeguard against hackers?
    I’m kinda paranoid about losing everything I’ve worked hard on. Any suggestions?

  • I was recommended this blog by my cousin. I am not sure whether this post is written by
    him as nobody else know such detailed about my problem. You are amazing!
    Thanks!

  • Enthält 100 natürliche Öle Entfernt überschüssigen Ohrenschmalz Zur Vorbeugung reduslim Entzündungen Pflegt schützt den Gehörgang.
    Nein, Reduslim in der Apotheke oder bei Online-Apotheken zu kaufen, ist nicht möglich.
    Reduslim wird einmal täglich für einen Monat eingenommen und reduziert das Gewicht von selbst.

    Um Gewicht zu verlieren und einen gesunden Lebensstil zu führen, sind
    eine gesunde Ernährung, regelmäßige Bewegung, ausreichende
    Wasseraufnahme und andere gesunde Gewohnheiten unerlässlich.
    Teilweise verspricht die Werbung Gewichtsabnahmen und eine gertenschlanke Taille, wobei gesunde Ernährung oder eine Umstellung der Ernährung, keine Rolle spielen. Bei genaueren Recherchen konnten wir dafür jedoch keine Nachweise finden und auch vonseiten des Herstellers gibt
    es diesbezüglich keine Aussagen. Auch online
    sind keine Hinweise auf Nebenwirkungen zu finden. Auf diese Weise minimierst Du das Risiko für Nebenwirkungen zusätzlich.
    Laut eigener Aussagen waren auch Nebenwirkungen ausgeblieben.
    Und das Ergebnis nach den ersten sieben Tagen konnte sich sehen lassen — ganze
    3 Kilo waren schon weg!

    Michael war mit dem Ergebnis sehr zufrieden, nicht nur,
    weil er Körpergewicht verloren hatte, sondern weil sein Wohlbefinden verbessert wurde.

    “Reduslim” ist ein Nahrungsergänzungsmittel zur Gewichtsabnahme, das eine effektive Lösung zur Fettverbrennung, zur Förderung eines schnellen Stoffwechsels und zur Unterdrückung des Appetits sein soll!
    Die Ursachen können zahlreich sein und reichen von Schilddrüsenungleichgewichten bis hin zu falschen Diäten, die
    die Eliminierung bestimmter Lebensmittel wie gute Fette,
    Proteine oder Kohlenhydrate beinhalten. Wenn Sie die Einnahme von Reduslim bis zum Ende des
    Kurses, der 30 Tage dauert, fortsetzen, können Sie weitere 5-9 kg abnehmen. Verwenden Sie diese
    Ergänzung nicht, wenn Sie schwanger sind oder stillen. Reduslim ist eine innovative Ergänzung in Kapseln mit einer völlig n-turle Zusammensetzung,
    die helfen kann, Fette zu reduzieren, vor allem in Kombination mit
    einer kalorienarmen Ernährung und moderate körperliche
    Aktivität. Verwenden Sie diese Ergänzung nicht, wenn Sie Nierenprobleme haben. Die verfügbaren Kaufquellen haben wir aber ja bereits des
    Öfteren erwähnt. Wir haben hier die wichtigsten für Sie zusammengestellt.
    They may not coincide with public opinion and do not correspond to reality.The CPA network is not responsible for the content of Website feedback.

    The feedback of users from the website is subjective opinion of their
    authors, which is in no way intended to be objective. 3.5.11 information on the energy
    efficiency of the goods for which the requirement for the availability of such
    information is determined in accordance with the legislation of
    the Russian Federation on energy conservation and
    on improving energy efficiency. 3.15. The Advertiser is obliged to deliver to the
    User the goods, the quality of which corresponds to the Contract and the information provided
    to the User at the conclusion of the Contract, as well as information brought to its attention when transferring the goods (in technical documentation attached to the product, on labels, by marking or
    by other means provided for certain types of the
    goods). 3.18. Payment for the goods by the User
    by transferring funds to the account of a third
    party indicated by the Advertiser does not relieve the Advertiser of the obligation to return the amount paid by
    the User when the goods are returned by the User both of proper and improper quality.
    4.13. When returning goods of inadequate quality, the User’s lack of a document
    confirming the fact and conditions for the purchase of the goods does not deprive him of the
    opportunity to refer to other evidence of the purchase of the goods from
    the Advertiser.

    3.16. If the Advertiser when concluding the Contract was informed
    by the User of the specific purposes for the purchase of the goods, the Advertiser
    is obliged to transfer to the User the goods suitable for use in accordance with these purposes.
    However, in the case of technically complex and
    expensive goods, these requirements of the User are to be
    met if significant deficiencies are discovered. 4.16.

    In case of using the results of the intellectual property of the CPA network; the
    materials of the Website, for any purpose, the User shall obtain the permission of the CPA network before
    placing such materials. 4.16. of this Agreement, the User undertakes to act, in the case of using the results of intellectual property, that
    it belongs to third parties. The User’s lack of
    this document does not deprive him of the opportunity to
    refer to other evidence of the purchase of goods from
    this Advertiser. 4.14. Refusal or evasion of the
    Advertiser from drawing up the waybill or the certificate does
    not deprive the User of the right to demand the return of the goods and (or) return of
    the amount paid by the User in accordance with the
    Contract.

    Also visit my web page :: «http://dba.5thfleet.net/index.php/User:GilbertCarrion1

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *