Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

Обзор

В этом уроке мы научимся создавать беспроводную сеть на Arduino, состоящую из нескольких трансиверов NRF24L01. В качестве примера собрана сеть из 5 узлов, каждый из которых может обмениваться данными с любым другим узлом и одновременно работать как передатчик, так и приёмник. Эта схема масштабируется до 3125 модулей на одном RF-канале. Рассмотрим, как это работает.

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

В предыдущих уроках мы уже изучали точечную связь между двумя Arduino с помощью библиотеки RF24. Теперь добавим библиотеку RF24Network, которая упрощает построение сети с множеством плат. Сетевая топология имеет древовидную структуру: один узел — базовый (master), остальные — дочерние. Каждый узел может иметь до 5 детей, глубина дерева — 5 уровней, итого максимум 3125 узлов. Адрес каждого узла — 15-битное число в восьмеричном формате, точно описывающее его положение в дереве.

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01
Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

Адреса задаются в восьмеричном формате: базовый узел — 00, его дети — 01–05, дети узла 01 — 011–051 и так далее. Важно: если узел 011 хочет передать данные узлу 02, пакет пройдёт через узлы 01 и 00, поэтому промежуточные узлы должны быть постоянно активны.

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

Простой пример: управление сервоприводом по беспроводной сети

Для понимания работы библиотеки начнём с двух узлов: потенциометр на узле 00 управляет сервоприводом на узле 01.

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

Код узла 00 (потенциометр)

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
   Example 01 - Servo Control / Node 00 - Potentiometer
   by Dejan, www.HowToMechatronics.com
   Libraries: nRF24/RF24, nRF24/RF24Network */
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>

RF24 radio(10, 9);                 // CE, CSN
RF24Network network(radio);        // Включаем радио в сеть
const uint16_t this_node = 00;     // Адрес этого узла (восьмеричный)
const uint16_t node01 = 01;        // Адрес целевого узла

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);    // (канал, адрес узла)
}

void loop() {
  network.update();                // Обязательный вызов для работы сети
  unsigned long potValue = analogRead(A0);
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // 0–180° для сервы
  RF24NetworkHeader header(node01); // Заголовок с адресом получателя
  bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Отправка
}

Код узла 01 (сервопривод)

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
   Example 01 - Servo Control / Node 01 - Servo motor */
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
#include <Servo.h>

RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 01;
Servo myservo;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  myservo.attach(3);               // Пин сервопривода
}

void loop() {
  network.update();
  while (network.available()) {    // Есть входящие данные?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData));
    myservo.write(incomingData);   // Поворачиваем серву
  }
}

Разбор: В setup() инициализируем сеть (канал 90, адрес узла). В loop() вызываем network.update() — это сердце библиотеки, обрабатывающее маршрутизацию. Отправка: создаём заголовок RF24NetworkHeader с адресом получателя и вызываем network.write(). Приём: проверяем network.available(), читаем network.read().

Основной пример: сеть из 5 узлов

Теперь построим сеть из 5 Arduino, где базовый узел управляет периферией, а периферия передаёт данные обратно и между собой.

Создание надежной беспроводной Mesh-сети на Arduino с модулями NRF24L01

Сценарий:

Это демонстрирует двусторонний обмен и межветвенную коммуникацию.

Код базового узла 00

/* Base / Master Node 00 */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define button 2
#define led 3

RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 00;
const uint16_t node01 = 01;
const uint16_t node012 = 012;
const uint16_t node022 = 022;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  radio.setDataRate(RF24_2MBPS);
  pinMode(button, INPUT_PULLUP);
  pinMode(led, OUTPUT);
}

void loop() {
  network.update();

  // === Приём ===
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData));
    analogWrite(led, incomingData); // Яркость от потенциометра узла 02
  }

  // === Передача ===
  // Сервопривод на узле 01
  unsigned long potValue = analogRead(A0);
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180);
  RF24NetworkHeader header2(node01);
  network.write(header2, &angleValue, sizeof(angleValue));

  // Кнопка → узел 012
  unsigned long buttonState = digitalRead(button);
  RF24NetworkHeader header4(node012);
  network.write(header4, &buttonState, sizeof(buttonState));

  // Второй потенциометр → узел 022
  unsigned long pot2Value = analogRead(A1);
  RF24NetworkHeader header3(node022);
  network.write(header3, &pot2Value, sizeof(pot2Value));
}

Код узла 02 (потенциометр → базовый узел)

/* Node 02 (Child of Master 00) */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 02;
const uint16_t master00 = 00;
const unsigned long interval = 10; // мс
unsigned long last_sent;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  radio.setDataRate(RF24_2MBPS);
}

void loop() {
  network.update();
  unsigned long now = millis();
  if (now - last_sent >= interval) {
    last_sent = now;
    unsigned long potValue = analogRead(A0);
    unsigned long ledBrightness = map(potValue, 0, 1023, 0, 255);
    RF24NetworkHeader header(master00);
    network.write(header, &ledBrightness, sizeof(ledBrightness));
  }
}

Код узла 01 (сервопривод + светодиод от узла 012)

/* Node 01 (Child of Master 00) */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <Servo.h>

#define led 2
RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 01;
const uint16_t master00 = 00;
Servo myservo;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  radio.setDataRate(RF24_2MBPS);
  myservo.attach(3);
  pinMode(led, OUTPUT);
}

void loop() {
  network.update();
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData));
    if (header.from_node == 0) {        // От базового узла → серва
      myservo.write(incomingData);
    }
    if (header.from_node == 012) {      // От узла 012 → светодиод
      digitalWrite(led, !incomingData);
    }
  }
}

Здесь используется header.from_node для определения отправителя.

Код узла 012 (ИК-датчик → узел 01, кнопка от базы → свой светодиод)

/* Node 012 (child of Node 01) */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define led 2
#define IR 3
RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 012;
const uint16_t node01 = 01;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  radio.setDataRate(RF24_2MBPS);
  pinMode(led, OUTPUT);
  pinMode(IR, INPUT);
}

void loop() {
  network.update();
  // Приём от базы (кнопка)
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long buttonState;
    network.read(header, &buttonState, sizeof(buttonState));
    digitalWrite(led, !buttonState);
  }
  // Передача ИК-данных на узел 01
  unsigned long irV = digitalRead(IR);
  RF24NetworkHeader header8(node01);
  network.write(header8, &irV, sizeof(irV));
}

Код узла 022 (4 светодиода от потенциометра базы)

/* Node 022 (child of Node 02) */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define led1 2
#define led2 3
#define led3 4
#define led4 5
RF24 radio(10, 9);
RF24Network network(radio);
const uint16_t this_node = 022;
const uint16_t master00 = 00;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);
  radio.setDataRate(RF24_2MBPS);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

void loop() {
  network.update();
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long potValue;
    network.read(header, &potValue, sizeof(potValue));
    // Пороговое включение светодиодов
    digitalWrite(led1, potValue > 240);
    digitalWrite(led2, potValue > 480);
    digitalWrite(led3, potValue > 720);
    digitalWrite(led4, potValue > 960);
  }
}

Заключение

Если все узлы подключены правильно и остаются активными, задача сводится к точной адресации — всю сложную работу по маршрутизации и повторной передаче берет на себя библиотека RF24Network. Это мощный инструмент для создания масштабируемых беспроводных сетей на Arduino.

Производственный процесс

  1. Построение доступной беспроводной сети датчиков для дома
  2. Распознавание рукописных цифр на Raspberry Pi с TensorFlow и OpenCV
  3. Беспроводная передача данных по магнитному полю на Arduino с 3D-сенсором Infineon
  4. Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
  5. Устройство для общения глухосліпых людей с помощью 1Sheeld и Arduino
  6. Умная копилка: управление монетоприёмником на Arduino Nano
  7. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  8. Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
  9. USB-BLE MIDI-адаптеры на Arduino: беспроводное подключение инструментов к iOS
  10. Интерактивный HMI-проект на Nextion с Arduino Mega и датчиками