3.2. Tidtagning

Modulen time samlar funktioner för att sova (pausa skriptet under en känd varaktighet) och för att mäta hur lång tid något tar. På en mikrokontroller är detta inte bara trevligt att ha; det är så skriptet styr takten på interaktioner med omvärlden – hur länge ett stift ska hållas högt, hur länge man ska vänta mellan samplingar, hur länge sedan en knapp senast trycktes ned.

3.2.1. Att sova

Tre sovfunktioner blockerar skriptet under den begärda varaktigheten:

  • time.sleep(s) – pausa i s sekunder. Accepterar ett flyttal, så time.sleep(0.5) väntar en halv sekund.

  • time.sleep_ms(ms) – pausa i ms millisekunder. Argumentet måste vara ett heltal.

  • time.sleep_us(us) – pausa i us mikrosekunder.

import time

print("now")
time.sleep_ms(500)
print("half a second later")

Använd time.sleep_ms() för typiska ”vänta lite”-behov och time.sleep_us() endast när tidtagningen måste vara strikt. Vanlig time.sleep() fungerar också bra, men varianterna med heltalsargument undviker flyttalskonvertering och läses mer naturligt för korta intervall.

Sleep är ett blockerande anrop. Medan skriptet sover gör det ingenting annat – läser inte ett stift, betjänar inte en UART, uppdaterar inte en LED. Ta till sleep när blockering är vad du vill ha; använd det icke-blockerande mönstret nedan när det inte är det.

3.2.2. Att läsa klockan

För att mäta hur lång tid en bit kod tar, läs klockan före och efter:

import time

start = time.ticks_ms()
do_work()
elapsed = time.ticks_ms() - start
print("took", elapsed, "ms")

Detta fungerar för det mesta. Tickräknaren slår runt (återgår till noll) efter ett stort men ändligt antal tick, och naiv subtraktion över det varvet ger ett vilt felaktigt negativt eller positivt tal.

Tallinje från 0 till MAX med ett starttick nära MAX och ett sluttick nära 0; en streckad runtvarvspil visar att räknaren efter MAX återgår till 0.

Tickräknaren slår tillbaka till noll när den når heltalsgränsen. En vanlig subtraktion över det varvet är felaktig.

3.2.3. ticks_diff

För att få de förflutna ticken korrekt, även över ett varv, använd time.ticks_diff():

import time

start = time.ticks_ms()
do_work()
elapsed = time.ticks_diff(time.ticks_ms(), start)
print("took", elapsed, "ms")

Argumentordningen är ticks_diff(later, earlier) – uttrycket läses ”hur långt efter earlier är later”. Resultatet är ett heltal med tecken; positivt betyder att later faktiskt är senare, negativt betyder att det är i det förflutna. Funktionen hanterar varvet internt.

Tips

Para alltid time.ticks_ms() / time.ticks_us() med time.ticks_diff(). Den råa subtraktionen är korrekt för det mesta; den gång den är fel är när ett skript har körts under lång tid – vanligtvis den sämsta tidpunkten att felsöka en tidtagningsglitch.

3.2.4. Icke-blockerande tidtagning

Ett mikrokontrollerskript har vanligtvis mer än en sak att göra ”samtidigt”: läsa en knapp, blinka en LED, polla en sensor, betjäna en UART. sleep duger inte för det – medan en sleep körs står de andra uppgifterna stilla.

Standardmönstret är att hålla en deadline per uppgift och att vid varje slinga kontrollera om deadlinen har passerat. Beslutet att agera bygger på time.ticks_diff(), aldrig på 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)

LED:en växlar var 500:e ms, sensorn pollas var 100:e ms, och ingen av uppgifterna blockerar den andra. time.ticks_add() flyttar fram en deadline med ett känt steg utan att råka illa ut för varvet.

Denna form – en enda slinga, flera tidsstyrda uppgifter, ingen sleep i kroppen – dyker upp överallt där maskinvarukod förekommer: mjukvaruavstudsning av strömbrytare, motorsekvensering, lästimeouter för UART. Samma tre funktioner (time.ticks_ms(), time.ticks_diff(), time.ticks_add()) täcker varje fall.