Autre Exemple de communication sans fil nRF24L01+ avec échange de structure

Salut - un des membres du forum avait besoin d'un petit coup de pouce pour échanger autre chose que un seul octet. J'ai repris en gros donc le même code que dans mon tuto précédent mais ce coup ci j'ai viré les boutons et les LEDs, tout l'affichage se fait sur le terminal

Il ne faut donc pour ce test que le matériel suivant:

2 x Arduino UNO
2 x (NRF24L01+ avec leur support adaptateur de tension 5V)

L'idée est toute simple, on met le même code sur les 2 arduinos mais le code va se configurer dynamiquement en fonction de la valeur de la Pin A0. Si A0 est à GND vous aurez le rôle 0, si elle est à une autre valeur alors vous avez le rôle 1 . ça permet d'avoir un seul code et de définir qui parle sur quel pipe et qui écoute sur quel pipe (en inversant les rôles) --> DONC BIEN BRANCHER CES FILS sinon virer la partie du setup() qui regarde A0 et mettre role à 0 pour un arduino, uploader dans le premier arduino, puis mettre role à 1 et uploader dans le second arduino.


Connexions depuis les composants vers l'arduino

NRF24L01+ avec leur support adaptateur de tension:
VCC --> 5V
GND --> GND
CE --> D7
CSN --> D8
SCK --> D13
MOSI (MO) --> D11
MISO (MI) --> D12
IRQ --> Non connecté

Configuration du logiciel
Arduino Pin A0 --> GND sur le premier Arduino (rôle = 0)
Arduino Pin A0 --> 3.3V sur le second Arduino (rôle = 1) (j'ai pris 3.3V car la pin 5V était prise :slight_smile: )


L'idée du code de démonstration est la suivante: chaque arduino va attendre pendant un moment aléatoire puis balancer un message structuré à l'autre arduino. ici la structure contient une zone de texte et un nombre. le code fait que le texte est la représentation ASCII du nombre ce qui permet de voir à l'affichage (si on en doutait) que l'on a bien reçu le message complet.

Voici le code:

// ************* La Radio *************
#include <SPI.h>
#include <RF24.h> // voir http://tmrh20.github.io/RF24/

// Configurer vos radio nRF24L01+ sur le bus SPI et mettre  CE sur D7 et CSN sur D8
RF24 radio(7, 8);

// Le nom des "pipes" de communication, un en lecture, un en écriture
const byte adresses[][6] = {"0pipe", "1pipe"}; // les "pipes" de communication de 1 à 5 doivent partager la même adresse sauf le premier octet

// A CONFIGURER sur la pin A0
// si A0 est à GND alors rôle = 0 --> le premier Arduino
// si A0 est à  3.3V ou 5V alors rôle = 1 --> pour le second
const byte configurationPin = A0;
uint8_t role;

// on déclare un message un peu complexe
struct message_t {
  char texte[11];         // 11 octets de texte - juste assez pour un unsined long qui est au plus de 10 caractères "4294967295" plus le nul '\0' de fin
  unsigned long chrono;   // 4 octets pour un timestamp
} message;


// ----------------------------------------------------------------------------------------
// envoi d'un octet vers l'autre radio
// ----------------------------------------------------------------------------------------

void envoyerMessage(message_t &msg)
{
  radio.stopListening();   // On arrête d'écouter pour qu'on puisse émettre

  if (!radio.write( &msg, sizeof(message_t) )) {
    Serial.println(F("erreur d'envoi"));
  }
  radio.startListening(); // On se remet en mode écoute
}

// ----------------------------------------------------------------------------------------
// vérifie si on a reçu une commande de la part de l'autre radio (1 octet)
// ----------------------------------------------------------------------------------------
boolean ecouterRadio(message_t &msg)
{
  boolean messageRecu = false;
  if ( radio.available()) {
    radio.read( &msg, sizeof(message_t));  // on lit le message
    messageRecu = true;
  }
  return messageRecu;
}

// ------------------------------------------------------------------

void setup() {
  pinMode(A0, INPUT); // cette pin sert à allouber les bonne adresses à chacun des modules

  randomSeed(analogRead(A1)); // la pin A1 est flottante on s'en  sert pour générer de l'aléatoire cf https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/

  Serial.begin(115200);

  role = (digitalRead(configurationPin) == LOW) ? 0 : 1 ; // si AO est LOW alors je suis le module 0 sinon je suis le module 1
  Serial.print(F("\nMon Role = ")); Serial.println(role);

  // On configure la radio
  radio.begin();
  
  // pour le test on règle le niveau d'énergie à RF24_PA_LOW pour éviter les interférences
  // mettre à RF24_PA_MAX si on veut la puissance d'émission max
  radio.setPALevel(RF24_PA_LOW);

  // On ouvre un pipe de lecture et un d'écriture avec des noms opposés en fonction du rôle
  // comme ça un parle sur "pipe0" et l'autre écoute sur "pipe0"
  // et l'autre parle sur "pipe1" tandisque Le premier écoute sur "pipe1"

  radio.openWritingPipe(adresses[role]); // role doit être 0 ou 1
  radio.openReadingPipe(1, adresses[1 - role]); // 1 - role = l'autre adresse

  // on commence à écouter si on nous parle
  radio.startListening();
}

// ------------------------------------------------------------------

void loop() {
  static unsigned long chronoPrecedent = millis();

  // on va parler de temps en temps de manière aléatoire
  unsigned long tempsAleatoire = random(5000); // une durée d'attente aléatoire avant d'émettre

  // tant qu'on n'a pas attendu assez longtems on ne fait qu'écouter si on reçoit un message
  while (millis() - chronoPrecedent <= tempsAleatoire) {
    if (ecouterRadio(message)) { // si on a reçu un message
      Serial.println(F("---------------------------"));
      Serial.print(F("J'ai recu \"")); Serial.print(message.texte);
      Serial.print(F("\"\ntiming = ")); Serial.println(message.chrono);
    }
  }

  // on a attendu assez longtemps on balance notre message
  chronoPrecedent = millis();
  ultoa(chronoPrecedent, message.texte, 10); // ultoa convertit un unsined long en texte https://www.microchip.com/webdoc/avrlibcreferencemanual/group__avr__stdlib_1ga34f41757388f40e340f31e370ac009b5.html
  message.chrono = chronoPrecedent;
  envoyerMessage(message);

}

le code est donc vraiment tout simple. On déclare une structure, le setup() prépare la configuration et dans la boucle on génère un nombre aléatoire qui sera notre temps de pause (entre 0 et 5 secondes), on fait une petite attente active sans delay() pour pouvoir écouter si on reçoit quelque chose pendant ce temps et une fois que l'on a attendu assez longtemps on balance notre message qui consiste simplement en la valeur de millis() à ce moment là, que l'on représente à la fois en ASCII et numériquement dans le message.

L'arduino de l'autre côté fait la même chose mais avec des pipes inversés, donc il écoute aussi et dès qu'il reçoit quelque chose il l'imprime (et inversement)

DONC:

  • vous câblez correctement les 2 Arduinos en n'oubliant pas de mettre A0 à GND sur l'un et 3.3V sur l'autre
  • vous sectionnez dans l'IDE le bon type d'Arduino
  • vous sélectionnez dans l'IDE le premier port série et vous uploadez
  • vous sélectionnez dans l'IDE le second port série et vous uploadez

à partir de ce moment là vos 2 arduinos ont le bon code.

Pour tester il faut 2 ports USB sur votre ordinateur et un logiciel terminal série pour pouvoir afficher les 2 voies Séries en même temps. -> sur Mac j'utilise CoolTerm qui existe aussi pour windows et Linux mais les utilisateurs PC souvent prennent PUTTY.

ASSUREZ VOUS QUE LA CONSOLE SERIE ARDUINO NE SOIT PAS OUVERTE.

Vous lancez votre programme Terminal, ouvrez 2 fenêtres que vous configurez séparément pour être connecté sur chacun des ports séries

Puis vous vous connectez et là magie vous voyez que chaque arduino redémarre (quand on ouvre la console série) et ils affichent leur rôle puis les messages qui défilent comme prévu aléatoirement

Bonjour, Je m'arrache les cheveux avec mes nrf24L01 depuis 4 jours.
Je viens d'essayer votre montage et votre code. Je reçois, erreur d'envoi. Je précise que j'ai testé plein de codes, plein de configurations. Avec "l'adaptateur 5v/3,3", sans, avec un condensateur 10uF, sans, alimenté par l'usb de l'ordi, puis alimenté par une alim d'atelier (faite avec une alim de pc). J'ai testé tous mes câbles à l’ohmmètre. toutes mes tensions au voltmètre. refais 10 fois les câblages. J'ai echangé les nrf24l01 avec deux neufs. Tout ça sans succés...
Vous avez l'air de maîtriser le sujet. auriez vous des idées d'autres chose à tester.
Je cherche à faire une radio commande, je suis à deux doigts d'en acheter une toute faite mais je ne me résoud pas à ne pas comprendre ce qui ne va pas...
Merci beaucoup.

Avez vous essayé avec un des codes d'exemple de la librairie RF24 ?
ensuite si vous avez essayé sans l'adaptateur 5v/3,3, ça veut dire quoi? vous avez balancé du 5V sur un module qui ne supporte que 3V ??