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

[Programmation] La gestion de Fonction
HVDifusion
Débutant
Débutant
Messages : 43
Enregistré en : décembre 2015

#1 Message par HVDifusion » lun. 25 juil. 2016 22:59

Bonjour,

J'ai un projet a faire pour quelqu'un.

Je vais expliqué son but en bref et de façons compréhensible car c'est pas si facile.

Je doit créer un module qui doit check un contacte libre de potentielle qui est actionné via du 24V d'une chaîne de production.

Le module doit remplir certaine condition :

-Si le contacte est maintenu,le programme est en veille.

-Si le contacte n'est plus détecté,il temporise 15 min avant d'enclenché une alarme qui va durée 3 min.

-Si le contacte ne fait qu'une impulsion,le programme se met en pause 1h,mais si il il se maintien a nouveau ben sa repasse en veille permanente bien sur.

J'ai commencé a faire le début qui consiste a faire la tempos de 15 minute puis 3 minute avec l'alarme.Ici dans le programme il n'est question que de détecté le contacte ou non (je programmerais l'impulsion plus tard).

Code : Tout sélectionner

// Definition PORTB Pin
#define VoltCheck PORTB.B2
#define Signal PORTB.B1

// Set Variable
bit alarme;
unsigned long int time;
unsigned int seconde;

void interrupt()
{
 if (INTCON.T0IF == 1)  // If TMR0 Overflowing
 {
  INTCON.T0IF = 0;  // Set Flag 0
  time++; // 10ms time incrémente
  TMR0 = 98; // Set TMR0 98 start value
 }
}

void Time15min()
{
 seconde = 0;
 time = 0;
 
 while(seconde <= 3)
 {
  if (time == 100 ) // set 1000ms
  {
   time = 0;
   seconde++;
  }
 }
}

void Time3min()
{
 seconde = 0;
 time = 0;
 
 while(seconde <= 3)
 {
  if (time == 100) // set 1000ms
  {
   time = 0;
   seconde++;
  }
 }
}

void main()
{
 // Set Register Bank
 INTCON = 0b10110000; // Enable all INT and INT TOIE,INTE
 PORTB = 0; // Initialisation 0V
 TRISB = 0b00000101; // Set RB0 and RB2 Input
 OPTION_REG = 0b11001101; // Pull-up Off,rising,Presc ON select 1:64
 PCON.B3 = 1; // 4Mhz oscillator

// Initialisation Variable
alarme = 0;
time = 0;
seconde = 0;

TMR0 = 98; // Set TMR0 98 start value

 while(1)
 {
  if (VoltCheck == 1)
  {
   Signal = 0;
   alarme = 0;
   seconde = 0;
   time = 0;
  }
 
  if (VoltCheck == 0)
  {
   Time15min();
   alarme = 1;
   
   if (alarme == 0)
   {
    Signal = 0;
   }
   
   if (alarme == 1)
   {
    Signal = 1;
    Time3min();
    alarme = 0;
   }
  }
 }
}


On remarque que j'ai activé le TIMER0 et je l'ai régler comme suit.Fosc/4=1us * 157 (TMR0 débute a 98 et non de 0),celas donne 157 us * un prescal de 64 donc 1048 us soit 10ms par débordement du TMR0.

J'ai créer 2 fonction qui sont sensée gérer chaque tempos différente.Je note une while tant que la variable Seconde est inférieure ou égale a 3.

Dans cette while vous remarquer l'incrémentation de la variable Seconde grâce a la variable timer qui est elle incrémentée toute les 10ms par le TMR0.

Pour infos j'ai mit 300 pour 3000ms car c'est plus rapide pour voir si sa fonctionne en teste,que d'attendre les 15 min ect.

Dans le main j'utilise des condition suivant l'étant de la broche d'entrée RB1 (VoltAlert) qui permet suivant son état d'appeler la fonction 15 minute et ensuite d'incrémenter la variable alarme qui suivant son état active RB2 (Signal) pour activé la sirène pendant 3 minute.

Sauf que la sirène s'enclenche tous de suite après que le contacte soit rompu.J'ai cherche je ne vois pas ce que je fait de mal,j'ai l'impression que ma méthode de la fonction n'est pas possible a faire comme je l'ai fait.

Qu'en pensez vous.

Ceci est assez long donc prenez votre temps pour me répondre,pas de soucis.

Cordialement.
Modifié en dernier par HVDifusion le lun. 1 août 2016 17:31, modifié 3 fois.

[Programmation] La gestion de Fonction
Claudius
Avatar de l’utilisateur
Passionné
Passionné
Messages : 260
Âge : 69
Enregistré en : septembre 2015
Localisation : ELANCOURT (78 - YVELINES)
Contact :

#2 Message par Claudius » lun. 25 juil. 2016 23:16

Bonsoir,

En 1ère analyse, je verrais un problème classique d'anti-rebond sur l'entrée VoltCheck ;-)
J'aurais commencer justement par gérer cette impulsion d'une durée maitrisée ;-))

A suivre...

[Programmation] La gestion de Fonction
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » mar. 26 juil. 2016 07:28

Bonjour HVDifusion,

je vais regarder ton programme ton programme ce matin ( je garde les enfants) .

Quel est ton type de PIC ( pourrait tu mettre la DS dans la case correspondante en éditant ton premier post : explication ).
Utilises-tu l'OSCINT ou un externe ? si externe, quelle est sa fréquence ?

J'ai pour habitude de ne jamais mettre de == pour comparer un compteur mais un <= ou >=, afin d'éviter ton bug ! Si pour une raison ou une autre ton PIC ne vois pas l’égalité , le comportement de celui-ci sera erroné .

quand tu parle d'impulsion c'est de quelle ordre de grandeur cette impulsion ( en temps) ? car comme le souligne Claudius il faudrait traiter les anti-rebonds si c'est un contact sec ! mais ne pas loupé l'impulsion de la chaine !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[Programmation] La gestion de Fonction
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#4 Message par Jérémy » mar. 26 juil. 2016 11:27

Sauf que la sirène s'enclenche tous de suite après que le contacte soit rompu

Code : Tout sélectionner

if (VoltCheck == 0)
  {
   
Time15min();
   
alarme 1;
   
   if (
alarme == 0)
   {
    
Signal 0;
   }
   
   if (
alarme == 1)
   {
    
Signal 1;
    
Time3min();
    
alarme 0;
   } 


dans cette partie de code si le contact est rompu , tu part faire ton attente de 15 min, et quand tu as fini l'attente, tu mets l'alarme à 1 .

et dans la foulée tu test si l'alarme est à 0 ou à 1 . comme tu viens de la mettre à 1 forcement elle se sera toujours à 1 dans ton test !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[Programmation] La gestion de Fonction
HVDifusion
Débutant
Débutant
Messages : 43
Enregistré en : décembre 2015

#5 Message par HVDifusion » mar. 26 juil. 2016 19:17

Jérémy a écrit :Source du message Utilises-tu l'OSCINT ou un externe ? si externe, quelle est sa fréquence ?


Osc interne régler a 4Mhz.

Jérémy a écrit :Source du message quand tu parle d'impulsion c'est de quelle ordre de grandeur cette impulsion ( en temps) ? car comme le souligne Claudius il faudrait traiter les anti-rebonds si c'est un contact sec ! mais ne pas loupé l'impulsion de la chaine !


Je n'ai effectivement pas de temps pour cette impulsion.

[Programmation] La gestion de Fonction
HVDifusion
Débutant
Débutant
Messages : 43
Enregistré en : décembre 2015

#6 Message par HVDifusion » mar. 26 juil. 2016 19:18

Jérémy a écrit :Source du message dans cette partie de code si le contact est rompu , tu part faire ton attente de 15 min, et quand tu as fini l'attente, tu mets l'alarme à 1 .

et dans la foulée tu test si l'alarme est à 0 ou à 1 . comme tu viens de la mettre à 1 forcement elle se sera toujours à 1 dans ton test !


Quand VoltAlert est égale a 1 il initiale alarme a 0,Signal a 0 également.

[Programmation] La gestion de Fonction
HVDifusion
Débutant
Débutant
Messages : 43
Enregistré en : décembre 2015

#7 Message par HVDifusion » mar. 26 juil. 2016 19:19

Claudius a écrit :Source du message En 1ère analyse, je verrais un problème classique d'anti-rebond sur l'entrée VoltCheck ;-)
J'aurais commencer justement par gérer cette impulsion d'une durée maitrisée ;-))


Tous a fait,tu me rappel que j'ai complètement négliger celas.

[Programmation] La gestion de Fonction
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#8 Message par Jérémy » mer. 27 juil. 2016 10:01

Hello,

Voila ma façon de faire.

NON TESTE

je créer un chronomètre sur INT . Ce chrono s’incrémente toute les secondes quand il est activé bien sur !
Suivant les drapeaux et la valeur du chrono on agit on NON !

Après 1 heure d'attente tu n'as pas précisé l'action à faire !
J'ai un doute sur ton PCON.B3 qui correspond en fait au paramètre de Power démarrage ou à un reset.

Pour reglé le TIMER0 j'ai utilisé ceci : Timer calculator

Après détection de checkvolt qui vérifie l'état du contact, j'ai fais une pause anti rebond de 10ms, suivit d'une deuxième pause pour voir si c'était une impulsion courte ou longue.
L'impulsion courte est réglée sur 200ms , au delà cela signifie une impulsion longue.

A toi de jouer !

Code : Tout sélectionner

/* date : 27/07/2016
Programme pour HVDifusion sur fantaspic.fr
MIKROC PRO 6.6.3
PIC :  http://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf
*/

//******************************************************************************
//****************************   NON TESTE   ***********************************
//******************************************************************************

// Definition PORTB Pin
#define VoltCheck PORTB.B2
#define Signal PORTB.B1

// Set Variable
unsigned int time, chrono, pause1heure, pause15minutes, alarme3minutes ;

void interrupt()
{
 if (INTCON.T0IF == 1)  // If TMR0 Overflowing
    {
      INTCON.T0IF = 0;  // Réarmement du flag
      TMR0 = 100;        // Offset du timer0
      time++;           // 10ms time incrémente
      if (time >= 100)  // 1 seconde d'écoulée
         {
            chrono++;   // On icrémente le chrono
            time = 0;   // On raz time
         }
    }
}

void main()
{
 PORTB = 0; // PORTB en digital
 TRISB = 0b00000101; // RB0 and RB2 en entrée
 
 PCON
.B3 = 1; // 4Mhz oscillator
  
 
// configuration TIMER0
  OPTION_REG = 0x85;
  TMR0 = 100;
  INTCON = 0x80;  // GIE activé,  l'INT timer0 n'est pas encore activée

// Initialisation Variable
pause1heure = pause15minutes = alarme3minutes= chrono = time = 0 ;

delay_ms (1000);

 while(1){

//------------------------------------------------------------------------------

    if (VoltCheck == 1)   // Contact maintenu
    {
       pause1heure = pause15minutes = alarme3minutes= chrono = time = 0 ;
       T0IE_bit = 0;  // On arrete le chrono
    }
    else
    
{
    
     delay_ms
(10);         // Pause antirebond
     
     if  
(VoltCheck==&& pause1heure==&& pause15minutes==0)
         {
           delay_ms(200);         // Pause detection d'impulsion
           if  (VoltCheck == 1)   // C'était juste une impulsion
               {
                 pause1heure = 1;       // On fait une pause d'une heure
               }
               else              // Le contact est toujours pas maintenu
               {
                 pause15minutes = 1;   // On attend 15 minutes
               }
           chrono = 0;
           time = 0;
           T0IE_bit = 1;          // On lance le chrono
         }
    }
  }
//-------------------------   ATTENTE 1 HEURE   --------------------------------
  if ( pause1heure == 1 && chrono >= 3600) // l'attente d'une heure est finie
  {
     pause1heure = 0;    // On arrete la pause dune heure
     // action à faire
     T0IE_bit = 0;  // On arrete le chrono
  }

//-------------------------   ATTENTE 15 MINUTES   -----------------------------
  if ( pause15minutes == 1 && chrono >= 900) // l'attente d'une heure est finie
  {
     pause15minutes = 0;    // On arrete la pause 15 minutes
     alarme3minutes = 1;    // On active l'alarme pour 3 minutes
     Signal = 1;            // On active l'alarme
     chrono = 0;            // RAZ du chrono
     time = 0;              // RAZ de l'offset
     T0IE_bit = 1;          // On lance le chrono
  }
  
//-------------------------   ATTENTE 3 MINUTES   ------------------------------
  if (alarme3minutes = 1 && chrono>=180) // au bout des trois minutes
     { 
       alarme3minutes 
= 0; // On arrete l'alarme des 3 minutes
       Signal = 0 ;   // On éteint l'alarme
       T0IE_bit = 0;  // On arrete le chrono
     }
 
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[Programmation] La gestion de Fonction
HVDifusion
Débutant
Débutant
Messages : 43
Enregistré en : décembre 2015

#9 Message par HVDifusion » mer. 27 juil. 2016 19:07

Hello,

Je vais check ton programme en détails et apprendre de mes erreurs,je te dit quoi.

Au sujet du Registre PCON si le Bit 3 permet la configuration de la fréquence de l'horloge regarde :

http://prntscr.com/by93dn

[Programmation] La gestion de Fonction
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#10 Message par Jérémy » mer. 27 juil. 2016 19:18

Oui j'avais vu, mais comme au dessus il parlait de la mise sous tension, je sais pas , c'était bizarre ! j'ai chercher le OSCCON ( Socillateur control) , mais il n'y en as pas sur ce PIC .

PS: c'est pas vrai le lien de la DS c'est barré, c'est pas encore au point mon truc. Tu peut me redonner le Type de PIC ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

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