Подключение модуля nRF24L01+ к Raspberry Pi, Orange Pi, Banana Pi …

nRF24L01 один из самых популярных беспроводных модулей для интернета вещей (IoT). Подключив модуль nRF24L01+ к Raspberry Pi, Orange Pi, Banana Pi и т.п можно организовать многоканальную защищенную связь между мини-компьютерами и/или, например, Arduino. Таким образом можно подключить на каждую плату Arduino по датчику и передать полученые данные на, к примеру, Raspberry Pi, а там обрабатывать эти данные и/или загрузить в БД.

Рассмотрим, как установить библиотеку RF24 и как наладить связь между Orange Pi PC (плату можно менять на любую другую типа Raspberry Pi, Orange Pi, Banana Pi и т.п. — будет также работать) и несколько плат Ардуино по радиоканалу.

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

Библиотека RF24 универсальная, её можно установить и использовать как на Arduino, так и на устройства под ОС Linux (Raspberry Pi, Orange Pi, Banana Pi и т.п) поддерживающие SPIDEV, MRAA, RPi BCM2835 или LittleWire. Опция SPIDEV должна работать с большинством систем Linux, поддерживающих SPI.

Описание методов класса RF24 можете найти на странице Подключение модуля nRF24L01+ к Arduino.

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

  1. Установите необходимые компоненты, если они есть (библиотеки MRAA, LittleWire, SPI и т. д.). На Raspberry Pi используется нативная библиотека BCM2835, по этому нужно её установить. Также не забудьте включить SPI на Raspberry Pi, это можно сделать с помощью утилиты raspi-config;
  2. Загрузите файл install.sh с http://tmrh20.github.io/RF24Installer/RPi/install.sh;
    wget http://tmrh20.github.io/RF24Installer/RPi/install.sh
  3. Сделайте это файл исполняемым
    chmod +x install.sh
  4. Запустите его и выберите параметры
    ./install.sh
  5. Запустите пример из одной из библиотек
    cd rf24libs/RF24/examples_linux
  6. Для проверки можете отредактировать пример gettingstarted, чтобы настроить конфигурацию выводов, и запустить его
    nano gettingstarted.cpp
    make  
    sudo ./gettingstarted

Установка библиотеки RF24 на Orange Pi, Banana Pi и др.

Этот метод подойдёт и для установки на Raspberry Pi, и на любой ОС Linux, что поддерживает SPI.

  1. Установите необходимые компоненты, если они есть (библиотеки MRAA, LittleWire, SPI и т. д.). Не забудьте включить SPI, это можно сделать с помощью утилиты armbian-config, более подробно о том, как настроить SPI на Orange Pi, можете найти на странице Включение и настройка SPI (SPI0 и SPI1) на Orange Pi на ядрах 3.4 (Ubuntu 16.04) и 4.14 (Ubuntu 18.04).
  2. Клонируете репозиторий RF24.
    git clone https://github.com/tmrh20/RF24.git RF24
  3. Перейдите в новый каталог RF24.
    cd RF24
  4. Настройте среду сборки, используя скрипт
    ./configure

    Скрипт автоматически определяет устройство и среду сборки. Если хотите вручную настроить, смотрите на список возможностей скрипта:

    ./configure --help
  5. Соберите и установите библиотеку
    sudo make install
  6. Для проверки можете отредактировать пример gettingstarted, чтобы настроить конфигурацию выводов, и запустить его
    nano gettingstarted.cpp
    make  
    sudo ./gettingstarted

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

Подключается nRF24L01+ к Raspberry Pi по шине SPI (можно использовать как аппаратную так и программную шину). Выводы модуля Vcc и GND подключаются к шине питания 3.3 В постоянного тока. Выводы модуля MISO, MOSI, SCK и подключаются к одноименным выводам шины SPI на плате Raspberry Pi.

Вывод CSN (Chip Select nRF24L01+) подключается к выводу CE (Raspberry Pi) шины SPI, CE (Chip Enable) назначается при объявлении объекта библиотеки RF24 и подключаются к любым назначенным выводам Raspberry Pi. Вывод IRQ на NRF24L01+ в данном случае не используется.

Конкретные имена портов интерфейса SPI могут различаться в зависимости от производителя аппаратных средств, при этом возможны следующие варианты:

  • MOSI: SIMO, SDI (на устройстве), DO, DON, SI, MRSR;
  • MISO: SOMI, SDO (на устройстве), DI, DIN, SO, MTST;
  • SCLK: SCK, CLK;
  • SS: nCS, CS, CSB, CSN, nSS, STE, SYNC.

Полное представление о выводах Raspberry Pi см. http://pinout.xyz/. Если установлена библиотека WiringPi, можете воспользоваться командой

gpio readall

для определения назначения всех выводов на плате.
Схема подключения nRF24L01+ к Raspberry Pi - Raspberry Pi gpio readall

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

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

nRF24L01+ Raspberry Pi
GND 6 / GND
VCC 1 / 3.3V
CE 22 / GPIO25
CSN 24 / GPIO8 / SPI_CE0_N
SCK 23 / GPIO11 / SPI0_CLK
MOSI 19 / GPIO10 / SPI0_MOSI
MISO 21 / GPIO9 / SPI0_MISO
IRQ

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

nRF24L01+ Raspberry Pi
GND 6 / GND
VCC 2 / 5.0V
CE 22 / GPIO25
CSN 24 / GPIO8 / SPI_CE0_N
SCK 23 / GPIO11 / SPI0_CLK
MO / MOSI 19 / GPIO10 / SPI0_MOSI
MI / MISO 21 / GPIO9 / SPI0_MISO
IRQ

Схема подключения nRF24L01+ к Orange Pi, Banana Pi и др.

Как и в случае с Raspberry Pi, подключается nRF24L01+ к Orange Pi по шине SPI. Выводы модуля Vcc и GND подключаются к 3.3 В и GND соответственно. Тоже самое и с выводами MISO, MOSI, SCK и CSN. Единственное отличие в подключении вывода CE (Chip Enable) номер вывода отличается от Raspberry Pi, так как контроллер другой. Если установлена библиотека WiringOP или BPI-WiringPI (для Banana Pi), можете воспользоваться командой

gpio readall

для определения назначения всех выводов на плате Orange Pi или Banana Pi.
Схема подключения nRF24L01+ к Orange Pi - Orange Pi gpio readall

При объявлении объекта библиотеки RF24 нужно указывать номер пина из колонки BCM.

Схема подключения nRF24L01+ к Orange Pi, Banana Pi и др.

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

nRF24L01+ Orange Pi
GND 6 / GND
VCC 1 / 3.3V
CE 29 / GPIO7
CSN 24 / GPIO67 / SPI_CE0_N
SCK 23 / GPIO66 / SPI0_CLK
MOSI 19 / GPIO64 / SPI0_MOSI
MISO 21 / GPIO65 / SPI0_MISO
IRQ

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

nRF24L01+ Orange Pi
GND 6 / GND
VCC 2 / 5.0V
CE 29 / GPIO7
CSN 24 / GPIO67 / SPI_CE0_N
SCK 23 / GPIO66 / SPI0_CLK
MO / MOSI 19 / GPIO64 / SPI0_MOSI
MI / MISO 21 / GPIO65 / SPI0_MISO
IRQ

Примеры

Пример 1: Сканер диапазона 2.4 ГГц на NRF24L01+

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

Ниже приведённый пример представляет собой сканер, с помощью которого можно определить свободные каналы в ISM (Industrial, Scientific, Medical) диапазоне частот от 2400 МГц до 2527 МГц. Данный сканер сможет определять такие устройства как: WiFi, Bluetooth, некоторые радио телефоны, другие модули nRF24L01.

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

using namespace std;

/*
 * Конфигурация оборудования
 */
#define BCM_PIN 7
#define SPI_DEV 0
#define NUM_CHANNELS 126

/*
 * Информация о канале
 */
uint8_t values[NUM_CHANNELS];
const int numReps = 100;

int main() {
  /*
   * Создаём объект radio для работы с библиотекой RF24,
   * указывая номера вывода CE и SPI порта
   */
  RF24 radio(BCM_PIN, SPI_DEV);

  /*
   * Инициируем работу nRF24L01+
   */
  radio.begin();

  radio.setAutoAck(false);

  /*
   * Вход в режиме ожидания
   */
  radio.startListening();
  radio.stopListening();

  /*
   * Дамп конфигурации RF для отладки
   */
  radio.printDetails();

  /*
   * Распечатка заголовка, верхний и нижний разряд
   */
  for (int i = 0; i < NUM_CHANNELS; ++i) {
    printf("%x", i >> 4);
  }
  cout << endl;
  for (int i = 0; i < NUM_CHANNELS; ++i) {
    printf("%x", i & 0xf);
  }
  cout << endl;

  while (1) {
    /*
     * Очистка значений измерений
     */
    memset(values, 0, sizeof(values));

    /*
     * Сканирование всех каналов numReps раз
     */
    for (int k = 0; k < numReps; ++k) {
      for (int i = 0; i < NUM_CHANNELS; ++i) {

        /*
         * Выбор канала
         */
        radio.setChannel(i);

        /*
         * Послушать немного
         */
        radio.startListening();
        delayMicroseconds(128);
        radio.stopListening();

        /*
         * Проверка наличия несущей частоты на выбранном канале (частоте).
         */
        if (radio.testCarrier()) {
          ++values[i];
        }
      }
    }
    /*
     * Распечатка измерения канала в одну шестнадцатеричную цифру
     */
    for (int i = 0; i < NUM_CHANNELS; ++i) {
      printf("%x", min(0xf, (values[i] & 0xf)));
    }
    cout << endl;
  }
  return 0;
}

Компиляция и сборка

g++ -Ofast -Wall RF24_scanner.cpp -lrf24 -o RF24_scanner

Результат

Сканер диапазона 2.4 ГГц на NRF24L01 - Результат (RF24_scanner)
По полученным результатам мы можем сказать, что довольно много каналов заняты.

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

В основном на Raspberry Pi, Orange Pi, Banana Pi и т.п. можно запустить любой рабочий пример для Arduino со страницы Подключение модуля nRF24L01+ к Arduino. Единственое, нужно будет поменять функции для вывода на консоль: Serial.print(); на аналогичные в C/C++: printf(); или cout;.

Приёмнику можно задать до 6 труб функцией openReadingPipe(номер, адрес):

for (int i = 0; i < 6; i++) {
  radio.openReadingPipe(i, pipesAddress[i]);
}

с номерами труб от 0 до 5 и адресами труб совпадающими с адресами труб передатчиков.

/*
 * номера труб
 */
uint8_t pipesAddress[6][5] = {
{ '0', 'P', 'I', 'P', 'E' },
{ '1', 'P', 'I', 'P', 'E' },
{ '2', 'P', 'I', 'P', 'E' },
{ '3', 'P', 'I', 'P', 'E' },
{ '4', 'P', 'I', 'P', 'E' },
{ '5', 'P', 'I', 'P', 'E' },
};

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

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

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

radio.enableDynamicPayloads();

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

payloadSize = radio.getDynamicPayloadSize();

Читаем данные в массив receivedData и указываем сколько байт читать payloadSize.

radio.read(&receivedData, payloadSize);

Полный код приёмника:

/*
 * Приемник
 */

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

using namespace std;

#define BCM_PIN 7
#define SPI_DEV 0
#define MAX_LEN 32

/*
 * Создаём массив для приёма данных
 */
uint8_t receivedData[MAX_LEN];
uint8_t pipeNumber;
uint8_t payloadSize;

/*
 * номера труб
 */
uint8_t pipesAddress[6][5] = {

{ '0', 'P', 'I', 'P', 'E' },

{ '1', 'P', 'I', 'P', 'E' },

{ '2', 'P', 'I', 'P', 'E' },

{ '3', 'P', 'I', 'P', 'E' },

{ '4', 'P', 'I', 'P', 'E' },

{ '5', 'P', 'I', 'P', 'E' },

};

int main() {
  /*
   * Создаём объект radio для работы с библиотекой RF24,
   * указывая номера вывода CE и SPI порта
   */
  RF24 radio(BCM_PIN, SPI_DEV);
  /*
   * Инициируем работу nRF24L01+
   */
  radio.begin();
  /*
   * режим подтверждения приёма, 1 вкл 0 выкл
   */
  radio.setAutoAck(1);
  /*
   * время между попыткой достучаться, число попыток
   */
  radio.setRetries(0, 15);
  /*
   * Разрешить динамически изменяемый размер блока данных для всех труб.
   */
  radio.enableDynamicPayloads();
  /*
   * Открываем трубу с идентификатором 0x1111111111LL для приема данных
   * (на одном канале может быть открыто до 6 разных труб, которые должны
   * отличаться только последним байтом идентификатора)
   */
  for (int i = 0; i < 6; i++) {
    radio.openReadingPipe(i, pipesAddress[i]);
  }
  /*
   * Указываем канал передачи данных (от 0 до 127),
   * (на одном канале может быть только 1 приёмник и до 6 передатчиков)
   * Выбираем канал в котором нет шумов!
   */
  radio.setChannel(0x70);
  /*
   * Указываем мощность передатчика
   * RF24_PA_MIN=-18dBm
   * RF24_PA_LOW=-12dBm
   * RF24_PA_HIGH=-6dBm
   * RF24_PA_MAX=0dBm
   */
  radio.setPALevel(RF24_PA_MAX);
  /*
   * Указываем скорость передачи данных
   * RF24_250KBPS = 250Кбит/сек
   * RF24_1MBPS = 1Мбит/сек
   * RF24_2MBPS = 2Мбит/сек
   */
  radio.setDataRate(RF24_1MBPS);

  /*
   * Включаем приемник, начинаем прослушивать открытую трубу
   */
  radio.startListening();
  radio.printDetails();
  cout << "startListening" << endl;
  while (true) {
    /*
     * Если в буфере имеются принятые данные
     */
    if (radio.available(&pipeNumber)) {
      payloadSize = radio.getDynamicPayloadSize();
      /*
       * Читаем данные в массив data и указываем сколько байт читать
       */
      radio.read(&receivedData, payloadSize);
      cout << "Pipe: " << (int) pipeNumber << "; ";
      cout << "Size: ";
      printf("%02d", (int) payloadSize);
      cout << "; ";
      cout << "Data: [";
      for (uint8_t i = 0; i < payloadSize; ++i) {
        if (i == 0) {
          printf("%02X", receivedData[i]);
        } else {
          printf(", %02X", receivedData[i]);
        }
      }
      cout << "]" << endl;
    }
    __msleep(10);
  }
  return 0;
}

Компиляция и сборка

g++ -Ofast -Wall RF24_receiver.cpp -lrf24 -o RF24_receiver

Результат

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

Пример 3: Передача данных — Arduino скетч

Ниже приведённый код нужно залить на Arduino, можно залить на 6 плат, но не забудьте менять адрес трубы radio.openWritingPipe(pipesAddress[0]); — от 0 до 5.

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

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

byte counter = 0;
uint8_t data[32];
uint8_t payloadSize;
uint8_t pipesAddress[6][5] = {

  { '0', 'P', 'I', 'P', 'E' },

  { '1', 'P', 'I', 'P', 'E' },

  { '2', 'P', 'I', 'P', 'E' },

  { '3', 'P', 'I', 'P', 'E' },

  { '4', 'P', 'I', 'P', 'E' },

  { '5', 'P', 'I', 'P', 'E' },

}; //возможные номера труб

void setup(void) {
  Serial.begin(115200);
  printf_begin();
  /*
    Инициируем работу nRF24L01+
  */
  radio.begin();
  /*
    Режим подтверждения приёма, 1 вкл 0 выкл
  */
  radio.setAutoAck(1);
  /*
    Размер пакета, в байтах
  */
  radio.enableDynamicPayloads();
  /*
    Указываем канал передачи данных (от 0 до 127)
    (на одном канале может быть только 1 приёмник и до 6 передатчиков).
    Выбираем канал в котором нет шумов!
  */
  radio.setChannel(0x70);
  /*
    Указываем скорость передачи данных
    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);
  /*
    Открываем трубу для передачи данных (на одном канале
    может быть открыто до 6 разных труб, которые должны
    отличаться только последним байтом идентификатора)
  */
  radio.openWritingPipe(pipesAddress[0]);
  /*
    Не слушаем радиоэфир, мы передатчик
  */
  radio.stopListening();
  /*
    Дамп конфигурации RF для отладки
  */
  radio.printDetails();
}

void loop(void) {
  /*
    Передаём счетчик
  */
  payloadSize = random(1, 32);
  for (uint8_t i = 0; i < payloadSize; i++) {
    data[i] = i;
  }
  Serial.print("Передача:");
  for (uint8_t i = 0; i < payloadSize; i++) {
    Serial.print(" ");
    Serial.print((int) data[i]);
  }
  Serial.print("; ");
  if (radio.write(data, payloadSize)) {
    Serial.println("Данные приняты приёмником.");
  } else {
    Serial.println("Данные не приняты приёмником.");
  }
  /*
    Ждем 1000мс
  */
  delay(1000);
}

Материалы

Serial Peripheral Interface
Optimized High Speed NRF24L01+ Driver Class Documenation

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

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

  • А можно подобным образом создать подобие Walkie-Talkie для подключения к ip-камерам, построенным на базе MotionEYEOs?
    Возможно, вопрос сформулирован коряво (заранее извиняюсь).

    • Если я правильно понимаю, вам нужна простая рация. По мне так легче сделать её на Arduino, на ней есть встроенный АЦП.
      Можно использовать и встроенный или USB микрофон на Orange Pi/Raspberry Pi, но тут будет по сложнее, нужно будет написать драйвер, чтобы передать/получить звук по SPI < -> nRF24L01+

  • Нестыкуется
    Указано в таблице CE пин 22 оранжа, а на картинке с выводом пинов указан пин 29.
    Что куда?

    • Спасибо, что заметили.
      Пин 29 так, как указанно на картинке. Можно использовать любой вывод общего назначения (GPIO), нужно только менять значение константы

      #define BCM_PIN 7
  • подскажите, пожалуйста, как полученные данные передавать в php скрипт на raspberry?
    ^_^

  • I’ll appreciate if you can help hepatitis test also done and all negative result please helpI did have sex with 8 different strangers and right now i’m having fever and tiredness for more than a month and i’m confused?
    More people are using the internet to look for a online pharmacy hong kong effective if you’re over 65 years old?
    Personalized blood sugar self-monitoring benefits people with type 2 diabetes even if they’re not taking insulin, a new small study shows.

  • Custom Medical Stock Photo, Inc.
    Affordable prices can be found to Prevacid for details.
    Still, if you have any of these signs or other suspicious symptoms, you should see your health care professional right away.

  • Also avoid any drinks that contain alcohol.
    the pricesAlways ask if you get something new when you https://cilisfastmed.com/ cialis heartburn over the counter, or do I need a prescription?
    The same group tested the validity of questions commonly used to indicate presence of indoor molds, compared to established objective measures of mold e.

  • [url=https://maria-sharapovaar.biz]https://www.maria-sharapovaar.biz[/url]

    last news about maria sharapova
    https://www.maria-sharapovaar.biz

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

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