Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Dans ce tutoriel, nous allons apprendre à construire un réseau sans fil Arduino composé de plusieurs modules transcepteurs NRF24L01. Vous pouvez regarder la vidéo suivante ou lire le tutoriel écrit ci-dessous.

Vue d'ensemble

Comme exemple, j'ai réalisé un réseau de 5 nœuds, chacun pouvant communiquer avec n'importe quel autre nœud du réseau, tout en fonctionnant à la fois comme émetteur et récepteur. Cette configuration explique en réalité comment créer un réseau bien plus grand : précisément, nous pouvons avoir jusqu'à 3125 modules communiquant entre eux sur un seul canal RF. Voyons comment cela fonctionne.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Dans mes tutoriels précédents, nous avons déjà appris à établir une communication sans fil entre deux cartes Arduino en utilisant les modules NRF24L01 et la bibliothèque RF24. Ici, en plus de cette bibliothèque, nous utiliserons la bibliothèque RF24Network, qui permet de construire facilement un réseau sans fil Arduino avec de nombreuses cartes communiquant entre elles. Voici comment fonctionne la topologie du réseau.

Communication entre plusieurs modules NRF24L01

Un seul module NRF24L01 peut écouter activement jusqu'à 6 autres modules simultanément.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Cette capacité est exploitée par la bibliothèque RF24Network pour générer un réseau organisé en topologie arborescente (tree), où un nœud est la base (master), et tous les autres nœuds sont des enfants de ce nœud ou d'un autre. Chaque nœud peut avoir jusqu'à 5 enfants, et cette structure peut aller jusqu'à 5 niveaux de profondeur, ce qui permet de créer un réseau de 3125 nœuds au total. Chaque nœud doit être défini avec une adresse sur 15 bits, qui décrit précisément sa position dans l'arborescence.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Nous pouvons en fait définir les adresses des nœuds en format octal. Ainsi, l'adresse du master (nœud de base) est 00, les enfants de la base ont les adresses 01 à 05, les enfants du nœud 01 ont les adresses 011 à 051, et ainsi de suite.

Notez que si le nœud 011 veut communiquer avec le nœud 02, la communication doit passer par le nœud 01 et le nœud de base 00. Ces deux nœuds doivent donc être actifs en permanence pour que la communication réussisse.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Contrôle sans fil d'un servomoteur Arduino avec la bibliothèque RF24Network

Avant d'expliquer l'exemple principal de ce tutoriel, pour mieux comprendre le fonctionnement de la bibliothèque, réalisons un exemple plus simple de deux cartes Arduino communiquant entre elles. Voici le schéma de câblage pour cet exemple.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Vous pouvez vous procurer les composants nécessaires pour ce tutoriel Arduino via les liens ci-dessous :

  • Module transcepteur NRF24L01
  • Servomoteur
  • Potentiomètre
  • Arduino Nano

À l'aide du potentiomètre sur le premier Arduino, nous contrôlerons le servomoteur sur le second Arduino. Examinons maintenant les codes sources.

Code côté potentiomètre (Nœud 00) :

/* Réseau sans fil Arduino - Tutoriel Multiples NRF24L01 == Exemple 01 - Contrôle Servo / Nœud 00 - Potentiomètre == par Dejan, www.HowToMechatronics.com
Bibliothèques: 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); // Inclure la radio dans le réseau
const uint16_t this_node = 00; // Adresse de ce nœud en format octal (04, 031, etc.)
const uint16_t node01 = 01;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, adresse du nœud)
}

void loop() {
  network.update();
  unsigned long potValue = analogRead(A0); // Lire la valeur du potentiomètre
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Convertir en valeur 0-180 pour le servo
  RF24NetworkHeader header(node01); // Adresse de destination
  bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Envoyer les données
}

Nous devons d'abord inclure les bibliothèques RF24 et RF24Network, ainsi que la bibliothèque SPI. Ensuite, nous créons l'objet RF24 et l'incluons dans l'objet RF24Network. Nous définissons les adresses des nœuds en format octal : 00 pour ce nœud, et 01 pour l'autre nœud côté servo.

Dans la section setup, nous initialisons le réseau en définissant le canal et l'adresse de ce nœud.

Dans la boucle loop, nous devons constamment appeler la fonction update() qui gère toutes les actions du réseau. Ensuite, nous lisons la valeur du potentiomètre et la convertissons en une valeur de 0 à 180 adaptée au contrôle du servo. Nous créons un en-tête réseau (header) où nous assignons l'adresse du nœud destinataire. Enfin, en utilisant la fonction write(), nous envoyons les données vers l'autre nœud. Le premier paramètre contient les informations d'adressage, le second pointe vers les données à envoyer, et le troisième est la taille des données.

Code côté servomoteur (Nœud 01) :

/* Réseau sans fil Arduino - Tutoriel Multiples NRF24L01 == Exemple 01 - Contrôle Servo / Nœud 01 - Servomoteur == */
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
#include <Servo.h>

RF24 radio(10, 9); // nRF24L01 (CE, CSN)
RF24Network network(radio);
const uint16_t this_node = 01; // Adresse de notre nœud en format octal
Servo myservo; // Créer l'objet servo

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, adresse du nœud)
  myservo.attach(3); // Broche du servo
}

void loop() {
  network.update();
  while (network.available()) { // Y a-t-il des données entrantes ?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Lire les données
    myservo.write(incomingData); // Commander le servo à l'angle reçu
  }
}

De l'autre côté, au niveau du servomoteur, nous définissons les bibliothèques et les objets de la même manière. L'adresse de ce nœud en format octal est 01. Après avoir défini le servomoteur, dans la boucle loop, à l'aide de la boucle while() et de la fonction available(), nous vérifions constamment s'il y a des données entrantes. Si c'est le cas, nous créons un en-tête réseau pour recevoir les données et une variable pour les stocker. Ensuite, avec la fonction read(), nous lisons les données et les stockons dans la variable incomingData. Finalement, nous utilisons cette donnée pour déplacer le servomoteur selon la position du potentiomètre de l'autre nœud.

Réseau sans fil Arduino avec plusieurs modules NRF24L01

Après avoir compris cet exemple, nous pouvons passer à l'exemple principal et construire un réseau sans fil de 5 Arduinos communiquant entre eux. Voici un diagramme de blocs de l'exemple.

Construire un réseau mesh Arduino robuste avec des modules NRF24L01

Depuis la base, en utilisant un potentiomètre, nous contrôlerons le servomoteur au nœud 01 ; avec un second potentiomètre, nous contrôlerons les LEDs au nœud 022 ; à l'aide d'un bouton, nous contrôlerons la LED au nœud 012 ; et la LED à la base sera contrôlée par le potentiomètre au nœud 02. De plus, en utilisant le capteur infrarouge au nœud 012, nous contrôlerons la LED au nœud 01. On voit bien que cet exemple montre comment émettre et recevoir des données simultanément, ainsi que comment communiquer entre nœuds de branches différentes. Examinons maintenant les codes Arduino.

Lien connexe : DIY Arduino RC Transmitter

Code source de la base (Nœud 00)

/* Réseau sans fil Arduino - Multiples NRF24L01 == Base / Master Nœud 00 == par Dejan, www.HowToMechatronics.com
Bibliothèques: 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);
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();
  
  // ===== Réception =====
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData));
    analogWrite(led, incomingData); // Sortie PWM vers LED (variateur)
  }
  
  // ===== Émission =====
  // Contrôle servo au Nœud 01
  unsigned long potValue = analogRead(A0);
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180);
  RF24NetworkHeader header2(node01);
  bool ok = network.write(header2, &angleValue, sizeof(angleValue));
  
  // Contrôle LED au Nœud 012
  unsigned long buttonState = digitalRead(button);
  RF24NetworkHeader header4(node012);
  bool ok3 = network.write(header4, &buttonState, sizeof(buttonState));
  
  // Contrôle LEDs au Nœud 022
  unsigned long pot2Value = analogRead(A1);
  RF24NetworkHeader header3(node022);
  bool ok2 = network.write(header3, &pot2Value, sizeof(pot2Value));
}

Au nœud maître (base), nous définissons les bibliothèques et objets comme expliqué, ainsi que tous les autres nœuds vers lesquels le maître enverra des données. Dans la boucle, nous commençons par vérifier constamment s'il y a des données entrantes. Si c'est le cas, nous les lisons, les stockons dans incomingData et les utilisons pour contrôler la luminosité de la LED. Ces données proviennent en fait du potentiomètre du nœud 02. Si l'on regarde son code, le setup est très similaire. L'important est d'assigner la bonne adresse de destination. Ici, c'est le maître 00. Après avoir lu la valeur du potentiomètre et l'avoir convertie en valeur PWM de 0 à 255, nous envoyons cette donnée au maître. On note l'utilisation de la fonction millis() pour envoyer les données à intervalles de 10 millisecondes.

Code source du Nœud 02

/* Réseau sans fil Arduino - Multiples NRF24L01 == Nœud 02 (Enfant du 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; // ms
unsigned long last_sent;

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

void loop() {
  network.update();
  
  // ===== Émission =====
  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);
    bool ok = network.write(header, &ledBrightness, sizeof(ledBrightness));
  }
}

Ensuite, depuis le maître, nous envoyons les données du potentiomètre au nœud 01 pour contrôler le servomoteur.

Code source du Nœud 01

/* Réseau sans fil Arduino - Multiples NRF24L01 == Nœud 01 (Enfant du 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();
  
  // ===== Réception =====
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData));
    
    if (header.from_node == 0) { // Données venant du Master (Nœud 00)
      myservo.write(incomingData);
    }
    if (header.from_node == 012) { // Données venant du Nœud 012 (octal 10 en décimal)
      digitalWrite(led, !incomingData);
    }
  }
}

Le nœud 01 reçoit des données de deux nœuds différents : l'un pour le contrôle du servo, l'autre pour le contrôle de la LED provenant du capteur infrarouge du nœud 012. Dans ce cas, nous utilisons l'attribut header.from_node pour identifier la provenance des données. Si les données viennent du maître, nous contrôlons le servo ; si elles viennent du nœud 012, nous contrôlons la LED.

Code source du Nœud 012

/* Réseau sans fil Arduino - Multiples NRF24L01 == Nœud 012 (Enfant du Nœud 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();
  
  // ===== Réception =====
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long buttonState;
    network.read(header, &buttonState, sizeof(buttonState));
    digitalWrite(led, !buttonState); // Allumer/éteindre la LED
  }
  
  // ===== Émission =====
  unsigned long irV = digitalRead(IR); // Lire capteur IR
  RF24NetworkHeader header8(node01);
  bool ok = network.write(header8, &irV, sizeof(irV));
}

Au nœud 012, nous avons à la fois émission et réception. Le capteur infrarouge contrôle la LED mentionnée précédemment au nœud 01, et la LED locale est contrôlée par le bouton du maître.

Code source du Nœud 022

/* Réseau sans fil Arduino - Multiples NRF24L01 == Nœud 022 (Enfant du Nœud 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();
  
  // ===== Réception =====
  while (network.available()) {
    RF24NetworkHeader header;
    unsigned long potValue;
    network.read(header, &potValue, sizeof(potValue));
    
    // Allumer les LEDs selon la valeur du potentiomètre
    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);
  }
}

Enfin, les LEDs au nœud 022 sont contrôlées via les données provenant de l'autre potentiomètre au maître.

En résumé, si tout est correctement connecté et que tous les nœuds sont actifs en permanence, notre travail se résume à adresser précisément les nœuds ; tout le travail complexe en arrière-plan est géré par l'incroyable bibliothèque RF24Network.

C'est tout pour ce tutoriel. J'espère que vous avez apprécié ce projet Arduino et appris quelque chose de nouveau. N'hésitez pas à poser vos questions dans les commentaires ci-dessous.

Processus de fabrication

  1. Construire un réseau de capteurs sans fil abordable pour votre maison
  2. Créer un Reconnaissance de Chiffres sur Raspberry Pi avec TensorFlow et OpenCV
  3. Transfert de données magnétique sans fil Arduino + capteur 3D Infineon TLE493D
  4. Capteur CO2 K30 : Surveillance en temps réel de la qualité de l'air intérieur
  5. Faciliter la communication sourd-aveugle avec 1Sheeld et Arduino
  6. Construire une Tirelire Intelligente : Contrôler un Accepteur de Pièces avec Arduino Nano
  7. Contrôler une LED par Bluetooth avec Arduino et MIT App Inventor
  8. Intégrer un capteur d'empreintes capacitif DFRobot (ID809) avec Arduino ou ESP8266
  9. Adaptateurs MIDI USB-BLE sans fil – Connectivité transparente pour musiciens