Arduino pro mini - NRF24L01 - ACKPAYLOAD intégrer le Watchdog

Bonjour,

je souhaite réaliser une installation permettant d'obtenir la valeur de plusieurs capteurs de température et d'afficher celles ci sur un site internet.

Cette installation sera à base d'arduino pro mini couplée à une NRF24L01+ pour les capteurs et pour l'instant en phase mise au point une UNO + une NRF24L01+.

Grace aux exemples trouvés sur ce forum et sur celui en anglais, j'arrive à utiliser la fonctionnalité ACKPAYLOAD des NRF24L01 (Simple nRF24L01+ 2.4GHz transceiver demo - Exhibition / Gallery - Arduino Forum).

Maintenant, j'aimerais passer en basse consommation pour les capteurs et utiliser la fonction Watchdog de l'arduino pro mini.

Et là, ça bloque! en faisant un test avec un seul capteur, je reçois une donnée puis plus rien.

Pourtant, les mouchards que j'ai mis dans le sketch TX maître semblent indiquer que "ackPayload is Available" et que le message a bien été envoyé à l'esclave "radio.write successful".

Du coté de l'esclave RX, les messages semblent indiquer aussi que l'envoi du ackPayload est bien réalisé mais qu'une seule fois.

Je ne vois pas où ça peut bloquer.

Pouvez-vous m'aider ?

Ci dessous les Sketch et les sorties moniteur des messages :

TX Maître :

#include <SPI.h>
#include <RF24.h>
#include <nRF24L01.h>
#define CE 9//UNO
#define CS 10

//#define CE D2//wemos D1
//#define CS D8//wemos D1

//NRF24L01
RF24 radio(CE, CS);                // Micro nRF24L01 (CE,CSN)
byte dataToSend = 0; //Message envoyé pour collecte datas à chaque capteur
//char dataToSend = 'm'; //Message envoyé pour collecte datas à chaque capteur
float ackData; //Réponse avec datas des capteurs
uint8_t nbrCapteurs = 0;

const uint8_t numSlaves = 13;
const uint8_t slaveAddress[numSlaves][5] = {
  {'R', 'x', 'A', 'A', 'A'},
  {'R', 'x', 'A', 'A', 'B'},
  {'R', 'x', 'A', 'A', 'C'},
  {'R', 'x', 'A', 'A', 'D'},
  {'R', 'x', 'A', 'A', 'E'},
  {'R', 'x', 'A', 'A', 'F'},
  {'R', 'x', 'A', 'A', 'G'},
  {'R', 'x', 'A', 'A', 'H'},
  {'R', 'x', 'A', 'A', 'I'},
  {'R', 'x', 'A', 'A', 'J'},
  {'R', 'x', 'A', 'A', 'K'},
  {'R', 'x', 'A', 'A', 'L'},
  {'R', 'x', 'A', 'A', 'M'}
};



void setup() {
  Serial.begin(115200);
  SPI.begin(); //Communication RF
  delay(50);
  radio.begin();
  radio.setChannel(120);
  radio.setDataRate(RF24_2MBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.enableAckPayload();
  radio.setRetries(5, 3); // delay, count
  Serial.println("Choisir le nombre de capteurs");
  while (nbrCapteurs == 0) {
    if (Serial.available()) {
      nbrCapteurs = Serial.read() - '0';
    }
  }
}

void loop() {
  for (uint8_t n = 0; n < nbrCapteurs; n++) {
    radio.openWritingPipe(slaveAddress[n]);
    dataToSend++;
    if (dataToSend > 9) {
      dataToSend = 0;
    }
    if (radio.write(&dataToSend, sizeof(dataToSend))) {
      Serial.println("radio.write successful");
      if (radio.isAckPayloadAvailable()) {
        Serial.println("ackPayloadAvailable");
        radio.read(&ackData, sizeof(ackData));
        Serial.print("capteur N°: ");
        Serial.print(n);
       // Serial.println(dataToSend);
       Serial.print(" - ");
        Serial.println(ackData);
      }
    }
  }
  delay(3000);
}

RX Slave :

//ref : https://forum.arduino.cc/index.php?topic=668082.0
//https://forum.arduino.cc/index.php?topic=421081
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include "cactus_io_DS18B20.h"
#include <avr/sleep.h>
#include <avr/wdt.h>

float temperature = 0.0;
int DS18B20_Pin = 3; //DS18b20 Signal pin on digital 3
DS18B20 ds(DS18B20_Pin); // on digital pin 3

#define CE_PIN 7//PCB
#define CSN_PIN 8//PCB

const uint8_t address[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

ISR (WDT_vect)
{
  wdt_disable(); //désactive le watchdog
}

void myWatchdogEnable(const byte interval)
{
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_mode();            // now goes to Sleep and waits for the interrupt
}
// sleep bit patterns:
//  1 second:  0b000110
//  2 seconds: 0b000111
//  4 seconds: 0b100000
//  8 seconds: 0b100001

byte dataReceived;
//char dataReceived[10]; // this must match dataToSend in the TX
float ackData; // the values to be sent to the master
bool newData = false;

int test;

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

  ds.readSensor();
  delay(3000); // allow 3 seconds for sensor to settle down
  ds.readSensor(); // read again to avoid weird values for defaults

  radio.begin();
  radio.setChannel(120);
  radio.setDataRate(RF24_2MBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(1, address);
  radio.enableAckPayload();

  radio.startListening();

  radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
}

void loop() {
  radio.powerUp(); //alimente le module nrf24l01+
  delay(3000); //attente 3 secondes avant d’effectuer une mesure du capteur
  readTemp();
  getData();
  showData();
  delay(500);
  radio.powerDown(); //arrêt de l’alimentation du module nrf24l01+
  for (int i = 0; i < 30; i++) //mise en veille pendant 240 secondes
  {
       myWatchdogEnable (0b100001);  // 8 seconds
   // myWatchdogEnable (0b000111);  // 2 seconds
  }
}

void getData() {
  if ( radio.available() ) {
    radio.read( &dataReceived, sizeof(dataReceived) );
    updateReplyData();
    newData = true;
  }
}

//================

void updateReplyData() {
  test++;
  if (test > 100) {
    test = 0;
  }
  //  sprintf(ackData, "i0/%i/%s/%s/%s", test, "01", "01", "01");
  radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}

//================

void showData() {
  if (newData == true) {
    Serial.print("Data received : ");
    Serial.println(dataReceived);
    Serial.print(" ackPayload sent : ");
    Serial.println(ackData);
    newData = false;
  }
}
//================

void readTemp() {
  ds.readSensor();
  delay(3000); // allow 3 seconds for sensor to settle down
  ds.readSensor(); // read again to avoid weird values for defaults
  temperature = ds.getTemperature_C();
  ackData = temperature;
  Serial.print(F("\tTemperature Ext : "));
  Serial.print((ackData), 2);
  Serial.println(" °C");
  delay(1000);
}

Message coté TX master :

Choisir le nombre de capteurs
radio.write successful
ackPayloadAvailable
capteur N°: 0 - 0.00
radio.write successful
radio.write successful
ackPayloadAvailable
capteur N°: 0 - 21.69

Message coté SlaveA :

RadioPowerUp
	Temperature Ext : 21.69 °C
Radio Available
Data received : 1
 ackPayload sent : 21.69
RadioPowerUp
	Temperature Ext : 21.69 °C
Radio Available
Data received : 2
 ackPayload sent : 21.69
RadioPowerUp
	Temperature Ext : 21.75 °C
Radio Available
Data received : 3
 ackPayload sent : 21.75

Je vois que tu as placé un délai de 500ms avant endormissement. Sage précaution.
J'utilise plutôt la librairie MySensors qui fait tout ça pour moi.
Peut être en jetant un œil à leurs sources ?

Bonjour hbachetti,

Je vais regarder et chercher encore.

C'est sur qu'a terme je vais passer sur rpi et utiliser mysensors couple a domoticz.

Quel rpi tu conseille pour ça?

Mon DOMOTICSZ tourne sur un 3B+, très confortablement.
Je suis sûr qu'une 2B suffirait amplement.

Bien soigner l'achat de la SD, primordial.
Et pourquoi pas une alimentation UPS ? pour la sécurité ...

Tu passeras certainement beaucoup moins de temps à te former à DOMOTICZ / MySensors qu'à finaliser un projet maison.

Sans compter que MySensors accepte aussi le RFM69 433MHz ou 868MHz.
Redoutable sur les longues distances ...
Nécessite une passerelle supplémentaire bien entendu. Le code est fourni.

Ok merci, je regarde tout ca.