time — tijdgerelateerde functies

De time-module biedt functies voor het ophalen van de huidige tijd en datum, het meten van tijdsintervallen en voor vertragingen.

Tijdperk (epoch): De op Alif en i.MX RT gebaseerde OpenMV Cams gebruiken het POSIX-epoch van 1970-01-01 00:00:00 UTC. De op STM32 gebaseerde OpenMV Cams gebruiken een epoch van 2000-01-01 00:00:00 UTC. Het epoch-jaar kan tijdens runtime worden bepaald met gmtime(0)[0].

Bijhouden van de werkelijke kalenderdatum/-tijd: Dit vereist een Real Time Clock (RTC). Op de OpenMV Cam wordt de systeemtijd geleverd door het machine.RTC-object. De huidige kalendertijd kan worden ingesteld met machine.RTC().datetime(tuple) en wordt bijgehouden door een van de volgende:

  • Een back-upbatterij (een optioneel onderdeel op sommige OpenMV Cams).

  • Een netwerktijdprotocol zoals ntptime (vereist een netwerkverbinding).

  • Handmatig instellen bij elke keer dat het apparaat wordt ingeschakeld. De RTC blijft dan doorgaans behouden over soft resets, maar gaat verloren bij stroomverlies tenzij er een back-upbatterij is geplaatst.

Als de kalendertijd niet wordt bijgehouden, zullen de onderstaande functies die naar de huidige absolute tijd verwijzen zich niet gedragen zoals verwacht.

Functies

time.gmtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]
time.localtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]

Converteer de tijd secs, uitgedrukt in seconden sinds het epoch (zie hierboven), naar een 8-tuple die bevat: (year, month, mday, hour, minute, second, weekday, yearday) Als secs niet wordt opgegeven of None is, wordt de huidige tijd van de RTC gebruikt.

De functie gmtime() geeft een datum-tijd-tuple in UTC terug, en localtime() geeft een datum-tijd-tuple in lokale tijd terug.

Het formaat van de items in de 8-tuple is:

  • year omvat de eeuw (bijvoorbeeld 2014).

  • month is 1-12

  • mday is 1-31

  • hour is 0-23

  • minute is 0-59

  • second is 0-59

  • weekday is 0-6 voor ma-zo

  • yearday is 1-366

time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int

Dit is de inverse functie van localtime. Het argument is een volledige 8-tuple die een tijd uitdrukt zoals localtime. Het geeft een geheel getal terug dat het aantal seconden sinds het tijdperk is.

time.sleep(seconds: float) None

Slaap gedurende het opgegeven aantal seconden. seconds kan een drijvendekommagetal zijn, om gedurende een fractioneel aantal seconden te slapen. Gebruik voor fijnmazigere of uitsluitend gehele vertragingen de functies sleep_ms() en sleep_us().

Het aanroepen van sleep(), inclusief sleep(0), roept gegarandeerd in afwachting zijnde callback-functies aan.

time.sleep_ms(ms: int) None

Vertraag gedurende het opgegeven aantal milliseconden, moet positief of 0 zijn.

Deze functie vertraagt gedurende ten minste het opgegeven aantal milliseconden, maar kan langer duren als er andere verwerking moet plaatsvinden, bijvoorbeeld interrupt-handlers of andere threads. Het doorgeven van 0 voor ms staat deze andere verwerking nog steeds toe. Gebruik sleep_us() voor preciezere vertragingen.

Het aanroepen van sleep_ms(), inclusief sleep_ms(0), roept gegarandeerd in afwachting zijnde callback-functies aan.

time.sleep_us(us: int) None

Vertraag gedurende het opgegeven aantal microseconden, moet positief of 0 zijn.

Deze functie probeert een nauwkeurige vertraging van ten minste us microseconden te bieden, maar het kan langer duren als het systeem andere verwerking met hogere prioriteit moet uitvoeren.

time.ticks_ms() int

Geeft een oplopende millisecondenteller terug met een willekeurig referentiepunt, die na een bepaalde waarde terugloopt naar nul.

De terugloopwaarde wordt niet expliciet blootgesteld, maar we verwijzen ernaar als TICKS_MAX om de bespreking te vereenvoudigen. De periode van de waarden is TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD is gegarandeerd een macht van twee, maar kan voor het overige van port tot port verschillen. Dezelfde periodewaarde wordt gebruikt voor alle functies ticks_ms(), ticks_us(), ticks_cpu() (voor de eenvoud). Deze functies geven dus een waarde terug in het bereik [0 .. TICKS_MAX], inclusief, in totaal TICKS_PERIOD waarden. Merk op dat alleen niet-negatieve waarden worden gebruikt. Voor het grootste deel moet u de waarden die door deze functies worden teruggegeven als ondoorzichtig behandelen. De enige bewerkingen die voor hen beschikbaar zijn, zijn de hieronder beschreven functies ticks_diff() en ticks_add().

Opmerking: Het rechtstreeks uitvoeren van standaard wiskundige bewerkingen (+, -) of relationele operatoren (<, <=, >, >=) op deze waarden leidt tot een ongeldig resultaat. Het uitvoeren van wiskundige bewerkingen en vervolgens de resultaten ervan als argumenten doorgeven aan ticks_diff() of ticks_add() leidt ook tot ongeldige resultaten van deze laatste functies.

time.ticks_us() int

Net als ticks_ms() hierboven, maar in microseconden.

time.ticks_cpu() int

Vergelijkbaar met ticks_ms() en ticks_us(), maar met de hoogst mogelijke resolutie in het systeem. Dit zijn meestal CPU-klokken, en daarom is de functie zo genoemd. Maar het hoeft geen CPU-klok te zijn; een andere in een systeem beschikbare tijdbron (bijv. een hoogresolutietimer) kan in plaats daarvan worden gebruikt. De exacte tijdseenheid (resolutie) van deze functie is niet gespecificeerd op het niveau van de time-module, maar documentatie voor een specifieke port kan specifiekere informatie bieden. Deze functie is bedoeld voor zeer fijne benchmarking of zeer strakke real-time loops. Vermijd het gebruik ervan in porteerbare code. Ze is beschikbaar op alle OpenMV Cams.

time.ticks_add(ticks: int, delta: int) int

Verschuif de tickswaarde met een opgegeven getal, dat positief of negatief kan zijn. Gegeven een ticks-waarde, maakt deze functie het mogelijk om de tickswaarde delta ticks voor of na deze te berekenen, volgens de definitie van tickswaarden op basis van modulair rekenen (zie ticks_ms() hierboven). De parameter ticks moet een direct resultaat zijn van een aanroep van de functies ticks_ms(), ticks_us() of ticks_cpu() (of van een eerdere aanroep van ticks_add()). delta kan echter een willekeurig geheel getal of numerieke uitdrukking zijn. ticks_add() is nuttig voor het berekenen van deadlines voor gebeurtenissen/taken. (Opmerking: u moet de functie ticks_diff() gebruiken om met deadlines te werken.)

Voorbeelden:

# Find out what ticks value there was 100ms ago
print(ticks_add(time.ticks_ms(), -100))

# Calculate deadline for operation and test for it
deadline = ticks_add(time.ticks_ms(), 200)
while ticks_diff(deadline, time.ticks_ms()) > 0:
    do_a_little_of_something()

# Find out TICKS_MAX used by this port
print(ticks_add(0, -1))
time.ticks_diff(ticks1: int, ticks2: int) int

Meet het ticksverschil tussen waarden die worden teruggegeven door de functies ticks_ms(), ticks_us() of ticks_cpu(), als een waarde met teken die kan teruglopen.

De argumentvolgorde is dezelfde als voor de aftrekoperator; ticks_diff(ticks1, ticks2) heeft dezelfde betekenis als ticks1 - ticks2. De waarden die door functies zoals ticks_ms() worden teruggegeven kunnen echter teruglopen, dus het rechtstreeks toepassen van aftrekking erop levert een onjuist resultaat op. Daarom is ticks_diff() nodig; het implementeert modulair (of specifieker, ring-)rekenen om een correct resultaat te produceren, zelfs voor teruggelopen waarden (zolang ze niet te ver uit elkaar liggen, zie hieronder). De functie geeft een waarde met teken terug in het bereik [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (dat is een typische bereikdefinitie voor gehele binaire getallen met teken in twee-complement). Als het resultaat negatief is, betekent dit dat ticks1 eerder in de tijd plaatsvond dan ticks2. Anders betekent het dat ticks1 na ticks2 plaatsvond. Dit geldt alleen als ticks1 en ticks2 niet meer dan TICKS_PERIOD/2-1 ticks uit elkaar liggen. Als dat niet het geval is, wordt een onjuist resultaat teruggegeven. Specifiek, als twee tickswaarden TICKS_PERIOD/2-1 ticks uit elkaar liggen, wordt die waarde door de functie teruggegeven. Als er echter TICKS_PERIOD/2 real-time ticks tussen zijn verstreken, geeft de functie in plaats daarvan -TICKS_PERIOD/2 terug, d.w.z. de resultaatwaarde loopt terug naar het negatieve bereik van mogelijke waarden.

Informele rechtvaardiging van de bovenstaande beperkingen: Stel dat u opgesloten zit in een kamer zonder enige manier om het verstrijken van de tijd te volgen, behalve een standaardklok met 12 inkepingen. Als u nu op de wijzerplaat kijkt en pas weer na 13 uur kijkt (bijv. als u in een lange slaap valt), dan lijkt het u, wanneer u eindelijk weer kijkt, alsof er slechts 1 uur is verstreken. Om deze fout te vermijden, kijkt u gewoon regelmatig op de klok. Uw applicatie zou hetzelfde moeten doen. De metafoor “te lang slapen” vertaalt zich ook direct naar het gedrag van applicaties: laat uw applicatie geen enkele taak te lang uitvoeren. Voer taken in stappen uit en houd er tussendoor de tijd bij.

ticks_diff() is ontworpen om verschillende gebruikspatronen te ondersteunen, waaronder:

  • Pollen met time-out. In dit geval is de volgorde van de gebeurtenissen bekend en hebt u alleen met positieve resultaten van ticks_diff() te maken:

    # Wait for GPIO pin to be asserted, but at most 500us
    start = time.ticks_us()
    while pin.value() == 0:
        if time.ticks_diff(time.ticks_us(), start) > 500:
            raise TimeoutError
    
  • Gebeurtenissen plannen. In dit geval kan het resultaat van ticks_diff() negatief zijn als een gebeurtenis te laat is:

    # This code snippet is not optimized
    now = time.ticks_ms()
    scheduled_time = task.scheduled_time()
    if ticks_diff(scheduled_time, now) > 0:
        print("Too early, let's nap")
        sleep_ms(ticks_diff(scheduled_time, now))
        task.run()
    elif ticks_diff(scheduled_time, now) == 0:
        print("Right at time!")
        task.run()
    elif ticks_diff(scheduled_time, now) < 0:
        print("Oops, running late, tell task to run faster!")
        task.run(run_faster=true)
    

Opmerking: Geef geen time()-waarden door aan ticks_diff(); u moet er normale wiskundige bewerkingen op uitvoeren. Maar merk op dat time() ook kan (en zal) overlopen. Dit staat bekend als https://en.wikipedia.org/wiki/Year_2038_problem .

time.time() int

Geeft het aantal seconden, als geheel getal, sinds het epoch terug, ervan uitgaande dat de onderliggende RTC is ingesteld en wordt bijgehouden zoals hierboven beschreven. Als er geen RTC is ingesteld, geeft deze functie het aantal seconden terug sinds een port-specifiek referentiepunt in de tijd (voor embedded boards zonder een door batterij ondersteunde RTC meestal sinds het inschakelen of resetten). Als u een porteerbare MicroPython-applicatie wilt ontwikkelen, moet u niet op deze functie vertrouwen voor een hogere dan secondeprecisie. Als u hogere precisie, absolute tijdstempels nodig hebt, gebruik dan time_ns(). Als relatieve tijden acceptabel zijn, gebruik dan de functies ticks_ms() en ticks_us(). Als u kalendertijd nodig hebt, is gmtime() of localtime() zonder argument een betere keuze.

Verschil met CPython

In CPython geeft deze functie het aantal seconden sinds het Unix-epoch (1970-01-01 00:00 UTC) terug als drijvendekommawaarde, meestal met microsecondeprecisie. Op de OpenMV Cam geeft ze een geheel getal terug met een precisie van één seconde – de hardware kan niet zowel een lang tijdbereik als subsecondeprecisie in een float weergeven – en het epoch verschilt per board (zie Tijdperk (epoch) hierboven). Zonder een door batterij ondersteunde RTC die is ingesteld, telt ze in plaats daarvan de seconden sinds het inschakelen/resetten.

time.time_ns() int

Vergelijkbaar met time(), maar geeft nanoseconden sinds het epoch terug, als geheel getal (meestal een groot geheel getal, dus zal op de heap toewijzen).

Constructors

class time.clock

Geeft een klokobject terug.

Methoden

tick() None

Begint met het bijhouden van verstreken tijd.

fps() float

Stopt met het bijhouden van de verstreken tijd en geeft de huidige FPS (frames per seconde) terug.

Roep altijd eerst tick aan voordat u deze functie aanroept.

avg() float

Stopt met het bijhouden van de verstreken tijd en geeft de huidige gemiddelde verstreken tijd in milliseconden terug.

Roep altijd eerst tick aan voordat u deze functie aanroept.

reset() None

Reset het klokobject.