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

Беспроводная сеть Arduino с несколькими модулями NRF24L01

<основной класс="главный сайт" id="главный">

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

Обзор

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

В моих предыдущих уроках мы уже узнали, как установить беспроводную связь между двумя платами Arduino, используя модули NRF24L01 и библиотеку RF24. Теперь в дополнение к этой библиотеке мы будем использовать библиотеку RF24Network, которая позволяет простым способом построить беспроводную сеть Arduino с множеством плат, взаимодействующих друг с другом. Вот как работает топология сети.

Связь с несколькими модулями NRF24L01

Один модуль NRF24L01 может активно прослушивать до 6 других модулей одновременно.

Эта возможность используется библиотекой RF24Network для создания сети, организованной в топологии дерева, где один узел является базовым, а все остальные узлы являются дочерними элементами этого или другого узла. У каждого узла может быть до 5 дочерних элементов, и это может иметь глубину 5 уровней, что означает, что мы можем создать сеть из 3125 узлов. Каждый узел должен быть определен с помощью 15-битного адреса, который точно описывает положение узла в дереве.

На самом деле мы можем определить адреса узлов в восьмеричном формате. Таким образом, адрес мастера или базы — 00, адреса базовых дочерних узлов — от 01 до 05, адреса дочерних узлов 01 — от 011 до 051 и т. д.

Обратите внимание, что если узел 011 хочет связаться с узлом 02, связь должна проходить через узел 01 и базовый узел 00, поэтому эти два узла должны быть активны все время, чтобы связь была успешной.

Управление беспроводным серводвигателем Arduino с использованием сетевой библиотеки RF24

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

Компоненты, необходимые для этого руководства по Arduino, можно получить по ссылкам ниже:

Таким образом, используя потенциометр на первом Arduino, мы будем управлять серводвигателем на втором Arduino. Давайте теперь посмотрим на исходные коды.

Вот код со стороны потенциометра:

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

RF24 radio(10, 9);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 00;   // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01;      

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node);  //(channel, node address)
}

void loop() {
  network.update();
  unsigned long potValue = analogRead(A0);  // Read the potentiometer value
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Convert the value to 0-180
  RF24NetworkHeader header(node01);     // (Address where the data is going)
  bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Send the data
}Code language: Arduino (arduino)

Для начала нам нужно включить обе библиотеки RF24 и RF24Network, а также библиотеку SPI. Затем нам нужно создать объект RF24 и включить его в объект RF24Network. Здесь нам нужно определить адреса узлов в восьмеричном формате или 00 для этого узла и 01 для другого узла на стороне сервопривода.

В разделе настройки нам нужно инициализировать сеть, установив канал и адрес этого узла.

В секции цикла нам постоянно нужно вызывать функцию update(), через которую происходят все действия в сети. Затем мы считываем значение потенциометра и преобразуем его в значение от 0 до 180, подходящее для сервоуправления. Затем мы создаем заголовок сети, где мы назначаем адрес узла, куда идут данные. В конце с помощью функции write() мы отправляем данные на другой узел. Итак, здесь первый параметр содержит информацию об адресах, второй параметр указывает, какие данные будут отправлены, а третий параметр — это размер данных.

Вот код на стороне сервопривода:

/*
  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);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 01;   // Address of our node in Octal format ( 04,031, etc)

Servo myservo;  // create servo object to control a servo

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); //(channel, node address)
  myservo.attach(3);   // (servo pin)
}

void loop() {
  network.update();
  while ( network.available() ) {     // Is there any incoming data?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
    myservo.write(incomingData);  // tell servo to go to a particular angle
  }
}Code language: Arduino (arduino)

С другой стороны, на серводвигателе нам нужно определить библиотеки и объекты так же, как объяснялось ранее. Здесь адрес этого узла в восьмеричном формате — 01. После определения серводвигателя, в секции цикла, с помощью цикла while() и функции available() мы постоянно проверяем, есть ли какие-либо поступающие данные. Если true, мы создаем сетевой заголовок, через который будут приниматься данные, а также переменную, в которой данные будут храниться. Затем с помощью функции read() мы считываем данные и сохраняем их в переменной incomingData. В конце мы используем эти данные для перемещения серводвигателя в соответствии с потенциометром другого узла.

Беспроводная сеть Arduino с несколькими модулями NRF24L01

После понимания этого примера мы можем перейти к основному примеру этого руководства и построить беспроводную сеть из 5 Arduino, которые общаются друг с другом. Вот блок-схема примера.

Итак, из базы с помощью потенциометра мы будем управлять серводвигателем в узле 01, вторым потенциометром мы будем управлять светодиодами в узле 022, с помощью кнопки мы будем управлять светодиодом в узле 012, а светодиодом здесь в узле 012. база будет управляться с помощью потенциометра в узле 02. Также с помощью инфракрасного датчика в узле 012 мы будем управлять светодиодом в узле 01. Таким образом, мы можем заметить, что этот пример объясняет, как передавать и получать данные одновременно, а также как общаться с узлами из разных ветвей. Теперь давайте посмотрим на коды Arduino.

Связанный:Радиоуправляемый передатчик Arduino своими руками

Исходный код Base 00

/*
  Arduino Wireless Network - Multiple NRF24L01 Tutorial
          == Base/ Master Node 00==
  by Dejan, www.HowToMechatronics.com
  Libraries:
  nRF24/RF24, https://github.com/nRF24/RF24
  nRF24/RF24Network, https://github.com/nRF24/RF24Network
*/

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

#define button 2
#define led 3

RF24 radio(10, 9);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 00;   // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01;      // Address of the other node in Octal format
const uint16_t node012 = 012;
const uint16_t node022 = 022;

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

void loop() {
  network.update();
  //===== Receiving =====//
  while ( network.available() ) {     // Is there any incoming data?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
    analogWrite(led, incomingData);    // PWM output to LED 01 (dimming)
  }
  //===== Sending =====//
  // Servo control at Node 01
  unsigned long potValue = analogRead(A0);
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Suitable for servo control
  RF24NetworkHeader header2(node01);     // (Address where the data is going)
  bool ok = network.write(header2, &angleValue, sizeof(angleValue)); // Send the data

  // LED Control at Node 012
  unsigned long buttonState = digitalRead(button);
  RF24NetworkHeader header4(node012);    // (Address where the data is going)
  bool ok3 = network.write(header4, &buttonState, sizeof(buttonState)); // Send the data

  // LEDs control at Node 022
  unsigned long pot2Value = analogRead(A1);
  RF24NetworkHeader header3(node022);    // (Address where the data is going)
  bool ok2 = network.write(header3, &pot2Value, sizeof(pot2Value)); // Send the data
}Code language: Arduino (arduino)

Таким образом, на базовом или главном узле нам нужно определить библиотеки и объекты, как объяснялось ранее, а также определить все остальные узлы, на которые главный узел будет отправлять данные. В разделе циклов мы начинаем с постоянной проверки наличия входящих данных. Если это так, мы считываем данные, сохраняем их в переменной incomingData и используем для управления яркостью светодиода. Эти данные на самом деле поступают от потенциометра из узла 02. Если мы посмотрим на его код, то заметим, что настройка почти такая же. Важно назначить правильный адрес, куда мы хотим отправлять данные. В данном случае это мастер 00. Итак, после считывания значения потенциометра и преобразования его в подходящее значение ШИМ от 0 до 255, мы отправляем эти данные мастеру. Здесь мы можем заметить, что я использовал функцию millis() для отправки данных с интервалом в 10 миллисекунд.

Исходный код узла 02

/*
  Arduino Wireless Network - Multiple NRF24L01 Tutorial
        == Node 02 (Child of Master node 00) ==    
*/

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

RF24 radio(10, 9);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 02;   // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00;    // Address of the other node in Octal format

const unsigned long interval = 10;  //ms  // How often to send data to the other unit
unsigned long last_sent;            // When did we last send?

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

void loop() {
  network.update();
  //===== Sending =====//
  unsigned long now = millis();
  if (now - last_sent >= interval) {   // If it's time to send a data, send it!
    last_sent = now;
    unsigned long potValue = analogRead(A0);
    unsigned long ledBrightness = map(potValue, 0, 1023, 0, 255);
    RF24NetworkHeader header(master00);   // (Address where the data is going)
    bool ok = network.write(header, &ledBrightness, sizeof(ledBrightness)); // Send the data
  }
}Code language: Arduino (arduino)

Далее от мастера мы отправляем данные потенциометра на узел 01 для управления серводвигателем.

Исходный код узла 01

/*
  Arduino Wireless Network - Multiple NRF24L01 Tutorial
        == Node 02 (Child of Master node 00) ==
*/

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <Servo.h>

#define led 2

RF24 radio(10, 9);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 01;   // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00;    // Address of the other node in Octal format

Servo myservo;  // create servo object to control a servo

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); //(channel, node address)
  radio.setDataRate(RF24_2MBPS);
  myservo.attach(3);   // (servo pin)
  pinMode(led, OUTPUT);
}

void loop() {
  network.update();
  //===== Receiving =====//
  while ( network.available() ) {     // Is there any incoming data?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
    if (header.from_node == 0) {    // If data comes from Node 02
      myservo.write(incomingData);  // tell servo to go to a particular angle
    }
    if (header.from_node == 10) {    // If data comes from Node 012
      digitalWrite(led, !incomingData);  // Turn on or off the LED 02
    }
  }
}Code language: Arduino (arduino)

Узел 01 фактически получает данные от двух разных узлов, один для управления сервоприводом, а другой для управления светодиодами, поступающими от инфракрасного датчика узла 012.

Исходный код узла 012

/*
  Arduino Wireless Network - Multiple NRF24L01 Tutorial
            == Node 012 (child of Node 02)==    
*/

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

#define led 2
#define IR 3

RF24 radio(10, 9);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 012;  // Address of our node in Octal format ( 04,031, etc)
const uint16_t node01 = 01;    // Address of the other node in Octal format

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

void loop() {
  network.update();
  //===== Receiving =====//
  while ( network.available() ) {     // Is there any incoming data?
    RF24NetworkHeader header;
    unsigned long buttonState;
    network.read(header, &buttonState, sizeof(buttonState)); // Read the incoming data
    digitalWrite(led, !buttonState); // Turn on or off the LED
  }
  //===== Sending =====//
  unsigned long irV = digitalRead(IR); // Read IR sensor
  RF24NetworkHeader header8(node01);
  bool ok = network.write(header8, &irV, sizeof(irV)); // Send the data
}Code language: Arduino (arduino)

В таком случае мы используем атрибут header.from_node, чтобы получить информацию, из какого узла поступают данные. Если данные поступают от мастера, мы используем их для управления сервоприводом, а если данные поступают с узла 012, мы используем их для управления светодиодом.

В узле 012 у нас есть и передача, и прием. Инфракрасный датчик управляет ранее упомянутым светодиодом в узле 01, а здесь светодиод управляется кнопкой на главном устройстве.

Исходный код узла 022

/*
  Arduino Wireless Network - Multiple NRF24L01 Tutorial
            == 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);               // nRF24L01 (CE,CSN)
RF24Network network(radio);      // Include the radio in the network
const uint16_t this_node = 022;  // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00;    // Address of the other node in Octal format

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

void loop() {
  network.update();
  //===== Receiving =====//
  while ( network.available() ) {     // Is there any incoming data?
    RF24NetworkHeader header;
    unsigned long potValue;
    network.read(header, &potValue, sizeof(potValue)); // Read the incoming data
    // Turn on the LEDs as depending on the incoming value from the potentiometer
    if (potValue > 240) {
      digitalWrite(led1, HIGH);
    } else {
      digitalWrite(led1, LOW);
    }
    if (potValue > 480) {
      digitalWrite(led2, HIGH);
    } else {
      digitalWrite(led2, LOW);
    }
    if (potValue > 720) {
      digitalWrite(led3, HIGH);
    } else {
      digitalWrite(led3, LOW);
    }
    if (potValue > 960) {
      digitalWrite(led4, HIGH);
    } else {
      digitalWrite(led4, LOW);
    }
  }
}Code language: Arduino (arduino)

Наконец, светодиоды в узле 022 управляются с помощью данных, поступающих от другого потенциометра на ведущем устройстве.

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

На этом все, надеюсь, вам понравился этот проект Arduino и вы узнали что-то новое. Не стесняйтесь задавать любые вопросы в разделе комментариев ниже.


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

  1. Создание сети беспроводных датчиков в вашем доме
  2. Распознавание цифр AI с помощью PiCamera
  3. Беспроводная магнитная передача данных
  4. Мониторинг CO2 с помощью датчика K30
  5. Слепоглухое общение с 1Sheeld / Arduino
  6. Управление монетоприемником с помощью Arduino
  7. Arduino с Bluetooth для управления светодиодом!
  8. Емкостной датчик отпечатков пальцев с Arduino или ESP8266
  9. Беспроводные MIDI-адаптеры USB-BLE
  10. Игра с дисплеем Nextion