3.2. Temporisation¶
Le module time regroupe des fonctions permettant de dormir (mettre le script en pause pendant une durée connue) et de mesurer le temps que prend quelque chose. Sur un microcontrôleur, ce ne sont pas des fonctionnalités accessoires ; c’est ainsi que le script cadence ses interactions avec le monde extérieur – combien de temps maintenir une broche à l’état haut, combien de temps attendre entre les échantillons, depuis combien de temps un bouton a été pressé pour la dernière fois.
3.2.1. Dormir¶
Trois fonctions de mise en veille bloquent le script pendant la durée demandée :
time.sleep(s)– pause dessecondes. Accepte un flottant, donctime.sleep(0.5)attend une demi-seconde.time.sleep_ms(ms)– pause demsmillisecondes. L’argument doit être un entier.time.sleep_us(us)– pause deusmicrosecondes.
import time
print("now")
time.sleep_ms(500)
print("half a second later")
Utilisez time.sleep_ms() pour les besoins typiques de type « attendre un peu » et time.sleep_us() uniquement lorsque la temporisation doit être précise. Le simple time.sleep() convient aussi, mais les variantes à argument entier évitent la conversion en virgule flottante et se lisent plus naturellement pour les courts intervalles.
Dormir est un appel bloquant. Pendant que le script dort, il ne fait rien d’autre – ni lire une broche, ni desservir un UART, ni mettre à jour une LED. Recourez à sleep lorsque le blocage est ce que vous voulez ; utilisez le motif non bloquant ci-dessous lorsque ce n’est pas le cas.
3.2.2. Lire l’horloge¶
Pour mesurer le temps que prend un morceau de code, lisez l’horloge avant et après :
time.ticks_ms()– la valeur actuelle du compteur de ticks en millisecondes.time.ticks_us()– la même en microsecondes.
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_ms() - start
print("took", elapsed, "ms")
Cela fonctionne la plupart du temps. Le compteur de ticks repasse à zéro (revient en boucle à zéro) après un nombre de ticks important mais fini, et une soustraction naïve à travers ce rebouclage produit un nombre négatif ou positif totalement erroné.
Le compteur de ticks repasse à zéro lorsqu’il atteint la limite entière. Une simple soustraction à travers ce rebouclage est erronée.¶
3.2.3. ticks_diff¶
Pour obtenir correctement les ticks écoulés, même à travers un rebouclage, utilisez time.ticks_diff() :
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_diff(time.ticks_ms(), start)
print("took", elapsed, "ms")
L’ordre des arguments est ticks_diff(later, earlier) – l’expression se lit « à quelle distance se trouve later après earlier ». Le résultat est un entier signé ; positif signifie que later est effectivement postérieur, négatif signifie qu’il est dans le passé. La fonction gère le rebouclage en interne.
Astuce
Associez toujours time.ticks_ms() / time.ticks_us() à time.ticks_diff(). La soustraction brute est correcte la plupart du temps ; le moment où elle est erronée est lorsqu’un script tourne depuis longtemps – généralement le pire moment pour déboguer un problème de temporisation.
3.2.4. Temporisation non bloquante¶
Un script de microcontrôleur a généralement plus d’une chose à faire « en même temps » : lire un bouton, faire clignoter une LED, interroger un capteur, desservir un UART. sleep ne convient pas pour cela – pendant qu’un sleep est en cours, les autres tâches sont à l’arrêt.
Le motif standard consiste à conserver une échéance par tâche, et à vérifier à chaque boucle si l’échéance est dépassée. La décision d’agir repose sur time.ticks_diff(), jamais sur sleep :
import time
next_blink = time.ticks_ms()
next_poll = time.ticks_ms()
state = False
while True:
now = time.ticks_ms()
if time.ticks_diff(now, next_blink) >= 0:
state = not state
# update LED here
next_blink = time.ticks_add(next_blink, 500)
if time.ticks_diff(now, next_poll) >= 0:
# read sensor here
next_poll = time.ticks_add(next_poll, 100)
La LED bascule toutes les 500 ms, le capteur est interrogé toutes les 100 ms, et aucune des deux tâches ne bloque l’autre. time.ticks_add() fait avancer une échéance d’un incrément connu sans tomber dans le piège du rebouclage.
Cette forme – une seule boucle, plusieurs tâches temporisées, aucun sleep dans le corps – apparaît partout où du code matériel intervient : anti-rebond logiciel des interrupteurs, séquencement de moteurs, délais d’attente de lecture UART. Les trois mêmes fonctions (time.ticks_ms(), time.ticks_diff(), time.ticks_add()) couvrent tous les cas.