Pages: [1]   Go Down
Author Topic: [AIDE] Utilisation de plusieurs boucles infinies  (Read 1145 times)
0 Members and 1 Guest are viewing this topic.
Haute Normandie
Offline Offline
Full Member
***
Karma: 1
Posts: 139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut tout le monde !

Voila j'ai un petit problème ou plutôt une petite question car mon code fonctionne parfaitement en l'état.

Dans le cadre de mon projet de lampe murale j'utilise une télécommande IR qui permet de sélectionner une couleur ou un mode de fonctionnement.

Actuellement j'utilise les interruptions matériels sur la broche 2 afin de décoder la trame issue de la télécommande, ce n'est pas le code envoyer que je lit mais un codage maison basé sur la durée des pulses, j'ai analysé les durées en affichant un tableau contenant les pulses recoltées et j'ai pu en déduire la durée de la pulse de début d'émission et le nombre de pulses sur une trame, je ne sais pas si cela marche sur toutes les télécommandes mais je pense, le but ici était de disposer d'un code unique propre a chaque bouton appuyé, je me fiche de la valeur exacte envoyé.

Avantage pas d'interruption permanente comme avec la librairie IRremote qui vient lire toutes le 50us la broche sur laquelle est relié le récepteur, donc gain de temps machine énorme, puisque quand il n'y a pas de signal IR mon arduino ne s'en occupe pas.

Mon problème est le suivant, j'utilise un SWITCH CASE pour agir en fonction de chaque bouton préssé, cependant je voulais savoir si il existait une astuces pour pouvoir sortir de mon SWITCH CASE sur un fonction contenant un WHILE(1){} en effet j'aimerais éviter de repasser par la boucle loop et encore un SWITCH CASE comme mon programme actuel et partir dans une fonction qui s'occupe en permanence du mode pour lequel elle est dédier.

J'ai essayé dans mon SWITCH, la première commande est bien prise en compte mais par la suite mon programme ne sort pas de la boucle et la télécommande ne répond plus, je me doute que cela est du au fait que le BREAK du SWITCH qui est situé juste après la fonction qui tourne en boucle n'est pas exécuté.

Auriez vous une solution pour partir de mon SWITCH CASE vers différentes fonction qui tournent en boucle en fonction du mode choisi ?

Voici mon code allégé avec la partie qu'il m'intéresse de modifier. Il fonctionne mais il passe par la fonction loop et un SWITCH CASE :
Code:
//-------------------------------------------------------------------------------------------------------------------------------
// Variables correspondantes aux différents boutons de la télécommande
//-------------------------------------------------------------------------------------------------------------------------------
const long Bouton_1  = 0x2A22808A;
const long Bouton_2  = 0x2A20808A;
//-------------------------------------------------------------------------------------------------------------------------------
// Variables utilisées pour la réception d'une trame infrarouge
//-------------------------------------------------------------------------------------------------------------------------------
volatile      int compteurdepulse = 0;
volatile      int tempsdepulse    = 0;
volatile      int tempsactuel     = 0;
volatile      int tempsprecedent  = 0;
volatile      int pret            = 0;
volatile      int tramerecue      = 0;
volatile      int etatpulse       = 0;
volatile long int valeurIR        = 0;
//-------------------------------------------------------------------------------------------------------------------------------
// Variables utilisées pour les différents mode
//-------------------------------------------------------------------------------------------------------------------------------
int modeaffichage = 0;
//-------------------------------------------------------------------------------------------------------------------------------
// Paramétrage de l'arduino
//-------------------------------------------------------------------------------------------------------------------------------
void setup(){
    Serial.begin(57600);
    pinMode(2, INPUT);
    attachInterrupt(0,ReceptionSignalIR,CHANGE);
}
//-------------------------------------------------------------------------------------------------------------------------------
// Fonction principale
//-------------------------------------------------------------------------------------------------------------------------------
void loop(){
    if(tramerecue){ AnalyseTrameIR(valeurIR); }
    switch(modeaffichage){
       case 0 :
            ModeCouleurUnique();
            break;
        case 1 :
            ModeTransitionCouleur();
            break;
        default:
            break;
    }
   
}
//-------------------------------------------------------------------------------------------------------------------------------
// Fonction qui affiche une couleur unique sur toutes les LED
//-------------------------------------------------------------------------------------------------------------------------------
void ModeCouleurUnique(){
    Serial.println("Mode Couleur Unique");
}
//-------------------------------------------------------------------------------------------------------------------------------
// Fonction qui effectue une transition de couleur sur les 6 LED
//-------------------------------------------------------------------------------------------------------------------------------
void ModeTransitionCouleur(){
    Serial.println("Mode Transistion De Couleur");
}
//-------------------------------------------------------------------------------------------------------------------------------
// Analyse la valeur reçue et agit en fonction du bouton qui a été appuyé
//-------------------------------------------------------------------------------------------------------------------------------
void AnalyseTrameIR(long boutonappuye){
    tramerecue = 0;
    switch (boutonappuye) {
        case Bouton_1 :
            Serial.println("Bouton 1");
            modeaffichage = 0;
            break;
        case Bouton_2 :
            Serial.println("Bouton 2");
            modeaffichage = 1;
            break;
        default:
            break;
    }
}
//-------------------------------------------------------------------------------------------------------------------------------
// Routine d'interruption pour le decodage d'un signal IR
//-------------------------------------------------------------------------------------------------------------------------------
void ReceptionSignalIR(){
    tempsactuel = micros();
    tempsdepulse = abs(tempsactuel - tempsprecedent);
    if(tempsdepulse > 8800 && tempsdepulse < 9200){
        pret = 1;
        compteurdepulse = 0;
    }
    if(pret == 1){
        if (tempsdepulse > 1000 ) etatpulse = 1;
        else etatpulse = 0;
        if(compteurdepulse >= 36){
            valeurIR ^= etatpulse;
            valeurIR <<= 1;
            if(compteurdepulse > 66){
                tramerecue = 1;
                pret = 0;
            }
        }
    }
    compteurdepulse++;
    tempsprecedent = micros();
}


 
Logged

Rien ne sert de chercher à tout savoir, mieux vaut savoir où tout chercher

Orleans
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Macbidouilleur
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour, une idée un peu en vrac comme ca :

Dans ton interruption tu mets 1 valeur dans ta variable modeaffichage en fonction du bouton


et dans ton loop tu fait un truc genre


while modeaffichage==1
      faire des trucs

while modeaffichage==2
      faire d'autre trucs


etc.

comme ça chaque fois que tu sort de l’interruption comme la variable a changé, par extension tu va sortir de tes boucles "affichage x" a l’itération suivante.


(je sait pas si j'ai bien expliqué ma pensée)
Logged


Bretagne
Offline Offline
Edison Member
*
Karma: 10
Posts: 1294
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dans le même esprit, j'utilise de temps à autre des boucles infinies, mais au lieu de faire while(1){}, je fais tourne=true; while(tourne){} et une interruption (réception IR dans ton cas) qui aurait comme fonction de sortir de la boucle ferait simplement tourne = false;, ainsi, le while n'est plus vérifié, donc s'arrête...
Logged

Haute Normandie
Offline Offline
Full Member
***
Karma: 1
Posts: 139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui, j'y avais pensé mais j'aurais préférer décomposer mon programme avec différentes fonctions qui ont une fonction bien précise et qui tourne avec un while(1) tant qu'il n'y a pas d'interruptions plutôt que de tout balancer a la suite dans le loop.
Logged

Rien ne sert de chercher à tout savoir, mieux vaut savoir où tout chercher

Bretagne
Offline Offline
Edison Member
*
Karma: 10
Posts: 1294
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alors je te donne un bout de code, fonctionBoucle est la fonction que tu appelles pour générer un truc qui tourne en boucle. j'ai rajouté une ligne magique en bas de la réception IR, dès la moindre réception IR, ton prog sortira de la boucle while. A toi d'arranger les choses, mais dans ton truc, je ne vois pas comment tu peux faire autrement...

Code:
volatile boolean tourne;

void fonctionBoucle(){
  switch (modeaffichage) {
    case 1 :
      tourne = true;
      while(tourne){

        // animations qui défilent, ici, on tourne en boucle...

      }
      break;
  }
}

//-------------------------------------------------------------------------------------------------------------------------------
// Routine d'interruption pour le decodage d'un signal IR
//-------------------------------------------------------------------------------------------------------------------------------
void ReceptionSignalIR(){
    tempsactuel = micros();
    tempsdepulse = abs(tempsactuel - tempsprecedent);
    if(tempsdepulse > 8800 && tempsdepulse < 9200){
        pret = 1;
        compteurdepulse = 0;
    }
    if(pret == 1){
        if (tempsdepulse > 1000 ) etatpulse = 1;
        else etatpulse = 0;
        if(compteurdepulse >= 36){
            valeurIR ^= etatpulse;
            valeurIR <<= 1;
            if(compteurdepulse > 66){
                tramerecue = 1;
                pret = 0;
            }
        }
    }
    compteurdepulse++;
    tempsprecedent = micros();

// ici la ligne magique :

    tourne = false;
}
void
Logged

Haute Normandie
Offline Offline
Full Member
***
Karma: 1
Posts: 139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, c'est le meilleur moyen que j'ai reussi a faire fonctionner mais ma télécommande a 44 boutons et mon SWITCH CASE risque de ressembler a une histoire sans fin.

Voici ma télécommande :

La solution que je vais retenir est donc la suivante :

Pour le choix d'une couleur , ou d'un fading ou d'un truc dans le genre qui ne demande pas un temps de réaction très rapide j'utiliserais un SWITCH CASE dans le loop, par contre pour faire réagir la lumière en fonction de la musique je placerais le code avec un WHILE comme tu viens de le montrer car pour être le plus sensible possible a la musique il faut que l'acquisition des données soit le plus rapide possible.

Je pensais qu'il devait bien exister une astuce avec genre une fonction break que l'on peut déporter dans une fonction ou bien en utilisant les pointeurs d'adresses choses qui me dépassent un peu car le break modifie une adresse en memoire pour dire au programme de retourner dans un endroit donc si j'avais pu définir cette endroit dans ma fonction avec le while(1) cela m'aurait permis d’exécuter le break du SWITCH CASE qui n'est pas exécuté.
Logged

Rien ne sert de chercher à tout savoir, mieux vaut savoir où tout chercher

Pages: [1]   Go Up
Jump to: