Code bloquant ou pas? Enchaînement des ordres.

Sommaire:
      Fonctionnement avec un ordre de temps en temps sans accélérations/décélérations
      Fonctionnement pour des ordres rapprochés, pile de un ordre
      Fonctionnement pour des ordres rapprochés, pile de plusieurs ordres
      Fonctionnement pour beaucoup d'ordres rapprochés, non bloquants
      Avec des accélérations et décélérations

 

Fonctionnement pour un ordre de temps en temps sans accélérations/décélérations

Voici comment fonctionne QuickStep. Il y a deux lignes de temps, celle du haut c'est votre programme (setup, loop, et vos autres fonctions). Le code peut être bloquant ou pas, cela n'a pas d'importance. En bas les actions de QuickStep qui se font grâce aux timer et qui vont interrompre, sans que vous le sachiez, votre code pour avancer. Attention ce n'est pas à l'échelle, l'avance d'un pas ne dure que quelques microsecondes:

... 1:
quickStep
Deplacement
AUTRE CHOSE 2:
quickStep
Deplacement
AUTRE CHOSE
1:
Pas
n°1
1:
Pas
n°2
1:
Pas
n°3
... 1:
Pas
n°N
2:
Pas
n°1
2:
Pas
n°2
2:
Pas
n°3
... Pas
n°N

En fait pendant que l'on avance d'un pas "Autre chose" est suspendu. Mais cela ne se voit pas.

Si on ne donne qu'un ordre de temps en temps, quickStepDeplacement() sans accélérations/décélérations n'est jamais bloquante

 

Fonctionnement pour des ordres rapprochés, pile de un ordre

Supposons que nous ayons fait le choix que la pile des ordres ne contient qu'une seule valeur utile soit 2 valeurs en tout (il y a une valeur qui est l'ordre d'arrêt), définie dans QuickStepConf.h ainsi:

#define ORDRES_TABLE 2 // Valeurs possibles 2, 4, 8, 16, 32, 64, 128 ou 256
ou même pas défini du tout (c'est la valeur par défaut). Si pendant que le moteur tourne, on donne plusieurs nouveaux ordres, il n'est pas possible de les exécuter immédiatement (il y en a un qui tourne), ni de les ignorer, ni de le mémoriser (table pleine). quickStepDeplacement() va donc attendre que l'ordre précédent soit fini. Dans ces conditions elle devient bloquante. Cela donne:

... 1:
quickStep
Deplacement
AUTRE
CHOSE
Attente dans
quickStep
Deplacement
2:
quickStep
Deplacement
Attente dans
quickStep
Deplacement
3:
quickStep
Deplacement
Attente dans
quickStep
Deplacement
1:
Pas
n°1
1:
Pas
n°2
1:
Pas
n°3
... 1:
Pas
n°N
2:
Pas
n°1
2:
Pas
n°2
2:
Pas
n°3
... 2:
Pas
n°N
3:
Pas
n°1
3:
Pas
n°2
3:
Pas
n°3
...

La fonction quickStepDeplacement est obligé d'attendre que pas n°N se termine, et ne peut continuer qu'au moment ou il y aurait pu y avoir un pas n°N+1 (il faut finir le temps de l'impulsion N et son temps inter-impulsion). quickStepDeplacement devient bloquante, et elle s'exécute entre les pas qui ne peuvent plus s'enchaîner.

Ce n'est pas forcément négatif. Ce peut être un résultat recherché. Par exemple si je veux informer de la progression, loop() peut ressembler à:

void loop()
{
  quickStepDeplacement1(pas[N], sens[N], tempsEntrePas[N]); // Lancer le mouvement n°N
  Serial.print("Je fais le mouvement n°"); Serial.println(N); // Information sur le mouvement
}
Tant que le mouvement en cours n'est pas fini, quickStepDeplacement1() attend et l'affichage n'a pas lieu. Cela fait le schéma:

... 1:
quickStep
Deplacement
Affichage Attente dans
quickStep
Deplacement
2:
quickStep
Deplacement
Affichage Attente dans
quickStep
Deplacement
3:
quickStep
Deplacement
Affichage Attente dans
quickStep
Deplacement
1:
Pas
n°1
1:
Pas
n°2
1:
Pas
n°3
... 1:
Pas
n°N
2:
Pas
n°1
2:
Pas
n°2
2:
Pas
n°3
... 2:
Pas
n°N
3:
Pas
n°1
3:
Pas
n°2
3:
Pas
n°3
...

 

Fonctionnement pour des ordres rapprochés, pile de plusieurs ordres

Si on veut pouvoir enchaîner les ordres les uns après les autres sans arrêts, on peut demander à QuickStep de mémoriser plusieurs ordres à l'avance. On peut mémoriser jusqu'à 255 ordres à l'avance, mais dans la majeure partie des cas 3 ordres suffisent (en fait il faut en avoir au moins un d'avance, mais pour des raisons de rapidité des calculs, la table est une puissance de 2). Dans QuickStepConf.h on aura alors la ligne

#define ORDRES_TABLE 4 // Valeurs possibles 2, 4, 8, 16, 32, 64, 128 ou 256
Si on donne trois ordres, les trois sont enregistrés immédiatement, on peut alors faire autre chose pendant ce temps. Cela donne:

... 1:
quickStep
Deplacement
2:
quickStep
Deplacement
3:
quickStep
Deplacement
AUTRE
CHOSE
1:
Pas
n°1
1:
Pas
n°2
1:
Pas
n°3
... 1:
Pas
n°N
2:
Pas
n°1
2:
Pas
n°2
2:
Pas
n°3
... 2:
Pas
n°N
3:
Pas
n°1
3:
Pas
n°2
3:
Pas
n°3
...

 

Fonctionnement pour beaucoup d'ordres rapprochés, non bloquants

Évidemment si on donne beaucoup d'ordres, un jour ou l'autre on dépassera la capacité de stockage. A ce moment quickStepDeplacement redevient bloquant. Pour éviter cela, il vaut mieux demander avant de donner un ordre si il y a de la place dans la table. Par exemple:

  if (quickSteplibre1() > 0 ) // si il y a au moins une place dans la table
    quickStepDeplacement1(nombreDePas, sens, tempsEntre Pas); // on peut alors demander sans blocage

 

Avec des accélérations et décélérations

Quand on demande un mouvement avec une accélérations, c'est identique à donner autant d'ordres en plus qu'il y a de paliers à faire. Si on fait une accélération sur 32 paliers, c'est comme si on demandait 33 ordres différents. Il en est de même pour les décélérations. Si on veut pouvoir avoir un code non bloquant , il faut alors que la table puisse admettre ces ordres.

Notez qu'avec 128 paliers d'accélérations et de décélérations, on sera forcément bloquant pendant les deux premiers paliers car la table la plus grande fait 255 ordres, alors qu'il en faudrait 257 (2N+1). On peut toutefois décomposer le mouvement, au lieu de faire:

#define ORDRES_TABLE1 256 // Valeurs possibles 2, 4, 8, 16, 32, 64, 128 ou 256
#define NB_ORDRES_ACCELERATION1 128 // Facultatif, valeurs possibles 4, 8, 16, 32, 64 ou 128
        ...
  if (quickSteplibre1() > 129 ) // si il y a au moins 129 places dans la table
    quickStepDeplacement1(nombreDePas / 2, sens, tempsEntrePas, nombreDePasAcceleration); // Accélère puis vitesse de croisière
	    ... 
  if (quickSteplibre1() > 129 ) // si il y a au moins 129 places dans la table
    quickStepDeplacement1(nombreDePas / 2, sens, tempsEntrePas, 0, nombreDePasDecceleration); // Vitesse de croisière puis décélération

 


dansetrad.fr Contactez-moi