Esclaves NRF24L01

Bonjour,
Je me permets de poster un message car il y a un truc que je ne comprends pas…
Mon but est simple:

  • j’envoie un message par exemple (“1”) pour lancer l’alerte.
    -L’esclave reçoit le message et si c’est (“1”) il envoie son “etat” .
    Cependant, l’Arduino reste bloqué, c’est à dire que je ne vois pas “envoie” .
    Donc je pense qu’il n’arrive pas à envoyer le message mais je ne sais pas pourquoi

Avez vous une idée ?
merci d’avance
Bonne journée

EMMETTEUR

//emmeteur  NRF24L01


#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#define CE_PIN   7
#define CSN_PIN 8

int alerte[1];
const uint64_t adresse[] = {0x01, 0x02};   // adresse du canal de communication
RF24 radio(CE_PIN, CSN_PIN);
const int interupteur = 3;


void setup(void)
{
  alerte[0] = 1;
  Serial.begin(9600);
  radio.begin();
  pinMode (interupteur, INPUT_PULLUP);
  radio.setPALevel(RF24_PA_MAX); // puissance maxi

}

void loop(void)
{

  if (digitalRead (interupteur) == LOW) {
    radio.openWritingPipe(adresse[0]);
    radio.write( alerte, sizeof(alerte) );
  }
}

RECEPTEUR

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#define CE_PIN   7
#define CSN_PIN 8
#include <avr/sleep.h>
const uint64_t adresse[] = {0x01, 0x02};  // adresse du canal de communication

RF24 radio(CE_PIN, CSN_PIN);    // création de l'objet radio
int data[1];
int etat[1];

void setup()
{
  Serial.begin(9600);
  etat[0] = 1;
  pinMode (2, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1, adresse[0]);
  radio.startListening();

  radio.maskIRQ(1, 1, 0);           
  attachInterrupt(1, interruptFunction, FALLING);//1 pour pin 3

}


void interruptFunction() {

  if ( radio.available() )
  {
    digitalWrite(2, HIGH);
    radio.read( data, sizeof(data) );
    Serial.print("recu =");
    Serial.println(String(data[0]));

    if (data[0] == 1) {
      Serial.println("alerte recu");
    }
    delay(500);
    digitalWrite(2, LOW);
  }


    radio.openWritingPipe(adresse[1]);
    radio.write( etat, sizeof(etat) );
    Serial.print("envoie");
    delay(200);

    }



    void loop() {}

Pas très malin de faire tous ces traitements dans une routine d’interruption.
Une routine d’interruption doit être la plus courte possible.

Donc :

  • positionner un flag à true dans la routine
  • dans loop() :
    si flag == true :
    faire les traitements
    flag = false

Je pense qu’un anti-rebond sur l’émetteur ne ferait pas de mal.

Merci pour votre réponse rapide, maintenant, cela fonctionne, merci
-Mais maintenant, quand je le repasse en mode ‘écoute’ il ne se passe plus rien…
-Quand vous dites “anti-rebond” est-ce le fait de rajouter un delay après avoir appuyé sur l’interrupteur ?
voici le code amélioré:

//****************************************   recepteur

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#define CE_PIN   7
#define CSN_PIN 8
#include <avr/sleep.h>
const uint64_t adresse[] = {0x01, 0x02};  // adresse du canal de communication

RF24 radio(CE_PIN, CSN_PIN);    // création de l'objet radio
int data[1];
int etat[1];


boolean flag = false;


void setup()
{
  Serial.begin(9600);
  etat[0] = 1;
  pinMode (2, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1, adresse[0]);
  radio.startListening();

  radio.maskIRQ(1, 1, 0);
  attachInterrupt(1, interruptFunction, FALLING);//1 pour pin 3
}

void interruptFunction() {
  flag = true;
}



void loop() {

  if (flag == true) {
    if ( radio.available() )
    {
      digitalWrite(2, HIGH);
      radio.read( data, sizeof(data) );
      Serial.print("recu =");
      Serial.println(String(data[0]));

      if (data[0] == 1) {
        Serial.println("alerte recu");
      }
      digitalWrite(2, LOW);
    }


    radio.openWritingPipe(adresse[1]);
    radio.write( etat, sizeof(etat) );
    Serial.print("envoie");
    delay(200);
    
    radio.openReadingPipe(1, adresse[0]);
    radio.startListening();

    flag = false;

  }
}

Anti-rebond : oui éventuellement (50ms).

Le sketch fonctionne t-il sans cette gestion d’interruption ?
Pour le savoir il suffit de supprimer le test du flag.

Je viens de me rendre compte qu’il y a des problèmes d’indentation (enfin de crochet).
Quand je téléverse ce code, la DEL reste allumée, donc il bloque lors de l’envoie du message…étrange

void loop() {


  if ( radio.available() )
  {
    digitalWrite(2, HIGH);
    radio.read( data, sizeof(data) );
    Serial.print("recu =");
    Serial.println(String(data[0]));

    if (data[0] == 1) {
      Serial.println("alerte recu");

      radio.openWritingPipe(adresse[1]);
      radio.write( etat, sizeof(etat) );
      Serial.print("envoie");
      delay(50);
      radio.openReadingPipe(1, adresse[0]);
      radio.startListening();
    }
    digitalWrite(2, LOW);
  }

 // flag = false;

}

A mon avis il manque des choses :

radio.stopListening(); radio.write( etat, sizeof(etat) ); radio.startListening();

Et puis les openWritingPipe() et openReadingPipe() peuvent être appelés dans setup(), une seule fois.

Voir ici :

https://github.com/nRF24/RF24/blob/v1.3.4/examples/GettingStarted/GettingStarted.ino

Merci, en effet, il me manquait des bouts…
IL reste un petit problème, je ne reçois pas en retour le message…Voyez vous pourquoi ?
Nouveau code
EMMETTEUR

//emmeteur  NRF24L01


#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#define CE_PIN   7
#define CSN_PIN 8

int alerte[1];
int etat[1];
const uint64_t adresse[] = {0x01, 0x02};   // adresse du canal de communication
RF24 radio(CE_PIN, CSN_PIN);
const int interupteur = 3;


void setup(void)
{
  alerte[0] = 1;
  Serial.begin(9600);
  radio.begin();
  pinMode (interupteur, INPUT_PULLUP);
  radio.setPALevel(RF24_PA_MAX); // puissance maxi


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

}

void loop(void)
{

  if (digitalRead (interupteur) == LOW) {
    radio.stopListening();
    radio.write( alerte, sizeof(alerte) );
    delay(50);
    radio.startListening();
  }


  if ( radio.available() )
  {
    Serial.print("Etat recu : ");
    radio.read( etat, sizeof(etat) );
    Serial.println(String(etat[0]));
  }

}

RECEPTEUR

//****************************************   recepteur

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#define CE_PIN   7
#define CSN_PIN 8
#include <avr/sleep.h>
const uint64_t adresse[] = {0x01, 0x02};  // adresse du canal de communication

RF24 radio(CE_PIN, CSN_PIN);    // création de l'objet radio
int data[1];
int etat[1];


boolean flag = false;


void setup()
{
  Serial.begin(9600);
  etat[0] = 1;
  pinMode (2, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1, adresse[0]);
  radio.openWritingPipe(adresse[1]);

  radio.startListening();

  radio.maskIRQ(1, 1, 0);
  attachInterrupt(1, interruptFunction, FALLING);//1 pour pin 3
}

void interruptFunction() {
  flag = true;
}



void loop() {

if (flag==true){
  if ( radio.available() )
  {
    digitalWrite(2, HIGH);
    radio.read( data, sizeof(data) );
    Serial.print("recu =");
    Serial.println(String(data[0]));

    if (data[0] == 1) {
      Serial.println("alerte recu");

      radio.stopListening();
      radio.write( etat, sizeof(etat) );
      Serial.print("envoie");
      radio.startListening();
    }
    digitalWrite(2, LOW);
    flag=false;
  }

}}

delay(50) : pourquoi ici ? devrait être placé juste après la lecture du bouton.

Il serait bon de tester les valeurs retournées de radio.write(), comme dans l'exemple #6.

println() est capable d'afficher un int. Éviter String (pas bon à la santé du logiciel, sauf ESP8266 ou ESP32).

D'accord, j'ai rectifié cela. Est-il nécessaire de mettre un delay avant de repasser en mode 'écoute' ? Car quand je l'ajoute, de temps en temps j'ai une réponse (je reçois l'etat : 1). (voir ci dessous) Mais pas à tous les coups....

void loop() {

  if (flag == true) {
    if ( radio.available() )
    {
      digitalWrite(2, HIGH);
      radio.read( data, sizeof(data) );
      Serial.print("recu: ");
      Serial.print(String(data[0]));

      radio.stopListening();
      delay(60);
      radio.write( etat, sizeof(etat) );
      Serial.print(" envoi");


      radio.startListening();

      digitalWrite(2, LOW);
      flag = false;
    }

  }
}

Normalement non.

Les deux cartes sont-elles bien éloignées l'une de l'autre ?

radio.setPALevel(RF24_PA_MAX); // côté émetteur, mais pas côté récepteur ?

A oui effectivement, j'étais sans doute trop près de l'émetteur. Merci à vous ! D'ailleurs, si je veux relier en série mon Arduino nano à un esp32 il faut bien un convertisseur de niveau bilinéaire 5v 3.3v ? Bonne soirée

un convertisseur de niveaux, oui. unidirectionnel ou bidirectionnel selon la nature de la liaison, unidirectionnel seulement pour Tx et Rx