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 :

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

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.