LowPower.powerDown librairie

Bonjour,

Bonne année 2018.

Je développe une petite télécommande avec un Arduino Pro Mini.
Je souhaite limiter la consommation du montage émetteur au stricte minimum afin de préserver la réserve d'énergie le plus longtemps possible. J'utilise donc la librairie Low-Power-Master (#include LowPower.h)

 LowPower.powerDown (SLEEP_FOREVER, ADC_OFF, BOD_OFF);

La consommation tombe bien à environ 50µA mais lors du réveil du système par l'appui sur un interrupteur extérieur (INT0) le système ne répond pas toujours à mon attente.

Exemple :
Il faut que j'appuie plusieurs fois sur le bouton avant que le récepteur ne reçoive le message transmit.

Avant de transmettre le message je fais une mesure de tension par une entrée analogique (A0) puis je formate un mots que je transmets via un nrf24l01. La tension lue semble bonne et le moniteur série m'indique bien que le message a bien été préparé avant l'envoi. (Tout semble correcte.)

Avant que j'implémente la fonction LowPower, la transmission se faisait à tous les coups. (J'utilisai déjà l'interruption INT0.)

Questions :

1- Faut-il juste après le réveil de l'Arduino réactiver la fonction ADC que je vais utiliser pour lire la tension ? (Ou au réveil, toutes les fonctions de l’Arduino sont automatiquement/implicitement réactivées ?)
Si oui, comment fait-on ?

2- Quel est le délai nécessaire à l’Arduino pour se réveiller et réactiver ses fonctions ? (L'interruption est très vite détectée mais il est peut-être nécessaire de laisser du temps au système avant de lui demander de transmettre le message ?

3- Est-il nécessaire de laisser du temps au module nrf24l01 pour se synchroniser avec l’Arduino avant de transmettre le message ?

4- avez-vous d'autres suggestions ?

En vous remerciant de votre aide.

Cordialement.
Christian

Bonjour et bonne année!

est-ce que la première instruction après le

attachInterrupt(0, ISR_Reveil, LOW);

est un detachInterrupt(0); ?

que fait l'ISR? comment gérez vous le rebond du bouton ?

Bonjour J-M-L,

Les rebonds sont normalement supprimés par une capa de 10nF qui est en parallèle sur le poussoir.

L'interruption reste toujours active, la séquence ne contient pas le detachInterrupt(0);

Je vais effectivement essayer avec.

Voici mon code actuel :

#include <RF24.h>
#include "PinChangeInterrupt.h"
// #include <ArduinoLowPower.h>  //Librairie de gestion pour la faible consommation
#include "LowPower.h"

#define CE_PIN 9
#define CSN_PIN 10 //Since we are using 3 pin configuration we will use same pin for both CE and CSN


RF24 radio(CE_PIN, CSN_PIN);

byte address[11] = "SimpleNode";

const int pin_inter_poussoir = 2; // Entrée bouton poussoir associée à l'Interruption (Même Numéro)
const int interruption_poussoir = 0;  //INT0 sur la broche D2 de l'arduino NANO
const int pin_Lecture_Tension_Pile = 1; // Entrée analogique pour mesure tension pile
int Tension_Pile_Digit = 0;
const int iType_ADC=1023;
const int iRef_ADC=3300;
int State_Interruption = 0;

/** Différents messages de commande */
const char CMD_BOUTTON_A[] = "IT_LUM_COUL";  //Interrupteur Lumière Couloir
const char Numero_interrupteur[] = "01";

volatile boolean Interrupt_Flag = false;
//volatile boolean Interrupt_Flag = true;
int state_poussoir = 1;

void setup() {
  Serial.begin(9600); // activation moniteur série
  pinMode(pin_inter_poussoir, INPUT_PULLUP);
  radio.begin(); // Start up the radio
  radio.setAutoAck(1); // Ensure autoACK is enabled
  radio.setRetries(15,15); // Max delay between retries & number of retries
  radio.openWritingPipe(address); // Write to device address 'SimpleNode'
  attachInterrupt(interruption_poussoir, Fonction_Interruption, FALLING); //Active l'interruption liée à l'action sur le poussoir (Le signal passe de VCC à GND)
}

//***********************************************************************
void loop(void){
  int Tension_Pile_Digit = 0;
  int Tension_Pile_Analog_mv = 0;
  char Buffer_Message [30] = "message";
  int n;
  Serial.print("Interrupt_Flag  ");
  Serial.println(Interrupt_Flag);
  state_poussoir = digitalRead(pin_inter_poussoir);
  Serial.print("state_poussoir  ");
  Serial.println(state_poussoir);
  
  if(Interrupt_Flag) {
 // if(state_poussoir==0) {
  delay(200);
  Tension_Pile_Digit=analogRead(pin_Lecture_Tension_Pile);  // lire la tension de la pile (Lecture entre 0 et 1023.)
  Serial.print("Tension_Pile_Digit  ");
  Serial.println(Tension_Pile_Digit);
  //Tension_Pile_Digit=700;
  Tension_Pile_Analog_mv = (map(Tension_Pile_Digit,0,iType_ADC,0,iRef_ADC));  // Transformation valeur digit => Analog
  n=sprintf(Buffer_Message,"%s %s %d", CMD_BOUTTON_A, Numero_interrupteur, Tension_Pile_Analog_mv); // Transformation des différentes données en un seul mots qui sera envoyé.
  radio.write(Buffer_Message, n); //Send data to 'Receiver' ever 2 second
  Serial.println(Buffer_Message);
  Interrupt_Flag=false;
    //state_poussoir = 1;
  }
delay(100);

 LowPower.powerDown (SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}
//***********************************************************************

void Fonction_Interruption()
{
Interrupt_Flag=true;
}

Bonne journée.

comment est alimentée la partie radio? elle reste allumée?

sinon quelques commentaires

  • avec RF24 l'adresse doit être par défaut sur 5 octets donc byte address[11] = "SimpleNode";c'est trop long (pas vraiment gênant sauf si vous en créez un autre genre "SimpleNode2" alors votre récepteur ne saura pas différencier.

  • au lieu de faire const int interruption_poussoir = 0;  //INT0 sur la broche D2 de l'arduino NANOutilisez la fonction digitalPinToInterrupt()associée attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

  • on déclare généralement les pin plutôt en const byte

  • Si vous gardez des commentaires, autant qu'ils soient cohérent avec le code

#define CE_PIN 9
#define CSN_PIN 10 //Since we are using 3 pin configuration we will use same pin for both CE and CSN
  • quand vous faites radio.write(Buffer_Message, n); vous n'envoyez pas le caractère NULL '\0' de fin de chaîne. il faut donc en tenir compte de l'autre côté. dans l'idéal si sprintf plante n sera négatif, ce serait bien de tester avant de l'utiliser dans radio.write()

Merci J-M-L pour toutes ces infos.

Step 1- 5 octets pour le code de transmission donc 5 caractères ou chiffres, C'est fait ! (Je ne savais pas, je me contente souvent de copier des portion d'exemple que je trouve sur le net sans chercher plus dans le détail.)

Step 2- attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); C'est fait. (Je ne connaissait pas non plus. Parler de N° de broche c'est plus simple !)

Step 3- Reprendre les commentaires, oui car après moult modifications et essais, certains ne veulent plus rien dire.

Step 4- ajouter le NULL '\0' c'est fait mais je ne saisi pas pourquoi il est important de l'ajouter.
Est-ce pour indiquer qu'il s'agit de la fin du message ?

Après ces modifications le système semble beaucoup plus stable et plus réactif.
Je vais maintenant travailler sur le hardware : Type de pile, retirer la led power du Pro mini, trouver le bon emplacement des nrf24l01 par rapport aux Arduinos afin de limiter les perturbations et garder une portée suffisante.

Merci pour votre aide.
Cordialement.
Christian

Step 4- ajouter le NULL '\0' c'est fait mais je ne saisi pas pourquoi il est important de l'ajouter.
Est-ce pour indiquer qu'il s'agit de la fin du message ?

non le message c'est tout ce qu'on envoie. par contre si dans la chaîne de réception il n'y a pas un '\0' à la fin et que vous essayez de faire de bidouille avec alors ça peut mal tourner

(si votre NRF reste alimentée alors de nouveaux gains d'énergie sur l'Arduino ne sont pas super pertinents..)