La cohabitation de QuickStep et de delay()

Sommaire:
      Perte d'impulsions
      Arrêt de l'horloge système
      Les boucles
      QuickStep et temporisations

 

Perte d'impulsions

Si on demande à un moteur de tourner suffisamment vite (à la limite de la bibliothèque) il est possible de perdre une impulsion Step. C'est le cas lors de l'interruption du programme par l'horloge système. Dans ces cas, impulsion sur Step n'aura pas lieu parce qu'au moment de la traiter, le processeur est occupé, et que quand il a fini, il y a déjà la demande de l'impulsion suivante. Il va donc y avoir une impulsion en moins, c'est à dire un micro-pas en moins. Si on est en micro-pas, ce n'est pas grave, on peur se permettre d'avoir une erreur d'un micro-pas (en fait d'un demi micro-pas). Cela n'a pas vraiment d'influence car cela équivaut à une perte de vitesse. Si on travaille par exemple à 3000tr/mn en mode 16 micro-pas pour un moteur 200 pas/tr, il y aura 3000/60*16*200 soit 160000 impulsions Steps par seconde. Si le timer 0 est actif et fait perdre une impulsion à chaque fois, nous allons perdre 1024 impulsions par secondes et le moteur ne tournera qu'à 160000-1024 soit 158976 impulsions par secondes (perte de vitesse de 0,64%).

Il n'y aura jamais perte de pas car le nombre de pas est compté uniquement si on traite l'impulsion. Si il manque une impulsion, cela ne change pas le nombre de pas au final. Ce n'est donc pas très grave.

On ne tourne quasiment jamais à 3000tr/mn, mais si huit moteurs tournent en même temps, on peut être dans le même cas.

 

Arrêt de l'horloge système

Pour ne pas avoir cette perte de vitesse, on peut désactiver l'horloge système en appelant la fonction stopHorlogeSysteme(). En désactivant l'horloge, les fonctions qui l'utilisent ne fonctionnent plus correctement. Il s'agit de delay(), millis() et micros().

delay() peut être appelée, mais risque bien de fournir une temporisation beaucoup plus courte que prévue, et n'est donc pas utilisable.

millis() sa valeur est fixe, elle devient inutile

micros() seul les 10 bits de poids faibles sont utilisables, à part cela elle fonctionne. Pour l'appeler, utilisez micros()&1024. Mais les intervalles de temps que l'on peut mesurer sont limités à 1ms.

delayMicroseconde() fonctionne toujours comme avant, elle n'utilise pas l'horloge système, mais fait des boucles. Le délai le plus grand est 16ms. Mais attention, si les moteurs tournent vite, il vont consommer du temps système, et ce sera autant qui ne sera pas utilisé pour faire les boucles. Si les moteurs consomment la moitié du temps, delayMicroseconde(1000); durera 2000µs. Il en est de même avec _delay_ms et _delay_µs.

 

Les boucles

On peut faire des temporisations avec des boucles. C'est ce que fait delayMicroseconde(). Tant qu'on ne fait pas tourner des moteurs rapidement, tout va très bien. Mais si un moteur tourne à 27tr/mn (la moitié de la vitesse maximale), la génération des impulsions va utiliser la moitié du temps disponible, et on passera donc deux fois moins de temps dans le calcul des boucles. Celui ci mettra donc deux fois plus de temps, faussant la temporisation.

Il est donc important lorsqu'on veut faire des temporisations de savoir si on utilise un timer ou des boucles de calcul;

 

QuickStep et temporisations

Si on utilise QuickStep et que les moteurs vont lentement, il n'y a pas lieu de s'alarmer, ne désactivez pas l'horloge système et utilisez les fonctions usuelles delay(), millis(), micros() et delayMicroseconde().

Si un ou des moteurs tournent assez près du maximum, vous pouvez laisser l'horloge système en route, cela peut éventuellement baisser la vitesse de 0,6% au maximum. Attention si on a plusieurs moteurs, le temps sera pris d'abord sur le ou les moteurs associés au timer 5, puis si cela l'arrête complètement, le temps est pris sur le ou les moteurs associés au timer 4... Cela peut se produire si les 4 moteurs dans l'ordre doivent tourner à 1630tr/mn, 1630tr/mn, 1tr/mn, 1tr/mn. La temporisation sera encore correcte avec l'utilisation du timer, mais plus avec le comptage de boucles (trop peu de temps restant). Évitez alors d'utiliser delayMicroseconds().

Il y a toujours la possibilité de désactiver l'horloge système que quand cela nous avantage. On peut la désactiver pour faire tourner les moteurs et l'activer (par startHorlogeSysteme()) pour pouvoir utiliser delay().

Pour les AVR, c'est le cas des Uno, Nano et Mega, il existe aussi deux fonctions de temporisations _delay_ms() et _delay_us() qui permettent de faire des temporisations par boucles.

En résumé:
    fonction         paramètre         unité         Timer ou boucle?         maximum    
delay()unsigned longmsTimer50 jours
delayMicroseconds()unsigned intµsBoucles16ms
_delay_ms()doublemsBoucles6s
_delay_us()doubleµsBoucles4s

Pour des durées plus longue, faites une boucle, par exemple:
    for (char boucle=0; boucle<10; boucle++) _delay_ms(1000.0); // Attente de 10s

 


dansetrad.fr Contactez-moi