nRF24L01+ ACK toujours HS (lib RF24)

Bonsoir a tous

Toujours pour ma domotique, je bloque depuis pas mal de temps avec les nRF24L01+ pour transmettre mes données en utilisant les ACK.

Pour faire mon test, j'ai :
une MEGA (funduino) qui sert de maitre.
une UNO et deux standalone en recepteur.

Quand, depuis le maitre, j'envoi des données à un recepteur, le recepteur m'affiche bien la donnée, mais le maitre me dit que l'emission n'est pas passée.

Voici les codes

Recepteur

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(8,7);      //(CE,CS)    3,2 --> LCD Shield

void setup()
{
  Serial.begin(115200);

  radio.begin();
  radio.setAutoAck(true);
  radio.enableAckPayload();              
  radio.setRetries(0,15);
  radio.setChannel(100);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setPayloadSize(sizeof(long));
  radio.openWritingPipe((byte *)"CENTR");
  radio.openReadingPipe(1,(byte *)"0MODU");
  radio.openReadingPipe(2,(byte *)"3MODU");
  radio.startListening();
}

void loop(void) 
{
    byte pipeNo;
    unsigned long recept;                                       // Dump the payloads until we've gotten everything
    pipeNo=1;
    while( radio.available(&pipeNo)){
      radio.read( &recept, sizeof(unsigned long));
      radio.writeAckPayload(pipeNo,&recept, sizeof(unsigned long) );    
      Serial.print("Reception sur pipe ");
      Serial.print(pipeNo);
      Serial.print("   Valeur : ");
      Serial.println(recept);
   }
}

Maitre

#include <BoutonsAnalogique.h>    //boutons analogique

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"



#define BA_AUCUN 0
#define BA_MOINS 1
#define BA_PLUS 3
#define BA_VALIDER 2
#define BA_ANNULER 4
#define BA_BAS 7
#define BA_HAUT 6
#define BA_GAUCHE 8
#define BA_DROITE 5


RF24 radio(48,49);

BoutonsAnalogique BA(A7, 8, 20, 250, NULL);    //&handleButtons  //Pin,Nb boutons, AntiRebond, Repetition, Fonction

void setup(){

  Serial.begin(115200);
  Serial.println("MEGA en maitre");

  radio.begin();
  radio.setAutoAck(true);
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(0,15);
  radio.setChannel(100);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setPayloadSize(sizeof(unsigned long));
  radio.openWritingPipe((byte *)"1MODU");
  radio.openReadingPipe(1,(byte *)"CENTR");
  radio.startListening();
  radio.powerUp();
}

void loop(){
  unsigned long time;
  byte tmp=BA.get(); 
  switch (tmp) {
  case BA_HAUT: 
    //Envoi vers le module 1
    Serial.print("Envoi au module 1 : ");
    time=millis();
    radio.stopListening();
    radio.openWritingPipe((byte *)"1MODU");
    if (radio.write(&time, sizeof(unsigned long)),0)
    {
      Serial.println("OK");
    }
    else
    {
      Serial.println("HS");
    }
    radio.startListening();
    break;
  case BA_BAS: 
    //Envoi vers le module 2
    Serial.print("Envoi au module 2 : ");
    time=millis();
    radio.stopListening();
    radio.openWritingPipe((byte *)"2MODU");
    if (radio.write(&time, sizeof(unsigned long)),0)
    {
      Serial.println("OK");
    }
    else
    {
      Serial.println("HS");
    }
    radio.startListening();
    break;
  case BA_DROITE: 
    //Envoi vers le module 3
    Serial.print("Envoi au module 3 : ");
    time=millis();
    radio.stopListening();
    radio.openWritingPipe((byte *)"3MODU");
    if (radio.write(&time, sizeof(unsigned long)),0)
    {
      Serial.println("OK");
    }
    else
    {
      Serial.println("HS");
    }
    radio.startListening();
    break;
  case BA_GAUCHE: 
    //Envoi vers tous les modules
    Serial.print("Envoi au module 0 : ");
    time=millis();
    radio.stopListening();
    radio.openWritingPipe((byte *)"0MODU");
    if (radio.write(&time, sizeof(unsigned long)),1)
    {
      Serial.println("OK");
    }
    else
    {
      Serial.println("HS");
    }
    radio.startListening();
    break;
  }  //fin switch
  //#########################  fin bouton analogique #############################


  // Teste si reception de données
  if(radio.available())
  {
    unsigned long recept;
    Serial.print("    Reception de nRF  : ");
    radio.read((byte *) &recept,sizeof(long));              //lecture des données reçues
    Serial.println(recept);
  } // if

}  // loop

Le moniteur du maitre me retourne :

MEGA en maitre
Envoi au module 2 : HS
Envoi au module 1 : HS
Envoi au module 3 : HS

et les recepteurs

Reception sur pipe 2   Valeur : 52738
Reception sur pipe 2   Valeur : 53188
Reception sur pipe 2   Valeur : 53567
Reception sur pipe 2   Valeur : 79857
Reception sur pipe 2   Valeur : 82217

Je suis parti de l'exemple de la lib "RF24" --> GettingStarted qui fonctionne mais que j'ai un peu modifié.
J'ai mis a jour la lib aujourd'hui et ça ne fonctionne pas mieux.

Qui a une idée du pourquoi ça ne fonctionne pas correctement?
Merci (et bonne nuit)

oui, mais je sais plus.
j'ai joué avec il n'y a pas longtemps, et je ne les ai plus sous la main.

je vais me servir au bar, le temps que ca me revienne.

j'avais le meme genre de problemes, et j'en suis venu a la conclusion de l'environement HF.
les deux modules etant à moins d'un metre de distance, ma freebox à 10 metres a travers murs porteur.

j'a changé
uint64_t baseAddress = 0x0000000000LL;
par
uint64_t baseAddress = 0xF0F0F0F0D2LL;
et ca a fonctionné.
j'ai pas approfondi depuis, j'ai prété les modules.

bonjour

Je suis parti de l'exemple de la lib "RF24" --> GettingStarted qui fonctionne mais que j'ai un peu modifié.
J'ai mis a jour la lib aujourd'hui et ça ne fonctionne pas mieux.

Dans le donte, j'ai retesté cet exemple, ça ne fonctionne pas non plus.

jean-I:
j'avais le meme genre de problemes, et j'en suis venu a la conclusion de l'environement HF.
les deux modules etant à moins d'un metre de distance, ma freebox à 10 metres a travers murs porteur.

C'est vrai que mes nRf24 sont a 30cm. Mais quand j'avais utilisé l'exemple la 1ere fois, ça fonctionné a peu près bien . 1 raté sur 10-15.

J'ai aussi fais un teste SCANNER pour voir la bande la plus efficace. On voit très bien ce que prend le WIFI. Le canal par défaut est en plein dedans, c'est pour ça que j'ai sélectionné le 100.
(Remarque a moi même. Est ce que j'ai sélectionné ce canal pour mon test de l'exemple ce matin ??)

Je vérifierais ça ce soir si je peux

A+

tu veux dire que meme les exemple de la lib ne fonctionnent plus?
t'aurai pas modifié d'autres lib? genre spi? t'es sous quel os et quelle version d'ide?
tu peut faire un essai avec une installation fraiche de l'ide?

le code que j'ai uilisé/adapté fait ping - pong - bang. chacun des deux modules n'envoi donc jamais le meme message deux fois de suite.

en vrac:

//http://wizzhardware.blogspot.fr/2014/04/communication-sans-fil-entre-deux.html
//http://itechnofrance.wordpress.com/2014/04/01/sonde-de-temprature-et-transmission-rf-avec-des-modules-nrf24l01/
//http://itechnofrance.wordpress.com/2014/03/28/sonde-de-temprature-et-consommation-dnergie/
//http://forum.arduino.cc/index.php/topic,248980.0.html

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
 
// creation d'un objet RF24, 9 et 10 sont les pins
// sur lesquelles les signaux CE et CSn sont branché
RF24 radio(9,10);
 
// l'adresse de base n'est pas une adresse mémoire mais plutôt
// un identifiant de transmetteur unique, sachant qu'un transmetteur
// peut ouvrir 6 pipes en lecture chacun avec une adresse unique.
// Il semble  recommandé que chaque pipe aient les même 32 premiers bits
// ici : 0x00 00 00 00--LL

//uint64_t baseAddress = 0x0000000000LL;
uint64_t baseAddress = 0xF0F0F0F0D2LL;

const uint64_t talking_pipes[5] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL, 0xF0F0F0F0B4LL, 0xF0F0F0F0A5LL, 0xF0F0F0F096LL };
const uint64_t listening_pipes[5] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL, 0x3A3A3A3AB4LL, 0x3A3A3A3AA5LL, 0x3A3A3A3A96LL };


int me = 0;
int other = 0;
int counter = 0;
//byte counter = 0;
int incomingByte = 0;   // for incoming serial data

char ping[8] = "1ping  ";
char pong[8] = "2poong ";
char bang[8] = "3baaang";

char s_recived[8] = "1234567";
char s_emit[8] = "1234567";
char c_recived[1] = {'A'};
String str_recived = "1234567";
String str_emited = "1234567";
 
void setup()
{
    Serial.begin(9600);
 
    // on entre l'identifiant du module radio local
    Serial.println("entrez votre identifiant : ");
    Serial.flush();
 
    while(true)
    {
        if(Serial.available())
        {
          delay(20);
            me = Serial.parseInt();
            break;
        }
    }
    while(Serial.available())
    {
        delay(20);
        incomingByte = Serial.read();
    }
    
    Serial.println(me);
 
    // on entre l'identifiant du module avec qui on veut correspondre
    Serial.println("entrez l'identifiant du module avec lequel vous voulez communiquer : ");
    Serial.flush();
    
    while(true)
    {
        if(Serial.available())
        {
          delay(20);
            other = Serial.parseInt();
            break;
        }
    }
    while(Serial.available())
    {
        delay(20);
        incomingByte = Serial.read();
    }
    Serial.println(other);

    SPI.begin();
    radio.begin();
    uint64_t address1 = baseAddress + other;

    radio.openWritingPipe(address1);
    //radio.openWritingPipe(talking_pipes[other]);
    
    uint64_t address2 = baseAddress + me;
    radio.openReadingPipe(1, address2);
    //radio.openReadingPipe(1, listening_pipes[me]);
    radio.startListening();
}
 
void loop()
{
    // initialisation du compteur de temps
    unsigned long t0 = millis();
    unsigned long t1 = t0;
 
    boolean done = false;

    while(true)
   {
        // mise ajour du compteur de temps
        t1 = millis();
        
        delay(1000);
 
        // si 3 secondes se sont écoulées sans aucun message, initiative de la com
        if( (t1-t0) > 3000 ) {
            //counter=radio.getPayloadSize();
            //Serial.print("getPayloadSize : ");
            //Serial.print(counter);

            counter = 1;
            
            Serial.print("Initiate Sending 1Ping (");
            Serial.print(sizeof(ping));
            Serial.print(" bytes) : ");
            
            Serial.println(ping);
             
            radio.stopListening();
        
            //radio.openWritingPipe(address1);
        
            delay(40);
            
            done = radio.write(&ping, 8);
            delay(100);
            if(done){
                Serial.println("send ping, 8 bytes ...success");}
            else{
                Serial.println("send ping, 8 bytes ...failed");}
             
            radio.startListening();
            delay(40);
            break;
        }
 
        if( radio.available() )
        {
            done = false;
           
            // on attend tant que la donnée n'est pas completement lisible.
            // il semble que la fonction 'radio.available' retourne true alors que
            // 'radio.read' ne peut pas retourner une donnée complete.
            while(!done) {
              delay(100);
              done = radio.read(&s_recived, 8);
              //delay(100);
            }
            //done = radio.read(&s_recived, 8);
 
            //Serial.print("counter recu : ");
            //Serial.println(counter);
            //Serial.print("chars recu : ");
            //Serial.println(s_recived);
             
            str_recived = s_recived;
            //str_recived = str_recived.substring(0,7);
            //str_recived.trim(); //remove whitespace
            
            //Serial.print("size recu : ");
            //Serial.println(sizeof(str_recived));
            Serial.print("str recu : ");
            Serial.print(str_recived);
            Serial.println("###");

            s_emit[0] = ' none? ';
            str_emited = " none? ";

            delay(40);
            radio.stopListening();
            delay(40);

            if (str_recived == "1ping  ") {
              str_emited = "2poong ";
              done = radio.write(&pong, 8);
            }
            else if (str_recived == "2poong ") {
              str_emited = "3baaang";
              done = radio.write(&bang, 8);
            }
            else if (str_recived == "3baaang") {
              str_emited = "1ping  ";
              done = radio.write(&ping, 8);
            }

            //done = radio.write(&str_emited, 8);
            delay(100);
            Serial.print("send ");
            Serial.print(str_emited);
            
            if(done){
                Serial.println(" ...success");}
            else{
                Serial.println(" ...failed");}

            radio.startListening();
            delay(40);
            break;
        }
   }
}

Re

j'ai tout repris depuis le debut.
J'ai fermé tous les IDE pour en relancer 2.
j'ai chargé l'exemple "GettingStarted" de la lib RF24.

j'ai ajouté un "radio.setChannel(100);" dans chacun et aussi changé les numéros de broche pour CE et CSN pou que ça colle eu hardware.

j'ai compilé les deux, un pour un MEGA et un pour un standalone.
J'ai aussi debranché les autres nRF24L01+ qui été alimenté sur les deux autres plaque d'essai pour n'avoir que les deux du test d'actif.

Je lance les moniteurs serie et sur celui du MEGA, j'envoi "T" pour le passer en maitre.

Le moniteur du maitre me retourne

*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
Now sending 
failed.
Failed, response timed out.
Now sending 
Sent 10731196, Got response 10731196, round-trip delay: 37520 microseconds
Now sending 
failed.
Failed, response timed out.
Now sending 
failed.
Sent 13044256, Got response 13044256, round-trip delay: 82096 microseconds
Now sending 
failed.
Failed, respo 8)nse timed out.

Par contre, l'esclave capte bien et m'affiche ce que j'attends

Sent response 9458204 
Sent response 10731196 
Sent response 11771268 
Sent response 13044256 
Sent response 14128896 
Sent response 15401876 
Sent response 16674864 
Sent response 17947872 
Sent response 19220860 
Sent response 20493848 
Sent response 21766828 
Sent response 23039812

Je mets le doigt sur l'antenne et la, miracle, plus un seul raté.

Now sending 
Sent 251611524, Got response 251611524, round-trip delay: 10736 microseconds
Now sending 
Sent 252625152, Got response 252625152, round-trip delay: 10764 microseconds
Now sending 
Sent 253638808, Got response 253638808, round-trip delay: 10764 microseconds
Now sending 
Sent 254652464, Got response 254652464, round-trip delay: 6320 microseconds
Now sending

J'inverse le maitre et l'esclave, ça ne fonctionne pas.
le maitre ne me fait que des timeout

Now sending 
failed.
Failed, response timed out.
Now sending 
failed.
Failed, response timed out.
Now sending 
failed.
Failed, response timed out.
Now sending 
failed.
Failed, response timed out.
Now sending

Même en mettant mon doigt sur le nRF24L01+ de l'esclave (ni sur celui du maitre d'ailleur) mais l'esclave reçoit bien les données.
Je n'y comprends plus rien.
Je rebascule, tout va bien. J'ai même posé une broche d'un condo qui trainé par la sur le nRF24 et ça continue de fonctionner.

Je continue mes test et la, plus rien ne fonctionne. l'esclave reçoit bien mais n'envoie rien.

Je suis perdu.

Je galère depuis des jours la dessus et le reste n'avance pas. ça non plus d'ailleurs.

Sur ceci, je vais me coucher. La suite demain si possible.
Bonne nuit a tous

a+

PS: @jean-l nos message se sont croisé.
La lib RF24 est toute fraiche d'hier.
Les seules lib que j'ai modifiées sont les miennes en cour de dev.
Je suis sous windows 8.1 64 bit avec IDE en 1.0.5-R2
Je testerai ton prog demain, la je suis trop naze pour reflechir plus
merci

Bonsoir
Je viens de retester, ça ne fonctionne que si je mets un bout de fil sur l'antenne du nRF24.
J'ai pensé à un truc, c'est de baisser le débit et la puissance. J'ai tout mis au minimum.
Tout va bien même SANS le bout de fil. Je pense donc que a distance trop proche des modules y est pour beaucoup. surtout quand la puissance est au max, valeur par défaut.

Je vais pouvoir continuer mon dev.
Je vous tiendrais au courant si cela fonctionne comme espéré.

a+

Tu utilises le 3,3V que fournit le Mega pour le nRF24 ?

alimenter avec le 3v3 du UNO, je n'ai jamais constaté une réelle difference, quand j'avais des soucis, a ce qu'une capa, quelque soit sa techno, resoudrait.
néanmoins, je n'ai pas non plus poussé les test tres loin, et il serai toujours bon d'en prévoir une (voir deux).
je n'ai pas de valeur specifique a proposer, vu que je n'ai plus les modules.

Disons que j'ai lu un peu partout, et notamment ici : http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo que l'appel de courant du nRF24 (en émission je suppose) nécessitait une meilleure alim 3.3V que celle fournie par les Arduino Uno ou Mega et qu'il fallait également une capa de découplage.

Pour mes essais je n'ai donc pas cherché à faire autrement. Le nRF était alimenté par une alim de breadboard (AMS1117) et j'avais fait de petites cartes avec une capa au tantale de 10µF.

jlbechennec:
Tu utilises le 3,3V que fournit le Mega pour le nRF24 ?

Non, j'utilise un AMS1117 3.3 avec un condo de 4.7µF pour chaque nRF24

jean-I:
alimenter avec le 3v3 du UNO, je n'ai jamais constaté une réelle difference, quand j'avais des soucis, a ce qu'une capa, quelque soit sa techno, resoudrait.
néanmoins, je n'ai pas non plus poussé les test tres loin, et il serai toujours bon d'en prévoir une (voir deux).
je n'ai pas de valeur specifique a proposer, vu que je n'ai plus les modules.

Au début, j'utiliser le 3.3V du UNO avec un condo 4.7µF mais comme ca ne fonctionné pas avec mes test, j'ai aussi mis un régulateur. Au final, je ne vais utiliser que des stand alone à part pour la centrale où ça sera un méga, donc des régulateur partout.

Sinon, je confirme qu'en baissant la puissance au min, ça marche nickel.
Il me faudra faire des teste de porté quand mes modules seront en place pour voir si je ne devrais pas booster la puissance.
En tout cas pour les tests avec les modules proches l'un de l'autre, il FAUT baisser au min la puissance.
Par contre, la vitesse n'influence pas la qualité de la transmission à courte distance.

Je vais pouvoir avancer. Enfin. Ouf

A+
Bonne nuit à tous

bonjour, petite retour d'expérience rapide :
j'ai fait 2 module (nrf + nano v3 + pc portable pour test )
donc en tout 2 nrf , 2 nano v3 , 2 pc portable.

presque aucune donnée ne passait , a 10 cm.. 10m etc..
j'ai changer la confit de la puissance d'antenne , du débit , du canal ... sans aucune amélioration.

a un moment le pc portable qui servait au module de réponse s'est mis en veille (avec toujours l'usb d'alimenté) et la miracle je reçoit toute mes trames correctement ( environ 1 erreur sur 20 ).

un de mes pc relâche trop d'onde parasite...