Configuration de la Bibliothèque QuickStep

Sommaire:
      Configuration paramétrable
      Choix des drivers utilisées
      Choix des timers utilisées
      Définition des broches utilisées
      Choix du sens positif des moteurs
      Choix du nombre de paliers
      Choix de la taille des tables
      Enregistrer la configuration

 

Configuration paramétrable

Usuellement pour une bibliothèque, on crée un objet définissant ses caractéristiques. Par exemple ce serait quelque chose du genre:

QuickStep monMoteur(200pas, interruption1, Step sur la broche 11, Dir sur la 12, table de 32 déplacements);
Avec l'optique que j'ai, cela ne fonctionne pas bien pour plusieurs raisons:
- si je veux pouvoir utiliser l'interruption 1 soit pour un seul moteur, soit pour deux moteurs, je suis obligé d'écrire une fonction qui puisse faire les deux. Elle sera donc moins performante que si j'écris deux fonctions différentes.
- si je veux pouvoir mettre en place entre 1 et 4 fonctions d'interruption, il faudrait que je mette en place systématiquement les 4 fonctions et on ne pourrait pas utiliser les timers pour faire autre chose (du PWM par exemple). Les fonctions mises en place ne sont pas appelées par le programme car ce sont des interruptions et l'éditeur de liens ne peut pas enlever celles qui ne sont pas utilisées.
- la taille des table doit aussi pouvoir être choisie, et si la taille n'est pas définie à la compilation, cela ralentit le code.
- mon niveau en programmation n'est pas suffisant pour faire exactement ce dont j'ai envie.

Pour ces raisons, j'ai écrit provisoirement la bibliothèque avec une configuration paramétrable.

 

Choix des drivers utilisées

Ceci ne concerne que les drivers qui utilise le couple Step/Dir.

L'impulsion sur Step par défaut (si on ne précise rien) dure 1.688µs à l'état haut. C'est suffisant pour certains drivers, mais pas pour tous. En choisissant le bon driver, ou le temps que doit durer l'état haut de l'impulsion, on s'assure du bon fonctionnement (cela peut conduire à une réduction de la vitesse maximale). Cela se fait en décommentant la ligne choisie. Si deux lignes sont choisies en même temps, QuickStep utilisera la durée la plus longue pour garantir le bon fonctionnement.

Si on utilise un A4988, on enlèvera les // devant la ligne contenant le nom A4988. Cela donnera par exemple:

#define A4988      // T_Step_H_min=1µs    ( 8V   à 35V;   2A)

 

Choix des timers utilisées

Pour chaque mouvement, il faut utiliser un timer 16 bits. Un seul timer permet un mouvement d'un seul moteur ou de deux moteurs associés. Deux moteurs associés démarent en même temps et s'arrêtent en même temps. Avec deux moteurs indépendants, rien ne garantit la simultanéité de mouvements. On peut par exemple gérer avec un seul timer le mouvement d'une table croisée XY. Avec deux moteurs associés, la vitesse qui est donnée est la vitesse de la tête, un correction est faite pour la vitesse réelle de chaque moteur. Par exemple si le moteur X doit avancer seul de 400 pas du point A vers le point B ( voir schéma à droite) à la vitesse de 500 pas par seconde, il mettra 0,8s. Si la tête doit avancer de A à C à la même vitesse, les deux moteurs associés doivent avancer l'un de 300 pas, l'autre de 400 pas et il mettront en même temps une seconde car la distance équivalente est de de 500 pas.

Si on veut gérer les trois axes, il faut au moins deux timers. Pour deux moteurs indépendants, on peut aller plus vite en utilisant un timer par moteur. Mais un seul moteur fonctionne à la fois ou si quand les deux fonctionnent il démarrent et s'arrêtent en même temps, on peut n'utiliser qu'un seul timer. C'est intéressant si on a trop de moteurs ou si on a une carte Uno qui n'a qu'un seul timer 16 bits.

On ne peut pour l'instant utiliser que les timers 16 bits. Avec une Uno/Nano il y a un seul timer 16 bits, le timer N°1. Avec une Mega, on a 4 timers 16 bits: les timers N°1, N°3, N°4 et N°5.

Si on utilise un timer, il faut que cela serve. Il faut donc obligatoirement définir un ou deux moteurs en décommentant les lignes utiles de la bonne section. Si on utilise souhaite utiliser deux moteurs avec le timer 1, il faut renseigner le paragraphe qui commence par:

//#####################################®#####################################
//######### Configuration si on utilise deux moteurs sur le timer 1 #########
//#####################################®#####################################

 

Définition des broches utilisées

On peut utiliser un driver qui demande une commande Step/Dir. Définir la broche Step est indispensable (Step1 pour le commander le moteur par Step via le timer 1, Step3 si on utilise le timer 3...). Si le moteur tourne toujours dans le même sens et si Dir n'est pas câblé, ne pas définir Dir permettra d'aller plus vite ou d'économiser du temps. La définition de Dir, si elle est très souvent utilisée, reste facultative. On peut aussi gérer la broche Enable, si elle est définie QuickStep la programmera en sortie à l'état bas. Votre programme peut l'utiliser si vous le souhaitez. Pour définir une broche, Step par exemple, il faut décommenter la ligne, mais aussi remplacer <N° de la broche pour Step du premier moteur> par le numéro de la broche correspondant. On écrira par exemple:

#define Step3A 2
ou bien:
#define Step3A 2
#define dir3A 6

On peut aussi utiliser un moteur dont on commande directement les bobines, par exemple via un ULN2803. Bien souvent on a 4 bobines qui sont repérées pour le timer 3 par:

//#define premBobine3A <N° de la broche pour la première bobine>
//#define deuxBobine3A <N° de la broche pour la deuxième bobine>
//#define troisBobine3A <N° de la broche pour la première troisième bobine> Ordre inverse de la première bobine
//#define quatreBobine3A <N° de la broche pour la première quatrième bobine> Ordre inverse de la deuxième bobine
Il faut donc décommenter les lignes correspondantes en enlevant les // en début, puis remplacer toute la fin par le numéro de la broche correspondante. Cela peut donner:
#define premBobine3A 2
#define deuxBobine3A 4
#define troisBobine3A 12
#define quatreBobine3A 3
Le moteur est alimenté en mode deux phases à la fois obligatoirement. Les bobines vont par paire, quand l'une est alimentée l'autre ne l'est pas. Avec certains montage, l'inversion est câblé hard. On utilise alors que deux broches. Il faut alors définir le moteur que par ses deux premières broches.

 

Choix du sens positif des moteurs

Quand on donne un ordre pour faire tourner un moteur, on doit préciser le sens. Il y a donc un sens positif et un sens négatif. Mais en fonction du câblage, le moteur peut tourner dans les sens souhaités, ou à l'envers de ce que l'on souhaite. Une ligne de la configuration permet d'inverser le sens de rotation. Il n'y a pas se surcoût de code ou de temps pour faire tourner le moteur dans un seul sens ou dans les deux au choix. Alors autant en profiter. Pour inverser le sens d'un moteur, décommenter la ligne correspondante, ce qui peut donner:

#define inversion1 // Décommentez la ligne si le moteur tourne dans le mauvais sens

 

Choix du nombre de paliers

Les fonctions demandant un déplacement rangent les informations (ordres de déplacement) dans une table.

Le choix fait pour cette bibliothèque est de faire des accélérations par paliers de vitesses constantes; on va faire N pas à la vitesse V1, N pas à la vitesse V2... N pas à la vitesse Vfinale-1 puis passer à la vitesse finale. Calculer chaque pas pour avoir une rampe plus douce prendrait trop de temps de calcul si on cherche à passer en sur-vitesse à 16 micro-pas. En fait quand je dis N paliers, c'est sans compter le palier à vitesse nulle qui est fictif, et le dernier palier à vitesse finale (de croisière).

Un déplacement simple sans accélération ni décélération utilise 1 seule place dans la table, une accélération utilise N places en plus et une décélération utilise N places en plus. Un déplacement avec accélération et décélération utilise donc 2N+1 places ou ordres de déplacements élémentaires. Quand on donne un seul ordre complexe (avec accélération et décélération), le programme le transforme en 2N+1 ordres élémentaires.

Le nombre N de paliers pour accélérer ou décélérer peut être choisi parmi 4, 8, 16, 32, 64 ou 128 paliers (sans compter le palier final). Avec 4 paliers, on va entendre les 5 vitesses (pour chaque vitesse le moteur fait un son différent). Plus le nombre de paliers augmente plus ce sera doux. La vitesse de démarrage est choisie ainsi:
4 paliers -> vitesse finale / 2,2
8 paliers -> vitesse finale / 3
16 paliers -> vitesse finale / 4,1
32 paliers -> vitesse finale / 5,7
64 paliers -> vitesse finale / 8,1
128 paliers -> vitesse finale / 11,4
Bien entendu, si la vitesse n'est pas possible parce que trop lente avec l'horloge choisie, elle est réglée au minimum possible. Il y aura moins de paliers et le premier occupera la place de plusieurs paliers.
Plus le nombre de paliers est important, plus on peut démarrer lentement ou plus on peut aller vite pour une même vitesse de démarrage (pour le comprendre, avec 1 seul palier on démarre entre la vitesse nulle et la vitesse finale, pour une infinité de paliers, on peut démarrer à vitesse nulle). La vitesse de démarrage c'est la vitesse finale divisée par racine du nombre de paliers plus un.
Mais plus le nombre de paliers est grand, plus cela prend de la place dans la table. Par exemple avec une table de 256 ordres de déplacements élémentaires, on peut mettre en avance 28 déplacements complets avec accélération et décélération si on choisit 4 paliers par accélération, 3 déplacements complets en avance si on choisit 32 paliers, et presque un si on choisit 128 paliers. Notez aussi que les accélérations et les décélérations enlèvent les à-coups de démarrage et d'arrêt. On peut aussi programmer un déplacement accéléré sur 2 valeurs en donnant directement les deux ordres appropriés.

Pour chaque timer, il faut définir le nombre de paliers d'accélération (et donc de décélération) entre 4, 8, 16, 32, 64 ou 128 paliers. Si on ne choisit pas le nombre de paliers (la ligne correspondante reste en commentaire), il n'y aura pas d'accélérations / décélérations (les valeurs si il y en a sont ignorées) et le programme occupera moins de place en mémoire car le code correspondant ne sera pas inséré.

Une accélération démarre à une vitesse nulle, et accélère jusqu'au maximum. La décélération fait l'inverse. Pour avoir une accélération non prévue, par exemple pour aller de la vitesse V1 à une vitesse V2, Il faut se calculer soi même les paliers, et donner autant d'ordre élémentaires de déplacements.

 

Choix de la taille des tables

Si les tables peuvent contenir les nouveaux ordres élémentaires, les fonctions demandant les déplacements ne sont pas bloquantes. Dans le cas contraire, ces fonctions vont attendre que la place se libère avant de rendre la main. On peut donc travailler avec une table de 1 ordre utile si on n'a rien d'autre à faire. Dans ce cas, tant que le déplacement n'est pas fini, il occupe toute la table, et il faut attendre que le déplacement soit fini pour enregistrer un nouveau déplacement. La fonction demandant un déplacement n'est pas bloquante, mais si on demande un nouveau déplacement sans avoir terminé le précédent la fonction devient bloquante.

Si on rentre les ordres un par un, on dispose de peu de temps à chaque fois. Avec 255 ordres utiles surtout si on n'est pas en mode accélération, on peut disposer d'un temps libre important avant que la table soit vide. Tant que la table n'est pas vide, les pas s'enchaînent sans arrêt entre deux ordres. Sauf dans le cas ou on a une table avec un seul ordre utile, deux déplacements de 100 pas sont strictement équivalents à un déplacement de 200 pas car il n'y a pas d'arrêt entre les deux mouvements. Il est ainsi possible d'enchaîner des mouvements ou de faire des paliers d'accélération (même en sur-vitesse).

Par contre plus la table est grande, plus on utilise la mémoire. Une carte Uno ou une Nano a 2ko de RAM qui est utilisée pour les variables et pour la pile. Une Mega a 8ko de RAM. Avec une Uno, si on utilise une carte SD qui a besoin de 700 octets, on ne peut pas utiliser 255 ordres...

Un ordre dans la table c'est 5 octets de RAM pour la gestion d'un seul moteur ou 7 octets de RAM pour la gestion de deux moteurs associés, et on peut choisir entre 2, 4, 8, 16, 32, 64, 128 ou 256 ordres de déplacement pour un timer donné. Un des ordres est inutilisable (réservé pour l'ordre d'arrêt). La taille d'une table est donné par le tableau:
Nombre
  d'ordre utiles  
Nombre
  d'ordres  
Taille en RAM pour
  un seul moteur  
Taille en RAM pour
  deux moteurs associés  
121014
342028
784056
151680112
3132160224
6364320448
127128640896
25525612801792
Avec une Uno qui n'a que 2ko de mémoire vive, on ne peut donc quasiment pas utiliser une table de 256 ordres pour commander deux moteurs ensembles

 

Enregistrer la configuration

Pour configurer la bibliothèque, il faut éditer le fichier QuickStepConf.h se trouvant dans le répertoire travail et décommenter les lignes utiles, et éventuellement compléter avec les bonnes valeurs, puis sauvegarder (tous les fichiers de QuickStep doivent se trouver dans le répertoire de travail ainsi que le fichier digitalWriteFast.h). On peut ou non garder les lignes inutiles (cela permet de corriger plus tard, et cela ne prend pas de place dans l'Arduino).

Cela pourrait ressembler à:

//###########################################################################
//########             Configuration des drivers utilisés            ########
//###########################################################################
#define A4988      // T_Step_H_min=1µs    ( 8V   à 35V;   2A)

//###########################################################################
//######## Configuration si on utilise un seul moteur sur le timer 3 ########
//###########################################################################
//#define Step3 <N° de la broche pour Step>
//#define dir3 <N° de la broche pour Dir> // Facultatif
#define premBobine3 2
#define deuxBobine3 3
//#define troisBobine3 <N° de la broche pour la première troisième bobine> // Ordre inverse de la première bobine
//#define quatreBobine3 <N° de la broche pour la première quatrième bobine> // Ordre inverse de la deuxième bobine
#define inversionDir3 // Décommentez la ligne si le moteur tourne dans le mauvais sens
//#define enable3  // Facultatif, au cas ou on veut la mettre à LOW
#define ORDRES_TABLE3 4 // Valeurs possibles 2, 4, 8, 16, 32, 64, 128 ou 256
//#define NB_ORDRES_ACCELERATION3 128 // Facultatif, valeurs possibles 4, 8, 16, 32, 64 ou 128
Et même si on est minimaliste:
#define A4988
#define premBobine3 2
#define deuxBobine3 3
#define inversionDir3
#define ORDRES_TABLE3 4

dansetrad.fr Contactez-moi