time — funkce související s časem

Modul time poskytuje funkce pro získání aktuálního času a data, měření časových intervalů a pro zpoždění.

Časová epocha: OpenMV Cam založené na Alif a i.MX RT používají POSIXovou epochu 1970-01-01 00:00:00 UTC. OpenMV Cam založené na STM32 používají epochu 2000-01-01 00:00:00 UTC. Rok epochy lze za běhu zjistit pomocí gmtime(0)[0].

Udržování aktuálního kalendářního data/času: To vyžaduje hodiny reálného času (RTC). Na OpenMV Cam je systémový čas poskytován objektem machine.RTC. Aktuální kalendářní čas lze nastavit pomocí machine.RTC().datetime(tuple) a je udržován jedním z následujících způsobů:

  • Záložní baterie (volitelná součást na některých OpenMV Cam).

  • Síťový časový protokol, jako je ntptime (vyžaduje síťové připojení).

  • Ruční nastavení při každém zapnutí. RTC je pak obvykle udržováno i přes softwarové resety, ale při ztrátě napájení se ztratí, pokud není osazena záložní baterie.

Pokud kalendářní čas není udržován, níže uvedené funkce, které odkazují na aktuální absolutní čas, se nebudou chovat podle očekávání.

Funkce

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]

Převede čas secs vyjádřený v sekundách od epochy (viz výše) na 8-tici, která obsahuje: (year, month, mday, hour, minute, second, weekday, yearday) Pokud secs není zadáno nebo je None, použije se aktuální čas z RTC.

Funkce gmtime() vrací n-tici data a času v UTC a funkce localtime() vrací n-tici data a času v místním čase.

Formát položek v 8-tici je následující:

  • year zahrnuje století (například 2014).

  • month je 1-12

  • mday je 1-31

  • hour je 0-23

  • minute je 0-59

  • second je 0-59

  • weekday je 0-6 pro Po-Ne

  • yearday je 1-366

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

Toto je inverzní funkce k localtime. Jejím argumentem je úplná 8-tice, která vyjadřuje čas podle localtime. Vrací celé číslo, což je počet sekund od časové epochy.

time.sleep(seconds: float) None

Uspí program na daný počet sekund. seconds může být číslo s plovoucí desetinnou čárkou pro uspání na zlomek sekundy. Pro jemnější nebo pouze celočíselná zpoždění použijte funkce sleep_ms() a sleep_us().

Volání sleep(), včetně sleep(0), zaručeně zavolá čekající callback funkce.

time.sleep_ms(ms: int) None

Zpoždění na daný počet milisekund, mělo by být kladné nebo 0.

Tato funkce vytvoří zpoždění alespoň o daný počet milisekund, ale může trvat déle, pokud musí proběhnout jiné zpracování, například obsluhy přerušení nebo jiná vlákna. Předání 0 pro ms stále umožní toto jiné zpracování. Pro přesnější zpoždění použijte sleep_us().

Volání sleep_ms(), včetně sleep_ms(0), zaručeně zavolá čekající callback funkce.

time.sleep_us(us: int) None

Zpoždění na daný počet mikrosekund, mělo by být kladné nebo 0.

Tato funkce se pokouší poskytnout přesné zpoždění alespoň us mikrosekund, ale může trvat déle, pokud má systém provádět jiné zpracování s vyšší prioritou.

time.ticks_ms() int

Vrací rostoucí čítač milisekund s libovolným referenčním bodem, který se po určité hodnotě přetočí.

Hodnota přetočení není explicitně vystavena, ale pro zjednodušení výkladu ji budeme označovat jako TICKS_MAX. Perioda hodnot je TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD je zaručeně mocninou dvou, ale jinak se může lišit port od portu. Stejná hodnota periody se používá pro všechny funkce ticks_ms(), ticks_us(), ticks_cpu() (pro jednoduchost). Tyto funkce tedy vrátí hodnotu v rozsahu [0 .. TICKS_MAX] včetně, celkem TICKS_PERIOD hodnot. Mějte na paměti, že se používají pouze nezáporné hodnoty. Z větší části byste měli s hodnotami vrácenými těmito funkcemi zacházet jako s neprůhlednými. Jediné operace, které jsou pro ně k dispozici, jsou funkce ticks_diff() a ticks_add() popsané níže.

Poznámka: Provádění standardních matematických operací (+, -) nebo relačních operátorů (<, <=, >, >=) přímo na těchto hodnotách povede k neplatnému výsledku. Provádění matematických operací a následné předání jejich výsledků jako argumentů funkcím ticks_diff() nebo ticks_add() rovněž povede k neplatným výsledkům z těchto funkcí.

time.ticks_us() int

Stejně jako ticks_ms() výše, ale v mikrosekundách.

time.ticks_cpu() int

Podobné jako ticks_ms() a ticks_us(), ale s nejvyšším možným rozlišením v systému. Obvykle se jedná o hodiny CPU, a proto je funkce takto pojmenována. Nemusí to však být hodiny CPU, místo toho lze použít jiný zdroj časování dostupný v systému (např. časovač s vysokým rozlišením). Přesná časová jednotka (rozlišení) této funkce není na úrovni modulu time specifikována, ale dokumentace konkrétního portu může poskytnout přesnější informace. Tato funkce je určena pro velmi jemný benchmarking nebo velmi těsné smyčky reálného času. Vyhněte se jejímu použití v přenositelném kódu. Je dostupná na všech OpenMV Cam.

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

Posune hodnotu ticks o daný počet, který může být kladný nebo záporný. Pro danou hodnotu ticks tato funkce umožňuje vypočítat hodnotu ticks delta tiků před ní nebo po ní, podle definice hodnot tiků v modulární aritmetice (viz ticks_ms() výše). Parametr ticks musí být přímým výsledkem volání funkcí ticks_ms(), ticks_us() nebo ticks_cpu() (nebo z předchozího volání ticks_add()). Hodnota delta však může být libovolné celé číslo nebo číselný výraz. ticks_add() je užitečná pro výpočet termínů (deadlinů) pro události/úlohy. (Poznámka: pro práci s termíny musíte použít funkci ticks_diff().)

Příklady:

# 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

Změří rozdíl tiků mezi hodnotami vrácenými z funkcí ticks_ms(), ticks_us() nebo ticks_cpu(), jako znaménkovou hodnotu, která se může přetočit.

Pořadí argumentů je stejné jako u operátoru odčítání, ticks_diff(ticks1, ticks2) má stejný význam jako ticks1 - ticks2. Hodnoty vrácené funkcemi ticks_ms() atd. se však mohou přetočit, takže přímé použití odčítání na nich povede k nesprávnému výsledku. Proto je potřeba ticks_diff() – implementuje modulární (nebo přesněji kruhovou) aritmetiku, aby produkovala správný výsledek i pro přetočené hodnoty (pokud nejsou od sebe příliš vzdálené, viz níže). Funkce vrací znaménkovou hodnotu v rozsahu [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (což je typická definice rozsahu pro znaménková binární celá čísla v dvojkovém doplňku). Pokud je výsledek záporný, znamená to, že ticks1 nastalo v čase dříve než ticks2. Jinak to znamená, že ticks1 nastalo po ticks2. To platí pouze tehdy, pokud jsou ticks1 a ticks2 od sebe vzdáleny ne více než TICKS_PERIOD/2-1 tiků. Pokud to neplatí, bude vrácen nesprávný výsledek. Konkrétně, pokud jsou dvě hodnoty tiků od sebe vzdáleny o TICKS_PERIOD/2-1 tiků, vrátí funkce tuto hodnotu. Pokud však mezi nimi uplynulo TICKS_PERIOD/2 tiků reálného času, vrátí funkce místo toho -TICKS_PERIOD/2, tj. výsledná hodnota se přetočí do záporného rozsahu možných hodnot.

Neformální zdůvodnění výše uvedených omezení: Představte si, že jste zamčeni v místnosti bez možnosti sledovat plynutí času kromě standardních hodin s 12 dílky. Pokud se nyní podíváte na ciferník a nepodíváte se znovu dalších 13 hodin (např. když na dlouho usnete), pak když se nakonec znovu podíváte, může se vám zdát, že uplynula jen 1 hodina. Abyste se tomuto omylu vyhnuli, dívejte se na hodiny pravidelně. Vaše aplikace by měla dělat totéž. Metafora „příliš dlouhého spánku“ se přímo vztahuje i na chování aplikace: nenechte svou aplikaci provádět jakoukoli jednotlivou úlohu příliš dlouho. Spouštějte úlohy po krocích a mezi nimi provádějte měření času.

ticks_diff() je navržena tak, aby vyhovovala různým vzorům použití, mimo jiné:

  • Dotazování s časovým limitem. V tomto případě je pořadí událostí známé a budete pracovat pouze s kladnými výsledky ticks_diff()

    # 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
    
  • Plánování událostí. V tomto případě může být výsledek ticks_diff() záporný, pokud je událost po termínu:

    # 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)
    

Poznámka: Nepředávejte hodnoty time() do ticks_diff(), měli byste na nich používat běžné matematické operace. Mějte však na paměti, že time() může (a bude) také přetékat. To je známé jako https://en.wikipedia.org/wiki/Year_2038_problem .

time.time() int

Vrací počet sekund jako celé číslo od epochy za předpokladu, že podkladové RTC je nastaveno a udržováno tak, jak je popsáno výše. Pokud RTC není nastaveno, vrací tato funkce počet sekund od referenčního bodu v čase specifického pro port (u vestavěných desek bez RTC zálohovaného baterií obvykle od zapnutí nebo resetu). Pokud chcete vyvíjet přenositelnou aplikaci MicroPythonu, neměli byste se spoléhat na to, že tato funkce poskytuje vyšší než sekundovou přesnost. Pokud potřebujete vyšší přesnost, absolutní časová razítka, použijte time_ns(). Pokud jsou přijatelné relativní časy, použijte funkce ticks_ms() a ticks_us(). Pokud potřebujete kalendářní čas, lepší volbou je gmtime() nebo localtime() bez argumentu.

Rozdíl oproti CPythonu

V CPythonu tato funkce vrací počet sekund od unixové epochy (1970-01-01 00:00 UTC) jako hodnotu s plovoucí desetinnou čárkou, obvykle s mikrosekundovou přesností. Na OpenMV Cam vrací celé číslo s přesností na jednu sekundu – hardware nedokáže v hodnotě float reprezentovat současně dlouhý časový rozsah i přesnost na zlomky sekundy – a epocha se liší podle desky (viz Časová epocha výše). Bez RTC zálohovaného baterií, které bylo nastaveno, místo toho počítá sekundy od zapnutí/resetu.

time.time_ns() int

Podobné jako time(), ale vrací nanosekundy od epochy jako celé číslo (obvykle velké celé číslo, takže bude alokovat na haldě).

Konstruktory

class time.clock

Vrací objekt clock.

Metody

tick() None

Začne sledovat uplynulý čas.

fps() float

Zastaví sledování uplynulého času a vrátí aktuální FPS (snímky za sekundu).

Před voláním této funkce vždy nejprve zavolejte tick.

avg() float

Zastaví sledování uplynulého času a vrátí aktuální průměrný uplynulý čas v milisekundách.

Před voláním této funkce vždy nejprve zavolejte tick.

reset() None

Resetuje objekt clock.