logo
+7 (495) 997-37-74
Москва, ул.Международная, 15

uniSensors nRF24 — Программирование

Программирование беспроводного контроллера uniSensors nRF24 не вызывает особых проблем, даже если вы не являетесь профессиональным программистом. В этой статье мы подробно разберём весь процесс написания скетчей для uniSensors nRF24.

Составные части uniSensors nRF24

Контроллер uniSensors nRF24 состоит из двух основных частей: микроконтроллера ATmega328P (такой же как и в Arduino Pro Mini) и радиочастотного nRF24 модуля (nRF24L01). Поэтому и программирование его разделяется на две части — программирование микроконтроллера ATmega328P (это делается также, как и программирование Arduino Pro Mini) и программирование беспроводного nRF24 модуля (это делается при помощи nRF24 библиотеки).

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

К выводам микроконтроллера ATmega328P на плате uniSensors nRF24 подключаются различные датчики и актуаторы так, как вы это обычно делаете в своих Ардуино-проектах, а в Arduino IDE вы пишите привычный вам код. Если вы на этом остановитесь, то у вас получится аналог контроллера Arduino Pro Mini с присущими ему возможностями.

Если же вам нужно передавать и принимать данные беспроводным способом, то вы просто пользуетесь функциями подключённой nRF24 библиотеки. Сам код беспроводного обмена очень несложный и мы подробно разберём его чуть ниже.

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

Кроме микроконтроллера и беспроводного модуля, плата uniSensors nRF24 содержит ещё множество компонентов, таких, как микросхема EEPROM памяти, датчик температуры и влажности, криптомикросхема ATSHA204A для хранения ключей шифрования и т. д. Примеры программирования и работы со всеми этими компонентами вы сможете найти в других статьях этой документации.

Сборка uniSensors nRF24

Для начала работы с контроллером нужно подсоединить модуль nRF24 к основной плате (ставить в соответствующий разъём).

Подключение USB-UART переходника к контроллеру uniSensors nRF24 производится 5-ю проводниками по следующей схеме:

Переходник – Контроллер

DTR – DTR

RX – TX

TX – RX

VCC – 3.3V

GND – GND

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

Внимание! Будьте внимательны при подключении USB-UART переходника к контроллеру uniSensors nRF24 и убедитесь, что он работает именно с напряжением 3,3 В, а не 5 В, иначе плата uniSensors nRF24 может выйти из строя.

Arduino IDE

Программировать плату uniSensors nRF24 можно в любой удобной вам среде разработки, но в этом руководстве мы будем говорить о работе в Arduino IDE, как наиболее популярной и простой среде программирования микроконтроллеров.

Примечание: все действия, упомянутые в статье, проводились в операционной системе Windows 7 64-bit, если у вас другая операционная система, то действия и внешний вид интерфейса могут немного отличаться.

Версия Arduino IDE роли не играет, все примеры из этой статьи будут работать в любой из последних версий Arduino, начиная с версии 1.6.5.

Для настройки Arduino IDE для работы с uniSensors nRF24 вам нужно выбрать в списке плат Arduino Pro Mini ATmega328P (3.3V 8 MHz) и порт, к которому подключён ваш USB-UART переходник. Это все настройки, которые вам нужно сделать, после этого вы уже можете начать программировать uniSensors nRF24.

Для работы с беспроводной частью контроллера вам понадобится ещё подключить nRF24 библиотеку. Загрузите эту библиотеку на компьютер и установите стандартным способом. После установки библиотеки не забудьте перезагрузить среду разработки Arduino IDE.

Программирование ATmega328P

Плата uniSensors nRF24 состоит из двух основных частей — микроконтроллера ATmega328P и радиочастотного nRF24 модуля. Для начала давайте разберём пример использования одного микроконтроллера ATmega328P, без радиочастотной nRF24 части. Этот пример ничем не будет отличаться от программирования стандартной платы Arduino Pro Mini.

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

/*
  uniSensors nRF24 Serial print example
*/

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start uniSensors nRF24!"));
}

void loop() {

}

После компиляции и загрузки этого скетча в контроллер uniSensors nRF24, вы можете наблюдать в Serial мониторе вывод тестового сообщения:

Аналогичным образом вы можете использовать микроконтроллер ATmega328P, встроенный в плату uniSensors nRF24, для программирования работы датчиков, актуаторов (например, реле), индикаторов и прочей периферии.

Но использовать таким образом плату uniSensors nRF24 не очень продуктивно, основное её достоинство — это беспроводной nRF24 модуль, о программировании которого мы поговорим далее.

nRF24 библиотека

Теперь перейдём к работе с радиочастотной частью платы uniSensors nRF24 и начнём со знакомства с nRF24 библиотекой. Эта библиотека содержит специфические функции для работы с nRF24 модулем, формирования, посылки и приёма nRF24 пакетов, а также некоторые дополнительные функции.

На этой странице находится подробное описание всех функций этой библиотеки. В наших примерах мы постепенно познакомимся с этими функциями и подробно разберём их работу.

Посылка nRF24 пакетов

Разбор работы беспроводной nRF24 связи мы начнём с примера посылки nRF24 пакетов в эфир, а в следующем примере разберём приём этих пакетов другим модулем uniSensors nRF24.

Ниже приведён пример скетча uniSensors nRF24 Sender, который формирует и посылает в эфир nRF24 пакеты с данными. Вот полный код скетча uniSensors nRF24 Sender:

/*
  uniSensors nRF24 Sender
  (based on standard example of nRF24 Library)
  (c)2020 Electromicro
  License: GNU GPL 2.1

  A simple example of sender nRF24 packets.
*/

#include <SPI.h>
#include "RF24.h"

#define RF_PIN A1

RF24 radio(6, 7); // CE, CSN
byte addresses[][6] = {"1Node", "2Node"};

#define PACKET_MAX_BYTES 32
byte buffRx[PACKET_MAX_BYTES];

byte buffTx[PACKET_MAX_BYTES] = {
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24 Sender start..."));

  pinMode(RF_PIN, OUTPUT);
  digitalWrite(RF_PIN, LOW);
  delay(500);

  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.openWritingPipe(   addresses[1]);
  radio.openReadingPipe(1, addresses[0]);
}

void printArray(byte arr[], byte len) {
  for (byte i = 0; i < len; i++) {
    if (arr[i] < 16) {
      Serial.print('0');
    }
    Serial.print(arr[i], HEX); Serial.print(' ');
  }
}

void loop() {
  radio.stopListening();
  Serial.print(F("Sending..."));

  unsigned long start_time = micros();

  if (!radio.write(&buffTx, PACKET_MAX_BYTES)) {
    Serial.println(F("failed"));
  }

  radio.startListening();

  unsigned long started_waiting_at = micros();
  boolean timeout = false;

  while (!radio.available()) {
    if (micros() - started_waiting_at > 200000 ) { // 200ms
      timeout = true;
      break;
    }
  }

  if (timeout) {
    Serial.println(F("Failed response."));
  } else {
    radio.read(&buffRx, PACKET_MAX_BYTES);
    Serial.print(F("Response: ")); printArray(buffRx, 32); Serial.println();
  }
  delay(3000);
}

Этот скетч выполняет одну простую функцию: отсылает тестовый 32-байтовый массив buffTx на другой контроллер uniSensors nRF24 и принимает от него обратно этот же массив. Разберём подробно работу этого скетча.

Вначале мы подключаем необходимые библиотеки: SPI для обеспечения работы по SPI интерфейсу и nRF24 для поддержки специфических nRF24 функций.

#include <SPI.h>
#include "RF24.h"

Далее задаём вывод управления подачей питания на nRF24 модуль, это пин A1.

#define RF_PIN A1

Создаём объект для управления модулем nRF24L01 и указываем номера GPIO для подключения его CE и CSN выводов.

RF24 radio(6, 7); // CE, CSN

Задаём адреса для связи «сендера» и «ресивера».

byte addresses[][6] = {"1Node", "2Node"};

И тестовый 32-байтовый массив для отсылки датчику.

byte buffTx[PACKET_MAX_BYTES] = {
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};

Затем, в функции setup(), подаём питание на радиомодуль uniSensors nRF24.

  pinMode(RF_PIN, OUTPUT);
  digitalWrite(RF_PIN, LOW);
  delay(500);

Включаем радиомодуль.

  radio.begin();

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

  radio.setPALevel(RF24_PA_MIN);

И настраиваем адреса для приёма и передачи данных.

  radio.openWritingPipe(   addresses[1]);
  radio.openReadingPipe(1, addresses[0]);

Далее в цикле loop() посылаем тестовый массив в эфир.

void loop() {
  radio.stopListening();

  Serial.print(F("Sending..."));

  unsigned long start_time = micros();
     
  if (!radio.write(&buffTx, PACKET_MAX_BYTES)) {
    Serial.println(F("failed"));
  }

Принимаем данные (32-байтовый массив) от ресивера и выводим его на печать в Serial.

    radio.read(&buffRx, PACKET_MAX_BYTES);
    Serial.print(F("Response: ")); printArray(buffRx, 32); Serial.println();

Код:

  radio.startListening();

  unsigned long started_waiting_at = micros();
  boolean timeout = false;

  while (!radio.available()) {
    if (micros() - started_waiting_at > 200000 ) { // 200ms
      timeout = true;
      break;
    }      
  }

отвечает за включение (в цикле) прослушивания эфира и прерывание этого прослушивания по таймауту (если ресивер по какой-то причине не отвечает).

Скетч рассчитан на работу с «ответной» частью (скетчем ресивера), который мы рассмотрим далее в этой статье.

Содержимое вывода в Serial Monitor скетча nRF24 Sender при посылке пакетов:

Вот и весь скетч формирования и посылки nRF24 пакетов в эфир. Таким же образом вы можете формировать любое другое содержимое nRF24 пакетов и реализовывать любое расписание посылки их в эфир. Содержимым пакетов могут быть текстовые сообщения, значения переменных, какие-либо кодовые команды и т. п. информация.

Приём nRF24 пакетов

Посылать nRF24 пакеты мы научились, теперь поговорим об их приёме. Принимать пакеты мы будем при помощи второй платы uniSensors nRF24. Для этого напишем и разберём работу скетча uniSensors nRF24 Receiver. Код скетча:

/*
  uniSensors nRF24 Receiver
  (based on standard example of nRF24 Library)
  (c)2020 Electromicro
  License: GNU GPL 2.1
  
  A simple example of receiver nRF24 packets.
*/

#include <SPI.h>
#include "RF24.h"

#define RF_PIN A1

RF24 radio(6, 7);
byte addresses[][6] = {"1Node", "2Node"};

#define PACKET_MAX_BYTES 32
byte buffRx[PACKET_MAX_BYTES];

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24 Receiver start..."));

  pinMode(RF_PIN, OUTPUT);
  digitalWrite(RF_PIN, LOW);
  delay(500);
  
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);

  radio.openWritingPipe(   addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.startListening();
}

void printArray(byte arr[], byte len) {
  for (byte i = 0; i < len; i++) {
    if (arr[i] < 16) {Serial.print('0');}
    Serial.print(arr[i], HEX); Serial.print(' ');
  }
}

void loop() {
  if (radio.available()) {
    while (radio.available()) {
      radio.read(&buffRx, PACKET_MAX_BYTES);
    }
   
    radio.stopListening();
    radio.write(&buffRx, PACKET_MAX_BYTES);
    radio.startListening();     
    
    Serial.print(F("Send response: ")); printArray(buffRx, 32); Serial.println();
  }
}

Скетч аналогичен уже рассмотренному выше скетчу uniSensors nRF24 Sender, поэтому здесь мы остановимся только на их отличиях. Подключение библиотек и функция setup() остаются прежними. Меняются адреса посылки и приёма пакетов.

  radio.openWritingPipe(   addresses[0]);
  radio.openReadingPipe(1, addresses[1]);

Далее скетч в цикле принимает данные по беспроводной nRF24 сети и отсылает их обратно.

void loop() {
  if (radio.available()) {
    while (radio.available()) {
      radio.read(&buffRx, PACKET_MAX_BYTES);
    }
    radio.stopListening();
    
    radio.write(&buffRx, PACKET_MAX_BYTES);
    radio.startListening();
    
    Serial.print(F("Send response: ")); printArray(buffRx, 32); Serial.println();
  }
}

Подробнее. Принимает данные в массив buffRx:

  if (radio.available()) {
    while (radio.available()) {
      radio.read(&buffRx, PACKET_MAX_BYTES);
    }

Останавливает прослушивание эфира

    radio.stopListening();

отсылает обратно полученные данные

    radio.write(&buffRx, PACKET_MAX_BYTES);

и снова начинает прослушивать эфир для получения следующего пакета

    radio.startListening();

Далее просто выводит на печать принятые данные

Serial.print(F("Send response: ")); printArray(buffRx, 32); Serial.println();

Вот результат работы нашего скетча:

Вот и всё, как видите, приём nRF24 пакетов ненамного сложнее их посылки и всё это благодаря nRF24 библиотеке, которая берёт на себя львиную долю всей работы.

Вместо простого вывода в Serial содержимого принятого пакета можно его анализировать и использовать любым способом, согласно логики вашего проекта. Расстояние между платами nRF24 передатчика и приёмника может составлять до сотни метров, в зависимости от окружающих условий и рельефа местности.

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

Заключение

В этой статье мы рассмотрели начало работы и основные приёмы программирования беспроводного nRF24 контроллера uniSensors nRF24. Как вы могли убедиться, работа с платой uniSensors nRF24 не представляет каких-то проблем и является простым и очень интересным занятием!

Ссылки по теме

Обзор контроллера uniSensors nRF24

Спецификации uniSensors nRF24

Программирование uniSensors nRF24

Работа с памятью M25P40. Часть 1. Спецификации и библиотека

Работа с памятью M25P40. Часть 2. Sleep, Wakeup, Erase и Busy

Работа с памятью M25P40. Часть 3. Read и Write Byte и Arrays

Работа с памятью M25P40. Часть 4. Работа с беззнаковыми типами данных

Работа с памятью M25P40. Часть 5. Работа со знаковыми типами данных

Работа с памятью M25P40. Часть 6. Read и Write Float

Работа с памятью M25P40. Часть 7. Read и Write Char array и String

Работа с памятью M25P40. Часть 8. Работа с секторами

Работа с памятью M25P40. Часть 9. Выборочное стирание секторов

Работа с памятью M25P40. Часть 10. Копирование секторов

Работа с памятью M25P40. Часть 11. Восстановление (backup) секторов

Работа с памятью M25P40. Часть 12. Работа с блоками памяти

Работа с памятью M25P40. Часть 13. Пишем библиотеку для работы с M25P40

Где купить?

uniSensors nRF24 в магазине «Electromicro»

Техническая поддержка

Мы внимательно относимся к потребностям наших клиентов и осуществляем техническую поддержку всей выпускаемой продукции. Вы можете написать нам письмо с вашим вопросом или позвонить по телефону и специалист нашей компании проконсультирует вас и поможет решить вашу проблему.

  • Емейл для вопросов по нашей продукции: electromicro@bk.ru
  • Наш телефон: +7 (495) 997-37-74

Аналогичные товары