Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

PIC12F508 machine à état et gestion du temps sans delay
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#11 Message par Jérémy » lun. 1 août 2016 23:07

switch(BTState)

Ici tu utilise un switch ? mais tu as seulement 2 cas de figures c'est plutot rare ! pour seulemetn deux cas de figure on utilise en général un IF/ELSE IF

GPIO4 est une entrée ? tu confirmes ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

PIC12F508 machine à état et gestion du temps sans delay
pickApick
Membre
Membre
Messages : 13
Enregistré en : août 2016

#12 Message par pickApick » lun. 1 août 2016 23:15

Jérémy a écrit :switch(BTState)

Ici tu utilise un switch ? mais tu as seulement 2 cas de figures c'est plutot rare ! pour seulemetn deux cas de figure on utilise en général un IF/ELSE IF

GPIO4 est une entrée ? tu confirmes ?

GPIO4 est bien une entrée. J'ai 2 autres cas de figures lorsque mon BT est ON je peux passer en pairing ou clearing mode. Par le biais de la détection d'un appui long ou appui cours sur GP3.
Pour récapituler:
GP1 passe de low à high => Front descendant sur 2s sur GP1 et GP5 passe à 0. (BTON)
GP1 passe de low à high => Front descendant sur 2s sur GP1 et GP5 passe à 1.(BT0FF)
Lorsque je suis en mode BTOn je peux en scrutant un appui long (sur GP3) rentrer en clearing mode. J'envoie alors une pulse sur front montant de 10s sur GP0.
Si appui court sur GP3 (pairing mode). J'envoie alors une pulse sur front descendant d'environ 200ms sur GP1 .

PIC12F508 machine à état et gestion du temps sans delay
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#13 Message par Jérémy » lun. 1 août 2016 23:34

Voici une ébauche , dans l'idée ce que ca donne !

A mon avis nous n'avons pas le même compilateur, donc à toi d'adapteur au besoin . Je n'ai pas tester la compilation !

Code : Tout sélectionner

////DÈfinition des commandes prÈprocesseurs
//#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//#include <time.h>
//#include <pic12f508.h>


#define XTAL_FREQ 4000000

// PIC12F508 Configuration Bit Settings
// CONFIG
#pragma config OSC = IntRC      // Oscillator Selection bits (internal RC oscillator)
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
#pragma config CP = ON          // Code Protection bit (Code protection on)
#pragma config MCLRE = OFF      // GP3/MCLR Pin Function Select bit (GP3/MCLR pin function is digital input, MCLR internally tied to VDD)


int main() {
     uint8_t chrono;
     uint8_t Temporaire;
     uint8_t Lancement;
     uint8_t synchro1;
     uint8_t synchro2;
    GPIO=0; //Mise à 0 des E/S
    GP1=1; //GP1 à 1 initialement
    TRISGPIO=0x18;     //Définition des ports E/S
    OPTION=0x08; // définition du timer TMR0 :4mHz/4 *256
    synchro1=1;
    static enum BTState//Définition des états désirés du BTH
    {
        BTOFF=0,
        BTON,
        PAIRING_MODE,
        CLEARING_MODE,

    }BTState=BTOFF;

Temporaire = GP4

while(1)
 {
    if (TMR0>=195)// Boucle permettant de gérer les durées TMR0>=250 ==> environ 50ms
       {
          TMR0 = 0;
          chrono++;   // On incremente notre compteur de 50ms
       }

    if ( (Temporaire != GP4) && (Lancement ==0) ) // Si GP4 à changé ET Lancement=0
                                                  // Alors on execute l'action correspondante à son nouvel état
       {
           Lancement = 1 ;  // On dit qu'on à placer le chrono pour deux 2 secondes
           GP1 = 0;         // On fait une pulse sur front descendant
           chrono = 0;      // On RAZ le chrono

           if ( GP4 == 1)  // GP4 est passé à l'état haut
              {
                GP5 = 0;
              }
           else if         // GP4 est passé à l'état bas
              {
                GP5 = 1;
              }
          Temporaire = GP4 // Mise à jour de la variable temporaire
       }

     if  ( (Lancement == 1) && (chrono >= 40) ) //Si le lancement de la tempo est en cours ET quele chrono arrive à deux secondes
         {
            Lancement = 0;
            GP1 =1;      // O,n replace GP à l'état haut
         }

 


Dans l'idée :

On créer un chrono qui s’incrémente toutes les 50ms . j'ai choisi 50ms, car c'est une base pour faire des multiples. Il faudrait reglé ce chrono pour obtenir la précision voulu , car il mettra un certains temps suivant la longueur du programme. Avec un programme court il tournera plus vite !

Ensuite un detecte si la broche GP 4 à changé ou non .
Quand elle change, on signale qu'on part pour une durée de 2s avec le flag "Lancement". on met GP1 à zero pour le front descendant. On Remet le chrono à zero.
Si l'état de GP4 est à l'état c'est donc un front montant de détecté, donc on met GP5 à zéro, sinon c'est un état bas , donc un front descendant et GP5 est mit à 1.
On n'oublie pas d'enregistrer la nouvelle valeur de GP4 dans temporaire.

Si le "Lancement" à été effectué ET que le chrono arrive à deux secondes, alors on RAZ le flag "lancement" et on remet GP1 à l'état haut !

Si j'ai bon, on continue !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

PIC12F508 machine à état et gestion du temps sans delay
pickApick
Membre
Membre
Messages : 13
Enregistré en : août 2016

#14 Message par pickApick » mar. 2 août 2016 10:52

J'ai modifié 2-3 trucs dans ton programme Jeremy. Surtout des oublies de points virgules et la condition else if (GP4==0) manquante.

Code : Tout sélectionner


int main
() {
     
uint8_t chrono;
     
uint8_t Temporaire;
     
uint8_t Lancement;
     
uint8_t synchro1;
     
uint8_t synchro2;
    
GPIO=0//Mise à 0 des E/S
    
GP1=1//GP1 à 1 initialement
    
TRISGPIO=0x18;     //Définition des ports E/S
    
OPTION=0x08// définition du timer TMR0 :4mHz/4 *256
    
synchro1=1;
    static 
enum BTState//Définition des états désirés du BTH
    
{
        
BTOFF=0,
        
BTON,
        
PAIRING_MODE,
        
CLEARING_MODE,

    }
BTState=BTOFF;

Temporaire GP4;

while(
1)
 {
    if (
TMR0>=195)// Boucle permettant de gérer les durées TMR0>=250 ==> environ 50ms
       
{
          
TMR0 0;
          
chrono++;   // On incremente notre compteur de 50ms
       
}

    if ( (
Temporaire != GP4) && (Lancement ==0) ) // Si GP4 à changé ET Lancement=0
                                                  // Alors on execute l'action correspondante à son nouvel état
       
{
           
Lancement ;  // On dit qu'on à placer le chrono pour deux 2 secondes
           
GP1 0;         // On fait une pulse sur front descendant
           
chrono 0;      // On RAZ le chrono

           
if ( GP4 == 1)  // GP4 est passé à l'état haut
              
{
                
GP5 0;
              }
           else if   (
GP4==0)      // GP4 est passé à l'état bas
              
{
                
GP5 1;
              }
          
Temporaire GP4// Mise à jour de la variable temporaire
       
}

     if  ( (
Lancement == 1) && (chrono >= 40) ) //Si le lancement de la tempo est en cours ET quele chrono arrive à deux secondes
         
{
            
Lancement 0;
            
GP1 =1;      // O,n replace GP à l'état haut
         
}

 } 
}

 


J'ai voulu simuler le tout avec MPLAB mais rien ne se passe donc je ne peux pas te dire pour le moment. Sinon cela me parait juste de mon point de vue. Et il y avait 2-3 trucs dont je n'avais pas pensé que tu as fait dans ton code et qui sont intéressant. Bon par contre dans l'état actuel on n'utilise pas la machine à état.

PIC12F508 machine à état et gestion du temps sans delay
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#15 Message par Jérémy » mar. 2 août 2016 11:59

Bonjour,

else if (GP4==0) manquante

Oups ce n'est pas else ifmais else tout court à mettre. Si GP4 n'est pas égale à 1 alors il est forcement à 0 ( pour le moment.

la machine à état.

Qu'entends tu par "machine état" ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

PIC12F508 machine à état et gestion du temps sans delay
pickApick
Membre
Membre
Messages : 13
Enregistré en : août 2016

#16 Message par pickApick » mar. 2 août 2016 12:13

la machine à état.

Qu'entends tu par "machine état" ?[/quote]

J'entends par machine à état les 4 états de mon pic BTON,BTOFF,PAIRINGMODE,CLEARINGMODE.

Code : Tout sélectionner


int main
() {
     
uint8_t temps;
     
uint8_t delay;
     
uint8_t synchro1;
     
uint8_t synchro2;
     
uint8_t temporaire;
     
uint8_t lancement;
    
GPIO=0;
    
GP1=1;
    
TRISGPIO=0x18;     
    
OPTION=0x08;
    
synchro1=1;
    static 
enum BTState
    
{
        
BTOFF=0,
        
BTON,
        
PAIRING_MODE,
        
CLEARING_MODE,
                
    }
BTState=BTOFF;
    
temporaire=GP4;
    while(
1)
    {
        if(
TMR0>=195)
        {
            
TMR0=0;
            
temps=temps+1;
        }
            
       switch(
BTState)
    {
           if((
lancement==1)&&(temps>=40))
            {
                
lancement=0;
                
GP1=1;
            }
           
        case 
BTOFF:    
    {
        if((
temporaire!=GP4)&&(lancement==0))
           {
               
lancement=1;
               
GP1=0;
               
temps=0;
               if (
GP4==1)
               {
                   
GP5=0;
                   
BTState=BTON;
                   
               }
               else if ((
GP4==0))
                {
                    
GP5=1;
                }
               
temporaire=GP4;
           }
           
            break;
        case 
BTON:
            
            if((
temporaire!=GP4)&&(lancement==0))
           {
               
lancement=1;
               
GP1=0;
               
temps=0;
               if (
GP4==1)
               {
                   
GP5=0;
                   
               }
               else if ((
GP4==0))
                {
                    
GP5=1;
                    
BTState=BTOFF;
                         
                            
                }
               
temporaire=GP4;
           }
            
            break;
            
            
               
    }
       }
    }
    

}




 


Voilà grosso modo ma machine à état avec ce que tu as fait avant. Après quelques tests il s'avère que je ne rentre jamais dans la boucle :

Code : Tout sélectionner

if((lancement==1)&&(temps>=40))
            {
                
lancement=0;
                
GP1=1;
            }




 


Ce qui fait que GP1 reste tout le temps à 0 .

PIC12F508 machine à état et gestion du temps sans delay
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#17 Message par Jérémy » mar. 2 août 2016 12:29

pickApick a écrit :Source du message if((lancement==1)&&(temps>=40))


Elle ne doit pas être traiter dans le switch case, mais en dehors .
Je pense que ta machine à état, embrouille plus qu'autre choses non ? ce n'est pas ma logique habituelle alors j'ai un peu de mal ! oops

L'idée c'est vraiment qu'a chaque boucle on check notre chrono pour voir ou on en ai .
ensuite on réagissi il se passe quelques chose !
Ici c'est si GP4 change d'état.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

PIC12F508 machine à état et gestion du temps sans delay
pickApick
Membre
Membre
Messages : 13
Enregistré en : août 2016

#18 Message par pickApick » mar. 2 août 2016 13:30

[/quote]

Elle ne doit pas être traiter dans le switch case, mais en dehors .
Je pense que ta machine à état, embrouille plus qu'autre choses non ? ce n'est pas ma logique habituelle alors j'ai un peu de mal ! oops
[/quote]

C'est bon je rentre bien dans la boucle il fallait la mettre en dehors du switch :bravo: . Je suis d'accord avec toi pour la machine à état mais ça me permet aussi d'essayer quelque chose de nouveau :wink: . Je me lance maintenant dans le cas du pairing et clearing mode. Je vais essayer de poster un code en fin de journée.

PIC12F508 machine à état et gestion du temps sans delay
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#19 Message par Jérémy » mar. 2 août 2016 13:47

Je travaille dessus ... :-D

Mais franchement, c'est quand même n'importe nawak de faire ca sans INT sur TIMER. les anti rebonds ne seront pas traités en plus . sinon ça complique encore !

J'ai bientôt finis je pense;
C'est en faisant des erreurs, que l'on apprend le mieux !!!

PIC12F508 machine à état et gestion du temps sans delay
pickApick
Membre
Membre
Messages : 13
Enregistré en : août 2016

#20 Message par pickApick » mar. 2 août 2016 13:55

Jérémy a écrit :Je travaille dessus ... :-D

Mais franchement, c'est quand même n'importe nawak de faire ca sans INT sur TIMER. les anti rebonds ne seront pas traités en plus . sinon ça complique encore !

J'ai bientôt finis je pense;


Je suis bien d'accord avec toi. De toute manière pour l'appui je vais faire un debounce pour gérer les anti rebonds.
Modifié en dernier par pickApick le mar. 2 août 2016 16:32, modifié 2 fois.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 106 invités