3.2. Temporização¶
O módulo time agrupa funções para dormir (pausar o script por uma duração conhecida) e para medir quanto tempo algo leva. Em um microcontrolador, isso não são recursos opcionais; é como o script ritma as interações com o mundo externo – por quanto tempo manter um pino em nível alto, quanto esperar entre amostras, quanto tempo se passou desde que um botão foi pressionado pela última vez.
3.2.1. Dormindo¶
Três funções de dormir bloqueiam o script pela duração solicitada:
time.sleep(s)– pausa porssegundos. Aceita um float, entãotime.sleep(0.5)espera meio segundo.time.sleep_ms(ms)– pausa pormsmilissegundos. O argumento deve ser um inteiro.time.sleep_us(us)– pausa porusmicrossegundos.
import time
print("now")
time.sleep_ms(500)
print("half a second later")
Use time.sleep_ms() para as necessidades típicas de “esperar um pouco” e time.sleep_us() apenas quando a temporização precisar ser precisa. O simples time.sleep() também serve, mas as variantes com argumento inteiro evitam a conversão de ponto flutuante e se leem de forma mais natural para intervalos curtos.
Dormir é uma chamada bloqueante. Enquanto o script está dormindo, ele não faz mais nada – não lê um pino, não atende uma UART, não atualiza um LED. Recorra a sleep quando bloquear for o que você deseja; use o padrão não bloqueante abaixo quando não for.
3.2.2. Lendo o relógio¶
Para medir quanto tempo um trecho de código leva, leia o relógio antes e depois:
time.ticks_ms()– o valor atual de ticks em milissegundos.time.ticks_us()– o mesmo em microssegundos.
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_ms() - start
print("took", elapsed, "ms")
Isso funciona na maioria das vezes. O contador de ticks transborda (volta a zero) após um número grande, porém finito, de ticks, e uma subtração ingênua através desse transbordo produz um número negativo ou positivo absurdamente errado.
O contador de ticks volta a zero quando atinge o limite do inteiro. Uma subtração simples através desse transbordo está errada.¶
3.2.3. ticks_diff¶
Para obter os ticks decorridos corretamente, mesmo através de um transbordo, use time.ticks_diff():
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_diff(time.ticks_ms(), start)
print("took", elapsed, "ms")
A ordem dos argumentos é ticks_diff(later, earlier) – a expressão se lê “quão depois later está de earlier“. O resultado é um inteiro com sinal; positivo significa que later é de fato posterior, negativo significa que está no passado. A função trata o transbordo internamente.
Dica
Sempre combine time.ticks_ms() / time.ticks_us() com time.ticks_diff(). A subtração crua está correta na maioria das vezes; a hora em que ela erra é quando um script está em execução há muito tempo – normalmente o pior momento para depurar uma falha de temporização.
3.2.4. Temporização não bloqueante¶
Um script de microcontrolador normalmente tem mais de uma coisa para fazer “ao mesmo tempo”: ler um botão, piscar um LED, consultar um sensor, atender uma UART. sleep não serve para isso – enquanto um sleep está em execução, as outras tarefas ficam paradas.
O padrão usual é manter um prazo (deadline) por tarefa e verificar a cada laço se o prazo já passou. A decisão de agir é construída sobre time.ticks_diff(), nunca sobre 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)
O LED alterna a cada 500 ms, o sensor é consultado a cada 100 ms, e nenhuma das tarefas bloqueia a outra. time.ticks_add() avança um prazo por um incremento conhecido sem cair na armadilha do transbordo.
Esse formato – um único laço, várias tarefas temporizadas, nenhum sleep no corpo – aparece em todo lugar onde código de hardware existe: debounce de chaves por software, sequenciamento de motores, timeouts de leitura de UART. As mesmas três funções (time.ticks_ms(), time.ticks_diff(), time.ticks_add()) cobrem todos os casos.