Découvrez notre nouvelle Chaîne YouTube "Ingénierie & Bourse"

Objectifs

  1. Savoir l’importance d’une temporisation bloquante
  2. Savoir déclencher une ou plusieurs temporisations non bloquantes
  3. Savoir utiliser la nouvelle fonction quickDelay()
  4. Etc.

Importance

Une temporisation non bloquante est très importante dans la commande des systèmes, la surveillance des défauts, le contrôle commande, etc. Elle est particulièrement intéressante pour la synthèse des actions temporisées, gestion du temps sans blocage de la boucle loop(). Contrairement aux fonctions delay() et delayMicroseconds()  qui bloquent le déroulement du programme, la nouvelle fonction quickDelay() déclenche une ou plusieurs temporisations avec une exécution rapide de la boucle principale.

Les caractéristiques de la fonction

  • Nombre de temporisateurs:  1-255
  • Résolution (LSB): 4 µS
  • Précision: ~1-2 LSB
  • Résolution binaire: 32 bits
  • Tempo Max: (2^32-1)*1µs: ~71,5827882667 Minutes

Voir le tuto pour plus de détails

La fonction quickDelay()

Définition

void quickDelay(unsigned long TimerX[][4],bool TimerCtrl[][3], byte NumTimer)

la fonction prend en entrée deux tableaux 2D (TimerX & TimerCtrl). Le premier tableau TimerX de taille Nx4 est dédié aux paramètres temporelles de la temporisation, le tableaux TimerCtrl de taille Nx3 pour les variables de contrôles. N étant le nombre de temporisations noté NumTimer. Ci-dessous la signification des champs des tableaux :

  • TimerX[X][0] : La durée du tempo en µS, à définir dans la fonction setup()
  • TimerX[X][1] : Le temps du début du tempo (variable interne à la fonction)
  • TimerX[X][2] : Le temps de la fin du tempo (variable interne à la fonction)
  • TimerX[X][3] : La valeur du tempo (incrémentation de 0 à TimerX[X][0] )

L’ensemble des paramètres du tableau TimerX sont accessibles en lecture à l’extérieure de la fonction. On peut à tout moment lire la valeur du tempo (TimerX[X][0] ), le temps du start/stop, etc.

 unsigned long Time_us =TimerX[NumTimer][0];

  unsigned long t_start =TimerX[NumTimer][1];

  unsigned long t_stop  =TimerX[NumTimer][2];

  unsigned long t_val   =TimerX[NumTimer][3];
  • TimerCtrl[X][0] : Activation/désactivation du tempo (true/false)
  • TimerCtrl[X][1] : Indicateur du lancement du tempo
  • TimerCtrl[X][2] : Signal d’expiration du tempo (Overflow). Ce paramètre est fondamental pour savoir quand ce qu’une temporisation est expirée. Le signal Overflow dure une itération de la boucle principale. Vous pouvez par exemple déclencher une action dès l’expiration du tempo, etc.

Voir le tuto pour plus de détails

  bool TimerEN      =TimerCtrl[NumTimer][0];

  bool TimerIsStart =TimerCtrl[NumTimer][1];

  bool TimerState   =TimerCtrl[NumTimer][2];

L’ensemble des paramètres du tableau TimerCtrl sont accessibles en lecture à l’extérieure de la fonction.

 unsigned long Time_us =TimerX[NumTimer][0];

  unsigned long t_start =TimerX[NumTimer][1];

  unsigned long t_stop  =TimerX[NumTimer][2];

  unsigned long t_val   =TimerX[NumTimer][3];

Déclaration

void quickDelay(unsigned long TimerX[][4],bool TimerCtrl[][3], byte NumTimer)
{
  unsigned long Time_us =TimerX[NumTimer][0];
  unsigned long t_start =TimerX[NumTimer][1];
  unsigned long t_stop  =TimerX[NumTimer][2];
  unsigned long t_val   =TimerX[NumTimer][3];
  
  bool TimerEN      =TimerCtrl[NumTimer][0];
  bool TimerIsStart =TimerCtrl[NumTimer][1];
  bool TimerState   =TimerCtrl[NumTimer][2];
  
  
  // Déclanchement du Timer  
  if((TimerEN==true) && (t_val==0))
  {
    // Lancement du Timer 
    t_start = micros(); 
    TimerIsStart=true;
    
    // Init de l'état du Timer
    TimerState=false;  
  }
  // Mise à jour de la valeur du Timer
  t_stop=micros(); 
  t_val=t_stop-t_start; 
  
  // Génération du Timer 
  if((TimerIsStart==true) && (t_val > Time_us))
  {
    TimerState = true; 
    t_val=0;  
  }

  // Arrêt du Timer
  if(TimerEN==false) 
  {
     
    t_start=0; 
    t_stop=0;
    TimerIsStart=false;
    TimerState=false; 
    t_val=0;  
  }
  // Mise à jour des valeurs du Timer 
  TimerX[NumTimer][0]=Time_us;
  TimerX[NumTimer][1]=t_start;
  TimerX[NumTimer][2]=t_stop;
  TimerX[NumTimer][3]=t_val;

  TimerCtrl[NumTimer][0]=TimerEN;
  TimerCtrl[NumTimer][1]=TimerIsStart;
  TimerCtrl[NumTimer][2]=TimerState;
}

Exemple d’utilisation de la fonction



#define N 255   // Déclaration de 3 Timers 
              // Nombre des Timers        1-255 (Mémoire)
              // Résolution (LSB)         4 µS
              // Précision                ~1-2 LSB
              // Résolution binaire       32 bits 
              // Tempo Max: (2^32-1)*1µs  ~71,5827882667 Heures

unsigned long TimerX[N][4]; 
bool TimerCtrl[N][3];    

bool StateLED=false;  

void setup() 
{
  // Définition des valeurs des tempos en µS 
  TimerX[0][0]=3000000;  // 3s
  TimerX[1][0]=5000000;  // 5s
  TimerX[2][0]=7000000;  // 7s

  // Désactivions des Timers par défaut 
  for(int i=0; i<N; i++) 
  {
    TimerCtrl[i][0]=false; 
    TimerX[i][3]=0;  
  }
 

  // Init port série 
  Serial.begin(9600); 
}

void loop() 
{
  // Lancement du Timer & Affichage 
  byte C; 
  C=0; TimerCtrl[C][0]=false; quickDelay(TimerX,TimerCtrl, C);
  C=1; TimerCtrl[C][0]=false; quickDelay(TimerX,TimerCtrl, C);
  C=2; TimerCtrl[C][0]=true; quickDelay(TimerX,TimerCtrl, C);
  
  // Mémorisation de l'état du Timer (Overflow)
  C=2;
  if(TimerCtrl[C][2]==true) 
  {
    // Inversion de l'état d'une LED par exemple :) 
    StateLED=!StateLED; 
  }


  // Affichage de la valeur & l’état du Timer 1 
  Serial.print((double)TimerX[0][3]*1E-6);  Serial.print( "\t");  
  Serial.print((double)TimerX[1][3]*1E-6);  Serial.print( "\t");
  Serial.print((double)TimerX[2][3]*1E-6);  Serial.print( "\t");
  //Serial.print( TimerCtrl[0][2]+3); Serial.print( "\t"); 
  //Serial.print( TimerCtrl[1][2]+5); Serial.print( "\t"); 
  //Serial.print( TimerCtrl[2][2]+7); Serial.print( "\t"); 
  Serial.println(StateLED);
}




void quickDelay(unsigned long TimerX[][4],bool TimerCtrl[][3], byte NumTimer)
{
  unsigned long Time_us =TimerX[NumTimer][0];
  unsigned long t_start =TimerX[NumTimer][1];
  unsigned long t_stop  =TimerX[NumTimer][2];
  unsigned long t_val   =TimerX[NumTimer][3];
  
  bool TimerEN      =TimerCtrl[NumTimer][0];
  bool TimerIsStart =TimerCtrl[NumTimer][1];
  bool TimerState   =TimerCtrl[NumTimer][2];
  
  
  // Déclanchement du Timer  
  if((TimerEN==true) && (t_val==0))
  {
    // Lancement du Timer 
    t_start = micros(); 
    TimerIsStart=true;
    
    // Init de l'état du Timer
    TimerState=false;  
  }
  // Mise à jour de la valeur du Timer
  t_stop=micros(); 
  t_val=t_stop-t_start; 
  
  // Génération du Timer 
  if((TimerIsStart==true) && (t_val > Time_us))
  {
    TimerState = true; 
    t_val=0;  
  }

  // Arrêt du Timer
  if(TimerEN==false) 
  {
     
    t_start=0; 
    t_stop=0;
    TimerIsStart=false;
    TimerState=false; 
    t_val=0;  
  }
  // Mise à jour des valeurs du Timer 
  TimerX[NumTimer][0]=Time_us;
  TimerX[NumTimer][1]=t_start;
  TimerX[NumTimer][2]=t_stop;
  TimerX[NumTimer][3]=t_val;

  TimerCtrl[NumTimer][0]=TimerEN;
  TimerCtrl[NumTimer][1]=TimerIsStart;
  TimerCtrl[NumTimer][2]=TimerState;
}

Augmenter la dynamique

Vous pouvez remplacer la fonction micros() avec millis() afin d’augmenter la durée maximale du tempo. En utilisant la fonction millis(), la durée passe du 71 minutes au 49.7 Jours! 

Sujets connexes

Accueil Programmation Arduino


0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Anti-Robot *

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.