time — funkcje związane z czasem¶
Moduł time zapewnia funkcje do pobierania bieżącej godziny i daty, mierzenia interwałów czasowych oraz do opóźnień.
Epoka czasu: Modele OpenMV Cam oparte na Alif oraz i.MX RT używają epoki POSIX 1970-01-01 00:00:00 UTC. Modele OpenMV Cam oparte na STM32 używają epoki 2000-01-01 00:00:00 UTC. Rok epoki można ustalić w czasie wykonywania za pomocą gmtime(0)[0].
Utrzymywanie rzeczywistej daty/godziny kalendarzowej: Wymaga to zegara czasu rzeczywistego (RTC). Na OpenMV Cam czas systemowy zapewnia obiekt machine.RTC. Bieżący czas kalendarzowy można ustawić za pomocą machine.RTC().datetime(tuple) i jest on utrzymywany przez jeden z poniższych mechanizmów:
Baterię podtrzymującą (opcjonalny element w niektórych modelach OpenMV Cam).
Sieciowy protokół czasu, taki jak
ntptime(wymaga połączenia sieciowego).Ręczne ustawianie przy każdym włączeniu zasilania. RTC jest wówczas zazwyczaj utrzymywany podczas miękkich resetów, ale jest tracony po zaniku zasilania, chyba że zamontowano baterię podtrzymującą.
Jeśli czas kalendarzowy nie jest utrzymywany, poniższe funkcje odwołujące się do bieżącego czasu bezwzględnego nie będą działać zgodnie z oczekiwaniami.
Funkcje¶
- 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]¶
Konwertuje czas secs wyrażony w sekundach od epoki (zobacz powyżej) na 8-elementową krotkę zawierającą:
(year, month, mday, hour, minute, second, weekday, yearday). Jeśli secs nie zostanie podane lub ma wartość None, używany jest bieżący czas z RTC.Funkcja
gmtime()zwraca krotkę daty i czasu w UTC, alocaltime()zwraca krotkę daty i czasu w czasie lokalnym.Format wpisów w 8-elementowej krotce jest następujący:
year zawiera stulecie (na przykład 2014).
month ma zakres 1-12
mday ma zakres 1-31
hour ma zakres 0-23
minute ma zakres 0-59
second ma zakres 0-59
weekday ma zakres 0-6 dla Pon-Niedz
yearday ma zakres 1-366
- time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int¶
Jest to funkcja odwrotna do localtime. Jej argumentem jest pełna 8-elementowa krotka wyrażająca czas zgodnie z localtime. Zwraca liczbę całkowitą będącą liczbą sekund od epoki czasu.
- time.sleep(seconds: float) None¶
Wstrzymuje wykonywanie na podaną liczbę sekund. seconds może być liczbą zmiennoprzecinkową, aby wstrzymać na ułamkową liczbę sekund. Dla dokładniejszych lub wyłącznie całkowitoliczbowych opóźnień użyj funkcji
sleep_ms()isleep_us().Wywołanie
sleep(), w tymsleep(0), gwarantuje wywołanie oczekujących funkcji wywołań zwrotnych.
- time.sleep_ms(ms: int) None¶
Opóźnia o podaną liczbę milisekund, która powinna być dodatnia lub równa 0.
Ta funkcja opóźni o co najmniej podaną liczbę milisekund, ale może trwać dłużej, jeśli musi zostać wykonane inne przetwarzanie, na przykład obsługa przerwań lub inne wątki. Przekazanie 0 dla ms nadal umożliwi wystąpienie tego innego przetwarzania. Dla dokładniejszych opóźnień użyj
sleep_us().Wywołanie
sleep_ms(), w tymsleep_ms(0), gwarantuje wywołanie oczekujących funkcji wywołań zwrotnych.
- time.sleep_us(us: int) None¶
Opóźnia o podaną liczbę mikrosekund, która powinna być dodatnia lub równa 0.
Ta funkcja próbuje zapewnić dokładne opóźnienie wynoszące co najmniej us mikrosekund, ale może trwać dłużej, jeśli system ma do wykonania inne przetwarzanie o wyższym priorytecie.
- time.ticks_ms() int¶
Zwraca rosnący licznik milisekund o dowolnym punkcie odniesienia, który zawija się po pewnej wartości.
Wartość zawinięcia nie jest jawnie udostępniona, ale dla uproszczenia dyskusji będziemy nazywać ją TICKS_MAX. Okres wartości wynosi TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD jest gwarantowaną potęgą dwójki, ale poza tym może różnić się między portami. Ta sama wartość okresu jest używana dla wszystkich funkcji
ticks_ms(),ticks_us(),ticks_cpu()(dla uproszczenia). Zatem funkcje te zwracają wartość z zakresu [0 .. TICKS_MAX] włącznie, czyli łącznie TICKS_PERIOD wartości. Należy pamiętać, że używane są tylko wartości nieujemne. W większości przypadków wartości zwracane przez te funkcje należy traktować jako nieprzejrzyste. Jedynymi dostępnymi dla nich operacjami są funkcjeticks_diff()iticks_add()opisane poniżej.Uwaga: Wykonywanie standardowych operacji matematycznych (+, -) lub operatorów relacyjnych (<, <=, >, >=) bezpośrednio na tych wartościach doprowadzi do nieprawidłowego wyniku. Wykonywanie operacji matematycznych, a następnie przekazywanie ich wyników jako argumentów do
ticks_diff()lubticks_add()również doprowadzi do nieprawidłowych wyników z tych funkcji.
- time.ticks_us() int¶
Tak samo jak
ticks_ms()powyżej, ale w mikrosekundach.
- time.ticks_cpu() int¶
Podobne do
ticks_ms()iticks_us(), ale z najwyższą możliwą rozdzielczością w systemie. Zwykle są to takty zegara CPU i dlatego funkcja została tak nazwana. Nie musi to jednak być zegar CPU, można zamiast niego użyć innego źródła czasu dostępnego w systemie (np. licznika czasu o wysokiej rozdzielczości). Dokładna jednostka czasu (rozdzielczość) tej funkcji nie jest określona na poziomie modułutime, ale dokumentacja konkretnego portu może dostarczyć bardziej szczegółowych informacji. Ta funkcja jest przeznaczona do bardzo precyzyjnych testów wydajności lub bardzo ścisłych pętli czasu rzeczywistego. Unikaj używania jej w kodzie przenośnym. Jest dostępna na wszystkich modelach OpenMV Cam.
- time.ticks_add(ticks: int, delta: int) int¶
Przesuwa wartość ticks o podaną liczbę, która może być dodatnia lub ujemna. Mając wartość ticks, funkcja ta pozwala obliczyć wartość ticks o delta taktów przed nią lub po niej, zgodnie z definicją arytmetyki modularnej wartości taktów (zobacz
ticks_ms()powyżej). Parametr ticks musi być bezpośrednim wynikiem wywołania funkcjiticks_ms(),ticks_us()lubticks_cpu()(lub z poprzedniego wywołaniaticks_add()). Natomiast delta może być dowolną liczbą całkowitą lub wyrażeniem liczbowym.ticks_add()jest przydatne do obliczania terminów dla zdarzeń/zadań. (Uwaga: aby pracować z terminami, musisz używać funkcjiticks_diff().)Przykłady:
# 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¶
Mierzy różnicę taktów między wartościami zwróconymi przez funkcje
ticks_ms(),ticks_us()lubticks_cpu(), jako wartość ze znakiem, która może się zawijać.Kolejność argumentów jest taka sama jak dla operatora odejmowania,
ticks_diff(ticks1, ticks2)ma takie samo znaczenie jakticks1 - ticks2. Jednak wartości zwracane przez funkcjeticks_ms()itp. mogą się zawijać, więc bezpośrednie użycie na nich odejmowania da nieprawidłowy wynik. Dlatego potrzebna jest funkcjaticks_diff(), która implementuje arytmetykę modularną (a dokładniej pierścieniową), aby uzyskać poprawny wynik nawet dla wartości zawijających się (o ile nie są one od siebie zbyt odległe, zobacz poniżej). Funkcja zwraca wartość ze znakiem z zakresu [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (to typowa definicja zakresu dla binarnych liczb całkowitych ze znakiem w kodzie uzupełnień do dwóch). Jeśli wynik jest ujemny, oznacza to, że ticks1 wystąpiło wcześniej w czasie niż ticks2. W przeciwnym razie oznacza to, że ticks1 wystąpiło po ticks2. Obowiązuje to tylko wtedy, gdy ticks1 i ticks2 są od siebie oddalone o nie więcej niż TICKS_PERIOD/2-1 taktów. Jeśli ten warunek nie jest spełniony, zostanie zwrócony nieprawidłowy wynik. W szczególności, jeśli dwie wartości taktów są oddalone o TICKS_PERIOD/2-1 taktów, funkcja zwróci tę wartość. Jeśli jednak między nimi minęło TICKS_PERIOD/2 taktów czasu rzeczywistego, funkcja zwróci zamiast tego -TICKS_PERIOD/2, tzn. wartość wyniku zawinie się do ujemnego zakresu możliwych wartości.Nieformalne uzasadnienie powyższych ograniczeń: Załóżmy, że jesteś zamknięty w pokoju bez możliwości śledzenia upływu czasu poza standardowym 12-godzinnym zegarem z 12 podziałkami. Wtedy, jeśli spojrzysz na tarczę teraz, a następnie nie spojrzysz ponownie przez kolejne 13 godzin (np. jeśli zapadniesz w długi sen), to gdy w końcu spojrzysz ponownie, może ci się wydawać, że minęła tylko 1 godzina. Aby uniknąć tego błędu, po prostu patrz na zegar regularnie. Twoja aplikacja powinna robić to samo. Metafora „zbyt długiego snu” odwzorowuje się również bezpośrednio na zachowanie aplikacji: nie pozwól, aby Twoja aplikacja wykonywała jakiekolwiek pojedyncze zadanie zbyt długo. Wykonuj zadania w krokach i mierz czas pomiędzy nimi.
ticks_diff()zostało zaprojektowane tak, aby obsługiwać różne wzorce użycia, między innymi:Odpytywanie z limitem czasu. W tym przypadku kolejność zdarzeń jest znana i będziesz mieć do czynienia tylko z dodatnimi wynikami
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
Planowanie zdarzeń. W tym przypadku wynik
ticks_diff()może być ujemny, jeśli zdarzenie jest spóźnione:# 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)
Uwaga: Nie przekazuj wartości
time()doticks_diff(), powinieneś używać na nich normalnych operacji matematycznych. Pamiętaj jednak, żetime()może (i będzie) również się przepełniać. Jest to znane jako https://en.wikipedia.org/wiki/Year_2038_problem .
- time.time() int¶
Zwraca liczbę sekund, jako liczbę całkowitą, od epoki, zakładając, że bazowy RTC jest ustawiony i utrzymywany w sposób opisany powyżej. Jeśli RTC nie jest ustawiony, funkcja ta zwraca liczbę sekund od specyficznego dla portu punktu odniesienia w czasie (w przypadku płytek wbudowanych bez RTC z podtrzymaniem bateryjnym zwykle od włączenia zasilania lub resetu). Jeśli chcesz tworzyć przenośną aplikację MicroPython, nie powinieneś polegać na tej funkcji w celu uzyskania precyzji wyższej niż jedna sekunda. Jeśli potrzebujesz wyższej precyzji, bezwzględnych znaczników czasu, użyj
time_ns(). Jeśli akceptowalne są czasy względne, użyj funkcjiticks_ms()iticks_us(). Jeśli potrzebujesz czasu kalendarzowego, lepszym wyborem jestgmtime()lublocaltime()bez argumentu.Różnica względem CPython
W CPython funkcja ta zwraca liczbę sekund od epoki Unix (1970-01-01 00:00 UTC) jako wartość zmiennoprzecinkową, zwykle z precyzją mikrosekundową. Na OpenMV Cam zwraca liczbę całkowitą z precyzją jednosekundową – sprzęt nie jest w stanie reprezentować jednocześnie szerokiego zakresu czasu i precyzji poniżej sekundy w liczbie zmiennoprzecinkowej – a epoka różni się w zależności od płytki (zobacz Epoka czasu powyżej). Bez ustawionego RTC z podtrzymaniem bateryjnym funkcja zamiast tego zlicza sekundy od włączenia zasilania/resetu.
Konstruktory¶
- class time.clock¶
Zwraca obiekt zegara.
Metody¶
- fps() float¶
Zatrzymuje śledzenie upływającego czasu i zwraca bieżącą wartość FPS (klatek na sekundę).
Zawsze wywołuj najpierw
tickprzed wywołaniem tej funkcji.