3.3. Timer virtuali#

La pagina Temporizzazione ha trattato i timestamp e i cicli non bloccanti guidati da time.ticks_diff(). Un timer virtuale è il rovescio della medaglia: il software chiede al runtime di chiamare una funzione secondo una pianificazione, e il runtime invoca il callback senza che lo script debba controllare da solo l’orologio.

3.3.1. La classe machine.Timer#

machine.Timer costruisce un timer virtuale. Il comportamento valido su tutte le porte richiede l’id speciale -1; tutto il resto – periodo, modalità, callback – viene impostato tramite argomenti keyword:

from machine import Timer

def tick(t):
    print("tick")

tim = Timer(-1)
tim.init(period=100, callback=tick)   # 10 Hz

Il callback viene invocato come qualsiasi normale chiamata di funzione – può allocare oggetti, usare print() e chiamare altro codice di libreria senza restrizioni particolari.

3.3.2. Periodico e a colpo singolo#

Sono disponibili due modalità:

  • Timer.PERIODIC (l’impostazione predefinita). Il callback si attiva ogni period millisecondi, all’infinito, finché non viene chiamato deinit() o il timer non viene reinizializzato.

  • Timer.ONE_SHOT. Il callback si attiva una sola volta, period millisecondi dopo init(), e il timer si ferma.

Timer(-1).init(mode=Timer.ONE_SHOT, period=2000, callback=fire)

deinit() ferma un timer periodico e annulla qualsiasi callback in sospeso:

tim.deinit()

3.3.3. Quando ricorrere a un timer#

I timer virtuali e il pattern di polling con ticks_diff() visto in Temporizzazione risolvono lo stesso problema da direzioni opposte. Un ciclo con polling controlla l’orologio a ogni iterazione e agisce quando è trascorso abbastanza tempo; un timer chiede al runtime di risvegliare lo script quando è trascorso abbastanza tempo.

  • Polling con ticks_diff. Tutto resta in un unico posto – il ciclo possiede la temporizzazione, nessun callback aggiuntivo da tenere sotto controllo. Ideale per lavori brevi e ben definiti che mettono insieme diversi compiti guidati dal tempo.

  • Timer virtuale. Sposta la pianificazione fuori dal corpo del ciclo. Ideale quando il compito periodico è indipendente dal flusso principale (un LED di heartbeat, un campionamento periodico di un sensore) e consente al ciclo principale di dedicare il proprio tempo ad altri lavori.

Entrambi gli approcci usano lo stesso orologio sottostante e offrono la stessa precisione a periodi di un millisecondo o più. Nessuno dei due è adatto per la commutazione precisa dei pin o per la generazione di forme d’onda sotto il millisecondo – la latenza del callback è dell’ordine del tick dello scheduler, non dei nanosecondi.