Radio-transmission d'un signal d'alarme avec NRF24L01+ et Attiny85
Répondre à la discussion
Affichage des résultats 1 à 3 sur 3

Radio-transmission d'un signal d'alarme avec NRF24L01+ et Attiny85



  1. #1
    michelcreuse

    Radio-transmission d'un signal d'alarme avec NRF24L01+ et Attiny85


    ------

    Bonjour à tous,

    je travaille sur un projet d’alarme d’évacuation à très basse consommation et d’un prix de revient peu élevé, dans lequel je fais intervenir des transmissions sans fil.
    Pour les transmissions radio, je souhaite utiliser le couple " microcontrôleur Attiny85-20PU et le module transducteur NRF24L01+ ".

    Description matériel:
    l’installation complète comprend plusieurs coffrets disposés chacun au centre d'une zone à protéger.
    Chaque coffret est distant l’un de l’autre de 20 à 30 mètres suivant les obstacles pouvant influencer la qualité des transmissions.
    Chaque coffret de protection de zone renferme :
    - Un déclencheur d’évacuation manuel: intégré ou déporté.
    - Une alarme d’évacuation type IV (NFS32-001).
    - Un module de transmission par radio à 2,4 GHz toujours en veille, ultra basse consommation.

    Fonctionnement:
    S’il faut, pour une raison valable, faire évacuer les personnes d’une zone devenue dangereuse:
    repérer et actionner le déclencheur manuel le plus proche.
    Lorsque celui-ci est actionné, il alimente en tension une broche déterminée de l’attiny85, créant ainsi un changement d’état de celle-ci.
    Au réveil du watchdog de l’attiny85 (programmé toutes les 2 secondes), celui-ci détecte le changement d’état de la broche et lance la suite du programme :
    a) d’une part envoie un signal "plus" pendant 10 secondes sur la boucle de l’alarme d’évacuation provoquant ainsi sa mise en route;
    b) d’autre part, le programme positionne le module en mode émetteur pour qu'il envoie un signal radio pendant 20 secondes aux récepteurs des coffrets environnants, repasse le module et le µC en mode réception puis en mode veille.
    Le récepteur de la zone mitoyenne ayant reçu le signal est réveillé à la fin du cycle du watchdog puis il exécute à son tour les mêmes opérations que celles effectuées par le coffret précédent et ainsi de suite jusqu’à ce que tous les coffrets installés soient en action.

    Besoin d'aide:
    Comme je m'y attendais, il ne fonctionne pas.
    Avant d'incriminer les librairies et notamment la dernière qui définie les caractéristiques des broches,
    j'aimerais que vous regardiez si je me suis trompé dans le raisonnement, ou dans la rédaction des instructions,
    ou fait une erreur idiote quelconque etc...

    Important! :
    Dans ce projet, l'émetteur n'a pas besoin de recevoir la confirmation de la bonne réception du message par le récepteur.
    Le récepteur (Attiny85) n'a pas non plus d'autres accessoires à gérer.

    ============oooooOOOOOOOOOOOOO ooooo============
    Voici le code complet:

    Code:
    /***************** TRANSMETTEUR POUR ALARME D'EVACUATION ********************
      L'ATtiny85 et le module radio sont normalement en mode sommeil.
      Au réveil du WDT, celui-ci détecte s'il y a changement d'état 
      du pin défini pour déclencher l'alarme.  
                            ** Hardware configuration **
                    pour moi, voir "Watchdog Timer et ATtiny85.docx"
                     ATtiny85 Pin map with CE_PIN 3 and CSN_PIN 4
                                      +-\/-+
                        NC ---| PB5  1|o   |8  Vcc --- |nRF24L01  VCC, pin2
        nRF24L01  CE, pin3 ---| PB3  2|    |7  PB2 --- |nRF24L01  SCK, pin5
        nRF24L01 CSN, pin4 ---| PB4  3|    |6  PB1 --- |nRF24L01 MOSI, pin7
        nRF24L01 GND, pin1 ---| GND  4|    |5  PB0 --- |nRF24L01 MISO, pin6
                                      +----+
    */
         #include "RF24.h"        
         #include "nRF24L01.h"
         #include <avr/sleep.h>
         #include <avr/power.h>   
         #include <avr/wdt.h>     
         byte compteur=40;     // émet 40 fois un signal d'alarme d'une durée de 0.5sec. soit un total d'env.:  20secondes.
     
         #ifndef cbi
         #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
         #endif
         #ifndef sbi
         #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
         #endif 
    
         #define CE_PIN 3
         #define CSN_PIN 4        
         int declencheur = 2;  // Déclare le déclencheur sur le pin 2 branché en commun avec SCK.
         int pinalarme = 0;    // pinalarme branché en commun avec MOSI (broche 5), pin 0 de l'attiny85.
         byte alarme;   
         volatile boolean f_wdt = 1;
    
    //*************  Configuration radio  *****************************/
       RF24 radio (CE_PIN, CSN_PIN);    //  RF24 radio(3,4);
       const byte rxAddr[6] = "01924";
    //*****************************************************************/
    
    void setup(void) 
    {
         pinMode(pinalarme,OUTPUT);
         pinMode(declencheur, INPUT_PULLUP);    // active pullup
         digitalWrite(declencheur,  LOW);  
         setup_watchdog(8);                               // en sommeil environ 4 secondes 
    }
    
    void emission()
    {
         delay(250);
         radio.begin();                       
         radio.setChannel(1);                 
         radio.setPALevel(RF24_PA_HIGH);        
         radio.setDataRate(RF24_250KBPS);     
         radio.setRetries(1,15);          
         radio.setCRCLength(RF24_CRC_8);  
         radio.openWritingPipe(rxAddr); 
         radio.stopListening();               
         delay(250);
    }
    
    void reception()
    {
         radio.begin();                        
         radio.setChannel(1);                 
         radio.setPALevel(RF24_PA_MIN);      
         radio.setDataRate(RF24_250KBPS);    
         radio.setRetries(15,15);               
         radio.setCRCLength(RF24_CRC_8);      
         radio.openReadingPipe(1,rxAddr);  
         radio.startListening();           
    }
         
    void alarme10s()    
    {   
         pinMode(pinalarme,OUTPUT);
         digitalWrite(pinalarme,HIGH);      // Envoie une tension interne de +3.7v pendant 10 sec. sur le pin 2
         delay(10000);                             // pour permettre le changement d'état de la boucle de l'alarme pour son déclenchement.
         digitalWrite(pinalarme,LOW);
         pinMode(pinalarme,INPUT);
    }
    
    void loop()
    {
    //******** Lecture des paquets qui arrivent au récepteur ********
      {
     if (f_wdt==1)    // attend la fin de la tempo du watchdog  
       { 
        f_wdt=0;        // reset flag
       }
        reception();    // positionne le prog. en mode réception.
        delay(100);     // Délai  pour permettre de bien se positionner.
       {
        radio.read(&alarme, 6);          
        delay(100);     // On attend pour lire correctement.
       }
      }  
    //******** Lecture de l'état du pin 2 pour définir l'action suivante à mener ********
      {
    //  val = digitalRead(declencheur); //  à utiliser si nécessaire, je ne sais pas.
      if (digitalRead(declencheur == HIGH))
       { 
        digitalWrite(declencheur, 1);
       } 
      if (digitalRead(declencheur == LOW))
       {
        digitalWrite(declencheur, 0); 
       }  
      }
    
    //****************** Traitement des informations *****************/
    //******** Si l'alarme est déclenchée:
    
      if (radio.available() || declencheur==1)                    
         delay(100);
      if (radio.available() || declencheur==1)  //  anti-rebond. 
      {
        {
             alarme10s();    // envoie un signe + pendant 10 sec. sur la pin 2
             delay(100);     // fait une pause avant de passer à l'étape suivante.
          {
    
    //********** Ecriture d'un déclenchement d'alarme vers les émetteur environnants ******
             emission();  // positionne le prog. en mode émission pour envoyer un signal pendant 20 sec.
             delay(100);  // fait une pause avant de passer à l'étape suivante.
          while (compteur>0)
            {
             delay(250);  // fait une pause
             radio.write("alarme", 6);   
             delay(250);  // fait une pause
             compteur=compteur-1;
            }
           compteur=40;
          }
    //********** Le programme se positionne en Mode réception et s'endort. 
             reception();    // le prog. se positionne en mode réception.
             delay(100);     // fait une pause
             system_sleep(); // l'ensemble s'endort
        }                            
      }
    
      //********* Si l'alarme n'a pas été déclenchée: Mode réception et s'endort.
      if ( !radio.available() && declencheur==0)
         delay(100);
      if ( !radio.available() && declencheur==0)  //  anti-rebond.
          {
            reception();    // le prog. se positionne en mode réception.
            delay(100);     // fait une pause
            system_sleep();
          }
    }
    
    /* Système de jeu dans l'état de sommeil
    Système se réveille quand le watchdog est dépassée*/
    
    void system_sleep() 
    {
          cbi(ADCSRA,ADEN);      // switch Analog to Digitalconverter OFF
          power_all_disable ();  // power off ADC, Timer 0 and 1, serial interfacesleep_enable();
          radio.powerDown();     //arrêt de l’alimentation du module nrf24l01+ 
          set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
          sleep_enable(); 
          sleep_mode();          // Système dort ici
          sleep_disable();       // Système continue l'exécution ici quand chien de garde a terminé
          radio.powerUp();       // réalimente le module nrf24l01+
          power_all_enable();    // power everything back on
          sbi(ADCSRA,ADEN);      // commutateur analogique à Digitalconverter ON
    }
    
    /* 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
       6=1 sec,7=2 sec, 8=4 sec, 9= 8sec*/
    
    void setup_watchdog(int ii) 
    {
         byte bb;
         int ww;
         if (ii > 9 ) ii=9;
         bb=ii & 7;
         if (ii > 7) bb|= (1<<5);
         bb|= (1<<WDCE);
         ww=bb;
      #if defined( __AVR_ATtinyX5__ )
        MCUSR &= ~(1<<WDRF);
    // commencer séquence cadencée
         WDTCR |= (1<<WDCE) | (1<<WDE);
    // définir une nouvelle valeur de temporisation du watchdog
         WDTCR = bb;
         WDTCR |= _BV(WDIE);
      #endif
    }
    
    // la détection de l'émetteur est exécutée lorsque la surveillance du watchdog a expiré.
        ISR(WDT_vect) 
    {
        f_wdt=1;  // reset du watchdog
    }
    En vous remerciant par avance pour le temps que vous allez me consacrer,
    je vous dis à bientôt
    michel

    -----

  2. #2
    invite60c6fa7f

    Re : Radio-transmission d'un signal d'alarme avec NRF24L01+ et Attiny85

    Bonjour Michel,

    Concrètement, sans savoir ce qui ne fonctionne pas, pas grand chose à dire.

    2 points toutefois:

    - L'attiny ne possède-il pas une interrupt-on-change, capable de le sortir du mode sleep au changement d'état d'une broche. Plutôt que de le réveiller cycliquement pour "poller" ladite broche?

    - Es-tu sur qu'en mode sleep le module RF est capable de se réveiller tout seul? Je pense qu'il doit être réveillé, et en mode réception pour être capable de recevoir quoi que ce soit (et l’interpréter).

    Edit: ok, il est mis en route cycliquement par le watchdog.

  3. #3
    michelcreuse

    Re : Radio-transmission d'un signal d'alarme avec NRF24L01+ et Attiny85

    Bonsoir à tous,

    J'ai essayé de comprendre ligne par ligne, j'ai téléchargé la dernière librairie
    RF24, puis j'ai recherché pour trouver pourquoi les pins CE,CSN,SCK,MOSI et MISO sont en position haute.
    Je n'ai rien trouvé.
    Ensuite, j'ai suivi le conseil de "r4ph" donc dans le programme, j'ai changé de méthode pour déclencher l'alarme.
    Maintenant j'ai opté pour le changement d'état de la pin SCK.
    Il m'a été confirmé qu'il faudrait que CE soit à "0" pour travailler avec les broches connectées au module NRF24,
    ce qui ne semble pas être le cas.
    Pour tester sous tension les broches du µC, j'ai pris une led connectée au moins que j'ai baladée sur CE, CSN, SCK qui se sont allumées franchement., par contre MISO émet des petits éclats et MOSI s'allume faiblement, en fait rien ne fonctionne.
    Dans le programme je ne sais pas ce qu'il faut mettre entre les parenthèses de " ISR (PCINT0_vect)".

    Voici mon nouveau code modifié:

    Code:
    /***************** TRANSMETTEUR POUR ALARME D'EVACUATION ********************
         L'ATtiny85 et le module radio sont normalement en mode sommeil.
       Réveil par détection d'un changement d'état de la broche n°7 ==> SCK 
                     la broche n°5 ==> MOSI envoie le signal d'alarme.  
                            ** Hardware configuration **
                    pour moi, voir "Watchdog Timer et ATtiny85.docx"
                     ATtiny85 Pin map with CE_PIN 3 and CSN_PIN 4
                                      +-\/-+
                        NC ---| PB5  1|o   |8  Vcc --- |nRF24L01  VCC, pin2
        nRF24L01  CE, pin3 ---| PB3  2|    |7  PB2 --- |nRF24L01  SCK, pin5
        nRF24L01 CSN, pin4 ---| PB4  3|    |6  PB1 --- |nRF24L01 MOSI, pin7
        nRF24L01 GND, pin1 ---| GND  4|    |5  PB0 --- |nRF24L01 MISO, pin6
                                      +----+
    */
         #include "SPI85.h"
         #include "RF24.h"       
         #include <avr/interrupt.h>
         #include <avr/io.h>
         #include <avr/sleep.h>
         #include <avr/power.h>   
         byte compteur=40;     // émet 40 fois un signal d'alarme d'une durée de 0.5sec. soit un total d'env.:  20secondes.
     
         #ifndef cbi
         #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
         #endif
         #ifndef sbi
         #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
         #endif 
    
         #define CE_PIN 3
         #define CSN_PIN 4        
         const byte pinalarme = 0;    // pinalarme branché en commun avec MOSI (broche 5), pin D0 de l'attiny85.
         const byte declencheur = 2;  // declencheur branché en commun avec SCK (broche 7), pin D2 / PCINT2.
    
         ISR (PCINT0_vect) 
         {
           // faire quelque chose d'intéressant ici...    "OUI MAIS FAIRE QUOI???"
         }
         byte alarme;   
    
    //*************  Configuration radio  *****************************/
       RF24 radio (CE_PIN, CSN_PIN);    //  RF24 radio(3,4);
       const byte rxAddr[6] = "01924";
    //*****************************************************************/
    
    void setup(void) 
    {
         pinMode(pinalarme,OUTPUT);
         pinMode(declencheur, INPUT_PULLUP);    // active pullup
         // changement de broche d'interruption (exemple pour D2)
         PCMSK  |= bit (PCINT2);  // veulent broche D2 / broche 7
         GIFR   |= bit (PCIF);    // effacer toutes les interruptions en suspens
         GIMSK  |= bit (PCIE);    // permettre le changement de broches interruptions
    }    // Fin de setup
    
    
    void emission()
    {
         delay(250);
         radio.begin();                       
         radio.setChannel(1);                 
         radio.setPALevel(RF24_PA_HIGH);        
         radio.setDataRate(RF24_250KBPS);     
         radio.setRetries(1,15);          
         radio.setCRCLength(RF24_CRC_8);  
         radio.openWritingPipe(rxAddr); 
         radio.stopListening();               
         delay(250);
    }
    
    void reception()
    {
         radio.begin();                        
         radio.setChannel(1);                 
         radio.setPALevel(RF24_PA_MIN);      
         radio.setDataRate(RF24_250KBPS);    
         radio.setRetries(15,15);               
         radio.setCRCLength(RF24_CRC_8);      
         radio.openReadingPipe(1,rxAddr);  
         radio.startListening();           
    }
         
    void alarme10s()    
    {   
         pinMode(pinalarme,OUTPUT);
         digitalWrite(pinalarme,HIGH);      // Envoie une tension interne de +3.7v pendant 10 sec. sur le pin 2
         delay(10000);                      // pour permettre le changement d'état de la boucle de l'alarme pour son déclenchement.
         digitalWrite(pinalarme,LOW);
         pinMode(pinalarme,INPUT);
    }
    
    void loop()
    {
    //******** Lecture des paquets qui arrivent au récepteur ********
        reception();    // positionne le prog. en mode réception.
        delay(100);     // Délai  pour permettre de bien se positionner.
        radio.read(&alarme, 6);          
        delay(100);     // On attend pour lire correctement.
    //******** Lecture de l'état du pin 2 pour définir l'action suivante à mener ********
        pinMode(declencheur, INPUT_PULLUP);   // active pullup et pin en entrée 
      if (digitalRead(declencheur) == HIGH) 
       {
        pinMode(declencheur, OUTPUT);    // il faut mettre le déclencheur en sortie !
        digitalWrite(declencheur, 1);   
       }
      if (digitalRead(declencheur) == LOW) 
       {
        pinMode(declencheur, OUTPUT);    // il faut mettre le déclencheur en sortie !
        digitalWrite(declencheur, 0); 
       }
    //****************** Traitement des informations *****************/
    //******** Si l'alarme est déclenchée:
    
      if (radio.available() || declencheur==1)                    
           {delay(100);}
      if (radio.available() || declencheur==1)  //  anti-rebond. 
        {
             alarme10s();    // envoie un signe + pendant 10 sec. sur la pin 2
             delay(100);     // fait une pause avant de passer à l'étape suivante.
    //********** Ecriture d'un déclenchement d'alarme vers les émetteur environnants ******
             emission();     // positionne le prog. en mode émission pour envoyer un signal pendant 20 sec.
             delay(100);     // fait une pause avant de passer à l'étape suivante.
          while (compteur>0)
            {
             delay(250);  // fait une pause
             radio.write("alarme", 6);   
             delay(250);  // fait une pause
             compteur=compteur-1;
            }
             compteur=40;
    //********** Le programme se positionne en Mode réception et s'endort. 
             reception();    // le prog. se positionne en mode réception.
             delay(100);     // fait une pause
             system_sleep(); // l'ensemble s'endort
         }                            
    //********* Si l'alarme n'a pas été déclenchée: Mode réception et s'endort.
      if ( !radio.available() && declencheur==0)
            {delay(100);}
      if ( !radio.available() && declencheur==0)  //  anti-rebond.
          {
            reception();    // le prog. se positionne en mode réception.
            delay(100);     // fait une pause
            pinMode(declencheur, INPUT_PULLUP);   // active pullup et pin en entrée
    //digitalWrite(pinalarme,LOW);
            system_sleep();
          }
     }
    
    /* Système se réveille quand changement d'état */
    void system_sleep() 
    {
          cbi(ADCSRA,ADEN);      // switch Analog to Digitalconverter OFF
          power_all_disable ();  // power off ADC, Timer 0 and 1, serial interfacesleep_enable();
          radio.powerDown();     //arrêt de l’alimentation du module nrf24l01+ 
          set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
          sleep_enable(); 
          sleep_mode();          // Système dort ici
          sleep_disable();       // Système reprend l'exécution ici
          radio.powerUp();       // réalimente le module nrf24l01+
          power_all_enable();    // power everything back on
          sbi(ADCSRA,ADEN);      // commutateur analogique à Digitalconverter ON
    }
    Décidément j'ai encore besoin d'aide, j'aimerai bien en finir avec ce projet.
    Je ne pensais pas que ce serait aussi fastidieux.
    En tous cas j'apprends beaucoup de choses et c'est plutôt passionnant.
    Merci par avance,
    michel

Discussions similaires

  1. nrf24l01+ avec pic 18f2520
    Par invitea5db0ae5 dans le forum Électronique
    Réponses: 28
    Dernier message: 14/08/2014, 22h42
  2. Générer un petit PWM avec un ATTINY85
    Par invite9e96eb3a dans le forum Électronique
    Réponses: 3
    Dernier message: 26/05/2013, 22h33
  3. transmission par radio
    Par invite18cef08f dans le forum Électronique
    Réponses: 13
    Dernier message: 21/03/2011, 08h43
  4. Réponses: 15
    Dernier message: 07/08/2010, 15h00
  5. [Blanc] Problème signal radio avec telecommande porte de garage BFT
    Par invite69fb3fe1 dans le forum Dépannage
    Réponses: 2
    Dernier message: 27/09/2009, 18h40
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...