Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino boucle ingérable

Sujet résolu
    17 mars 2019 à 17:52:13

    Bonjour tous le monde !! :)

    j'ai un  projet de communication ou le but est d'allumer une led a distance.

    j'utilise des modules nrf2401 et la librairie mirf.

    en m'aidant de plusieurs tuto j'ai réussi a faire (theoriquement) ce que je voulais faire.

    un arduino est en power down dès qu'une interruption a été faites sur la broche int0 il envoye une valeur au hasard (ici 10) et l'autre est censez être en ecoute constante et allumer la led si il recoit quelque chose.

    le 'bug?' est le même que l'arduino en power down soit éteint ou allumée ...

    1 -donc mon soucis actuellement se situe dans une boucle avec la condition d'attendre des données de la part du transmetteur...

    la boucle se termine directement alors que rien a été envoyé ! :(

    2- l'interrupteur est n permanence "vrai" alors qu'aucuncontact n'a été fait du coup la led s'allume 1 sec et s'éteint 1 sec ....

    sa fais 2 jours que je galere mais rien y fait, le programme est assez basique et je ne vois ou le problème ...

    code tarduino power down :

    #include <avr/sleep.h>
    #include <avr/power.h>
    #include <SPI.h>      // Pour la communication via le port SPI
    #include <Mirf.h>     // Pour la gestion de la communication
    #include <nRF24L01.h> // Pour les définitions des registres du nRF24L01
    #include <MirfHardwareSpiDriver.h> // Pour la communication SPI
    
    
     void ouicmoi() {
      
    }
    
    void sleep() {
     
        set_sleep_mode(SLEEP_MODE_PWR_DOWN)
        sleep_enable();
        attachInterrupt(0, ouicmoi, RISING);
        sleep_mode();
        sleep_disable();
        
    }
    
    
    void setup() {
      Serial.begin(9600);
      Mirf.cePin = 9; // Broche CE sur D9
      Mirf.csnPin = 10; // Broche CSN sur D10
      Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
      Mirf.init(); // Initialise la bibliothèque
    
      Mirf.channel = 20; // Choix du canal de communication (128 canaux disponibles, de 0 à 127)
      Mirf.payload = sizeof(int); // Taille d'un message (maximum 32 octets)
      Mirf.config(); // Sauvegarde la configuration dans le module radio
    
      Mirf.setTADDR((byte *) "nrf02"); // Adresse de transmission
      Mirf.setRADDR((byte *) "nrf01"); // Adresse de réception
     }
    
    void loop() {
       sleep();
      int message = 10;
     
    
     Mirf.send((byte*) &message);
       Serial.println("ok");
       while(Mirf.isSending()){} /
       Serial.println("ok");
       delay(100);
       
    }

    code arduino censé allumer la la led et l'éteindre grace a un interrupteur :

    #include <SPI.h>      // Pour la communication via le port SPI
    #include <Mirf.h>     // Pour la gestion de la communication
    #include <nRF24L01.h> // Pour les définitions des registres du nRF24L01
    #include <MirfHardwareSpiDriver.h> // Pour la communication SPI
    
    void setup() {
      Serial.begin(9600);
      Mirf.cePin = 9; // Broche CE sur D9
      Mirf.csnPin = 10; // Broche CSN sur D10
      Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
      Mirf.init(); // Initialise la bibliothèque
    
      Mirf.channel = 20; // Choix du canal de communication (128 canaux disponibles, de 0 à 127)
      Mirf.payload = sizeof(int); // Taille d'un message (maximum 32 octets)
      Mirf.config(); // Sauvegarde la configuration dans le module radio
    
      Mirf.setTADDR((byte *) "nrf01"); // Adresse de transmission
      Mirf.setRADDR((byte *) "nrf02"); // Adresse de réception
     
    }
    
    void loop() {
      pinMode(5,OUTPUT);
      pinMode(7,INPUT);
     
      Serial.println(test);
      
     Serial.println("in");
     
        digitalWrite(5,HIGH);
        test=5;
    delay(1000);
      while(test == 5){
         Serial.println("okkk");
         int t= digitalRead(7);
        if(t){
          digitalWrite(5,LOW);
          test=4;
          delay(1000);
          }
      }
      Serial.println("fin");
      while(!Mirf.dataReady()){ // C'est comme si cette boucle n'existait pas ! ...
      }
    }


    voila je crois avoir assez détaillé mon soucis, si vous avez des questions ou quoi qu'est-ce aucun soucis .....

    merci de votre réponse, et bonné journée ! :)

    -
    Edité par serakoc 17 mars 2019 à 18:32:37

    • Partager sur Facebook
    • Partager sur Twitter
      18 mars 2019 à 13:19:03

      tu es sur d'avoir bien compris le concept d'interruption ? tu ne fais absolument rien dans ton interruption.

      ensuite le second code est étrange,

      - test sert a quoi ?

      - pourquoi tu fais le pinMode dans le loop

      • Partager sur Facebook
      • Partager sur Twitter

      la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

      Mon GitHub

        18 mars 2019 à 16:47:06

        C'est pour éteindre la led sur la pin5(sortir de la boucle si la pin 7 vaut vrai)

        Le pin mode oui en effet pas besoin de la faire a achsue fois

        L'interruption sur int0??

        Merci de ta reponse

        • Partager sur Facebook
        • Partager sur Twitter
          18 mars 2019 à 17:01:14

          En fait ce qui me semble étrange , c'est que le code ne fait ce que j'ai compris de ta demande. Si j'ai bien compris tu as deux Arduino A et B, sur la Arduino A tu a un bouton et sur la B une led. Les Arduino A et B communiquent sans fil. C'est bien ça ?

          Qu'est-ce que tu veux mettre sur interruption ? le bouton, la led, la transmission  ?

          • Partager sur Facebook
          • Partager sur Twitter

          la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

          Mon GitHub

            18 mars 2019 à 19:02:46

            Si tu ne lis pas les données après la boucle, ça ne va pas réinitialiser les flags/interruptions du nrf24l01, donc Mirf.dataReady() va toujours renvoyer true et ta boucle sera ignorée.

            Tu dois soit, appeler Mirf.getData jusqu'à ce que les fifos du nrf soient vides (tant que Mirf.rxFifoEmpy() renvoie true), soit appeler Mirf.flushRX().

            • Partager sur Facebook
            • Partager sur Twitter
              18 mars 2019 à 22:36:58

              Alors merci de vos réponses,

              tout d'abord, ox :

              En me relisant c'est vrai que je n'ai pas été clair ! alors je m'explique mieux :

              arduino A :

              est constitué d'un bouton et d'un module nrf2401

              mon but est :

              de la relier par batterie(c'est pas encore d'actualité), donc une certaine economie d'energie s'impose, d'où le power_sleep_down;

              de ce que j'ai compris de cette fonction c'est que quand la fonction est active (donc arduino sous power down) il suffit avec RISING d'envoyer un courant a l'état haut pour que l'arduino s'allume et continue son code comme si de rien n'était . cad :

              instruction 1;

              instruction 2;

              fonction sleep();

              instruction 3;

              instruction 4;

              ainsi instruction 1&2 seront executés, ensuite fonction sleep, une fois qu'un courant a l'état haut a été envoyé sur int0(pin 2) l'arduino se réveil et les intructions 3&4 sont exécutés.

              quant à l'arduino B:

              est constitué d'un module nrf2401, d'un bouton et d'une led:

              son but :

              être en écoute constante, dès qu'elle reçoit quelque chose elle allume une led.

              la led reste allumée tant que la pin 7 n'est pas à l'état passant (via un bouton)

              test=5;
              delay(1000);
              while(test == 5){
                   Serial.println("okkk");
                   int t= digitalRead(7);
              
                   if(t){
                        digitalWrite(5,LOW);
                        test=4;
                        delay(1000);
                    }

              la boucle se répete donc tant que digitalRead(7) n'est pas à l'état haut (et donc ne vaut pas vrai);

              une fois que digitalRead(7) vaut vrai:

              on entre dans la condition if, on éteint la led et on modifie la valeur de test pour sortir de la boucle et retourner en écoute constante.

              alexisdm :

              je vais tester Mirf.flushRX() desuite j'edit pour te dire ce qu'il en ai.

              merci de vos réponse et bonne journée/ soirée à vous

              EDIT : alors j'ai essayer de faire un code un peu plus propre;

              ARDUINO A :

              #include <avr/sleep.h>
              #include <avr/power.h>
              #include <SPI.h>      // Pour la communication via le port SPI
              #include <Mirf.h>     // Pour la gestion de la communication
              #include <nRF24L01.h> // Pour les définitions des registres du nRF24L01
              #include <MirfHardwareSpiDriver.h> // Pour la communication SPI
              
              
               void ouicmoi() {
                byte message = 10;
                Serial.println("ok");
                Mirf.send(message); // Envoi du paquet
                Serial.println("ok1");
                while(Mirf.isSending()){} // tant que l'envoie est en cours
                Serial.println("ok2");
                delay(100);
              
              }
              
              void sleepPwrDown() {
                  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
                  sleep_enable();
                  attachInterrupt(0, ouicmoi, RISING);
                  sleep_mode();
                  sleep_disable();
              }
              
              
              void setup() {
                Serial.begin(9600);
                Mirf.cePin = 9; // Broche CE sur D9
                Mirf.csnPin = 10; // Broche CSN sur D10
                Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
                Mirf.init(); // Initialise la bibliothèque
              
                Mirf.channel = 20; // Choix du canal de communication (128 canaux disponibles, de 0 à 127)
                Mirf.payload = sizeof(byte); // Taille d'un message (maximum 32 octets)
                Mirf.config(); // Sauvegarde la configuration dans le module radio
              
                Mirf.setTADDR((byte *) "nrf02"); // Adresse de transmission
                Mirf.setRADDR((byte *) "nrf01"); // Adresse de réception
               }
              
              void loop() {
              sleepPwrDown();
              //ouicmoi();
              }

              ARDUINO B :

              #include <SPI.h>      // Pour la communication via le port SPI
              #include <Mirf.h>     // Pour la gestion de la communication
              #include <nRF24L01.h> // Pour les définitions des registres du nRF24L01
              #include <MirfHardwareSpiDriver.h> // Pour la communication SPI
              
              void setup() {
                Serial.begin(9600);
                Mirf.cePin = 9; // Broche CE sur D9
                Mirf.csnPin = 10; // Broche CSN sur D10
                Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
                Mirf.init(); // Initialise la bibliothèque
              
                Mirf.channel = 20; // Choix du canal de communication (128 canaux disponibles, de 0 à 127)
                Mirf.payload = sizeof(byte); // Taille d'un message (maximum 32 octets)
                Mirf.config(); // Sauvegarde la configuration dans le module radio
              
                Mirf.setTADDR((byte *) "nrf01"); // Adresse de transmission
                Mirf.setRADDR((byte *) "nrf02"); // Adresse de réception
                pinMode(5,OUTPUT);
                pinMode(7,INPUT);
              }
              
              void loop() {
                bool test;
                byte data[8];
                while(!Mirf.dataReady()){ // On attend de recevoir quelque chose
                Serial.println("on attend....");
                }
                digitalWrite(5,HIGH);
                test=true;
                while(test==true){
                 bool t= digitalRead(7);
                   if(t){
                    digitalWrite(5,LOW);
                    test=false;
                    }
                }
                while(Mirf.rxFifoEmpty()){
                  Serial.println("entrez dans fifo");
                  Mirf.getData((byte*) &data);
                  Serial.println("sa se vide ....");
                }
              }

              donc tout a l'air de bien fonctionner ; sauf que dès que l'interruption sur int0(arduino A) est faites l'envoie vers arduino B se fait sans probleme

              mais sur l'arduino B le serial se "bloque" sur le moniteur avec arduino b je vois donc au démarrage : "on attends ... " en boucle et sa se bloque quand elle reçoit quelque chose ....

              Y a t'il une erreur dans le code qui peut justifier sa ? :/

              merci de vos réponses ..!




              -
              Edité par serakoc 19 mars 2019 à 1:10:36

              • Partager sur Facebook
              • Partager sur Twitter
                19 mars 2019 à 7:54:24

                tu as un problème dans les setup, sizeof(byte) c'est egal à 1 alors que toi tu veux 8, je pense pas que ce soit ça le problème.

                Pour le reste je ne vois pas de problème, je me suis basé sur ce lien pour chercher.

                • Partager sur Facebook
                • Partager sur Twitter

                la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                Mon GitHub

                  19 mars 2019 à 12:04:28

                  Ce serait plutôt:
                  while(!Mirf.rxFifoEmpty()){

                  rxFifoEmpty() renvoie true si aucune donnée n'est présente dans la FIFO, et comme tu veux lire ces données dans la boucle afin de vider la FIFO, il faut la condition opposée.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 mars 2019 à 16:56:22

                    Alors Ox sizeof(byte) correspond a 8bit donc comme le message (10 ici) envoyer et reçu peut être coder sur 8bit (0 a 255 je crois) quand tu dis est égal à 1 je ne comprend pas ? :0

                    Alexis je teste sa

                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 mars 2019 à 17:14:57

                      sizeof ( byte ) = 8bits c'est 1 byte.

                      je te dis qu'il y a une incohérence car tu fais :

                      byte data[8]; 

                      ce qui fait 8 bytes soit 64bits ce qui est diffèrent de 1byte == 8 bits

                      -
                      Edité par ox223252 20 mars 2019 à 7:41:00

                      • Partager sur Facebook
                      • Partager sur Twitter

                      la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                      Mon GitHub

                        19 mars 2019 à 17:32:56

                        Ahhh oui exact ^^

                        j'ai modifier avec byte data; et sa fonctionne aussi gg

                        , donc j'ai un code prêt a l'emploi !

                        tout fonctionne nickel .!

                        merci a vous 2 les gars vous avez assurer ^^ :))

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Arduino boucle ingérable

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown