time — funcții legate de timp¶
Modulul time oferă funcții pentru obținerea orei și datei curente, pentru măsurarea intervalelor de timp și pentru întârzieri.
Epoca de timp: OpenMV Cam bazate pe Alif și i.MX RT folosesc epoca POSIX de la 1970-01-01 00:00:00 UTC. OpenMV Cam bazate pe STM32 folosesc o epocă de la 2000-01-01 00:00:00 UTC. Anul epocii poate fi determinat la momentul execuției cu gmtime(0)[0].
Menținerea datei/orei calendaristice reale: Aceasta necesită un ceas de timp real (RTC). Pe OpenMV Cam, timpul sistemului este furnizat de obiectul machine.RTC. Ora calendaristică curentă poate fi setată cu machine.RTC().datetime(tuple) și este menținută prin una dintre următoarele:
O baterie de rezervă (o componentă opțională pe unele OpenMV Cam).
Un protocol de timp în rețea, cum ar fi
ntptime(necesită o conexiune la rețea).Setarea manuală la fiecare pornire. RTC-ul este apoi de obicei menținut între resetările soft, dar se pierde la întreruperea alimentării, cu excepția cazului în care este montată o baterie de rezervă.
Dacă ora calendaristică nu este menținută, funcțiile de mai jos care fac referire la timpul absolut curent nu se vor comporta conform așteptărilor.
Funcții¶
- 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]¶
Convertește timpul secs exprimat în secunde de la epocă (vezi mai sus) într-un tuplu de 8 elemente care conține:
(year, month, mday, hour, minute, second, weekday, yearday). Dacă secs nu este furnizat sau este None, atunci se folosește ora curentă din RTC.Funcția
gmtime()returnează un tuplu dată-oră în UTC, iarlocaltime()returnează un tuplu dată-oră în ora locală.Formatul intrărilor din tuplul de 8 elemente este:
year include secolul (de exemplu 2014).
month este 1-12
mday este 1-31
hour este 0-23
minute este 0-59
second este 0-59
weekday este 0-6 pentru luni-duminică
yearday este 1-366
- time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int¶
Aceasta este funcția inversă a lui localtime. Argumentul ei este un tuplu complet de 8 elemente care exprimă un timp conform localtime. Returnează un întreg care reprezintă numărul de secunde de la epoca de timp.
- time.sleep(seconds: float) None¶
Așteaptă (sleep) pentru numărul dat de secunde. seconds poate fi un număr în virgulă mobilă, pentru a aștepta un număr fracționar de secunde. Pentru întârzieri mai fine sau exclusiv întregi, folosiți funcțiile
sleep_ms()șisleep_us().Apelarea
sleep(), inclusivsleep(0), garantează apelarea funcțiilor de retroapelare (callback) în așteptare.
- time.sleep_ms(ms: int) None¶
Întârzie pentru numărul dat de milisecunde, care trebuie să fie pozitiv sau 0.
Această funcție va întârzia cel puțin numărul dat de milisecunde, dar poate dura mai mult dacă trebuie să aibă loc alte procesări, de exemplu gestionarele de întreruperi sau alte fire de execuție. Transmiterea valorii 0 pentru ms va permite totuși desfășurarea acestor alte procesări. Folosiți
sleep_us()pentru întârzieri mai precise.Apelarea
sleep_ms(), inclusivsleep_ms(0), garantează apelarea funcțiilor de retroapelare (callback) în așteptare.
- time.sleep_us(us: int) None¶
Întârzie pentru numărul dat de microsecunde, care trebuie să fie pozitiv sau 0.
Această funcție încearcă să ofere o întârziere precisă de cel puțin us microsecunde, dar poate dura mai mult dacă sistemul are alte procesări cu prioritate mai mare de efectuat.
- time.ticks_ms() int¶
Returnează un contor de milisecunde crescător cu un punct de referință arbitrar, care se reia (wrap around) după o anumită valoare.
Valoarea de reluare (wrap-around) nu este expusă explicit, dar ne vom referi la ea ca TICKS_MAX pentru a simplifica discuția. Perioada valorilor este TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD este garantat a fi o putere a lui doi, dar în rest poate diferi de la port la port. Aceeași valoare a perioadei este folosită pentru toate funcțiile
ticks_ms(),ticks_us(),ticks_cpu()(pentru simplitate). Astfel, aceste funcții vor returna o valoare în intervalul [0 .. TICKS_MAX], inclusiv, în total TICKS_PERIOD valori. Rețineți că se folosesc doar valori nenegative. În cea mai mare parte, ar trebui să tratați valorile returnate de aceste funcții ca fiind opace. Singurele operații disponibile pentru ele sunt funcțiileticks_diff()șiticks_add()descrise mai jos.Notă: Efectuarea de operații matematice standard (+, -) sau a operatorilor relaționali (<, <=, >, >=) direct asupra acestor valori va duce la rezultate invalide. Efectuarea de operații matematice și apoi transmiterea rezultatelor lor ca argumente către
ticks_diff()sauticks_add()va duce, de asemenea, la rezultate invalide din partea acestor ultime funcții.
- time.ticks_us() int¶
La fel ca
ticks_ms()de mai sus, dar în microsecunde.
- time.ticks_cpu() int¶
Similar cu
ticks_ms()șiticks_us(), dar cu cea mai mare rezoluție posibilă din sistem. De obicei aceasta este reprezentată de ciclurile CPU, motiv pentru care funcția este denumită astfel. Dar nu trebuie neapărat să fie un ceas CPU; poate fi folosită în schimb o altă sursă de sincronizare disponibilă în sistem (de exemplu, un temporizator de înaltă rezoluție). Unitatea exactă de timp (rezoluția) a acestei funcții nu este specificată la nivelul modululuitime, dar documentația pentru un anumit port poate oferi informații mai specifice. Această funcție este destinată evaluării comparative (benchmarking) foarte fine sau buclelor în timp real foarte strânse. Evitați să o folosiți în cod portabil. Este disponibilă pe toate OpenMV Cam.
- time.ticks_add(ticks: int, delta: int) int¶
Decalează valoarea ticks cu un număr dat, care poate fi pozitiv sau negativ. Pentru o valoare ticks dată, această funcție permite calcularea valorii ticks cu delta ticks înainte sau după aceasta, conform definiției aritmeticii modulare a valorilor de tip tick (vezi
ticks_ms()mai sus). Parametrul ticks trebuie să fie un rezultat direct al apelului funcțiilorticks_ms(),ticks_us()sauticks_cpu()(sau dintr-un apel anterior laticks_add()). Totuși, delta poate fi un număr întreg arbitrar sau o expresie numerică.ticks_add()este utilă pentru calcularea termenelor-limită (deadline) pentru evenimente/sarcini. (Notă: trebuie să folosiți funcțiaticks_diff()pentru a lucra cu termene-limită.)Exemple:
# 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¶
Măsoară diferența de ticks dintre valorile returnate de funcțiile
ticks_ms(),ticks_us()sauticks_cpu(), sub formă de valoare cu semn care se poate relua (wrap around).Ordinea argumentelor este aceeași ca pentru operatorul de scădere,
ticks_diff(ticks1, ticks2)are aceeași semnificație caticks1 - ticks2. Totuși, valorile returnate de funcțiileticks_ms()etc. se pot relua (wrap around), așa că utilizarea directă a scăderii asupra lor va produce un rezultat incorect. De aceea este necesarăticks_diff(); ea implementează aritmetica modulară (sau mai exact, inelară) pentru a produce un rezultat corect chiar și pentru valorile reluate (atât timp cât nu sunt prea îndepărtate între ele, vezi mai jos). Funcția returnează o valoare cu semn în intervalul [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (aceasta este o definiție tipică de interval pentru întregi binari cu semn în complement față de doi). Dacă rezultatul este negativ, înseamnă că ticks1 a avut loc mai devreme în timp decât ticks2. În caz contrar, înseamnă că ticks1 a avut loc după ticks2. Acest lucru este valabil doar dacă ticks1 și ticks2 sunt la o distanță de cel mult TICKS_PERIOD/2-1 ticks unul de altul. Dacă acest lucru nu se respectă, va fi returnat un rezultat incorect. În mod specific, dacă două valori tick sunt la o distanță de TICKS_PERIOD/2-1 ticks, acea valoare va fi returnată de funcție. Totuși, dacă TICKS_PERIOD/2 de ticks de timp real au trecut între ele, funcția va returna în schimb -TICKS_PERIOD/2, adică valoarea rezultatului se va relua în intervalul negativ al valorilor posibile.Justificarea informală a constrângerilor de mai sus: Să presupunem că sunteți închis într-o cameră fără niciun mijloc de a monitoriza trecerea timpului, cu excepția unui ceas standard cu 12 diviziuni. Atunci, dacă vă uitați la cadran acum și nu vă mai uitați timp de încă 13 ore (de exemplu, dacă adormiți pentru un somn lung), atunci când în sfârșit vă uitați din nou, vi se poate părea că a trecut doar 1 oră. Pentru a evita această greșeală, uitați-vă la ceas în mod regulat. Aplicația dvs. ar trebui să facă același lucru. Metafora „somn prea lung” se aplică direct și comportamentului aplicației: nu lăsați aplicația să ruleze nicio sarcină individuală prea mult timp. Rulați sarcinile în pași și efectuați evidența timpului între ei.
ticks_diff()este concepută pentru a se adapta la diverse tipare de utilizare, printre care:Interogare (polling) cu timeout. În acest caz, ordinea evenimentelor este cunoscută și veți avea de-a face doar cu rezultate pozitive ale
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
Programarea evenimentelor. În acest caz, rezultatul
ticks_diff()poate fi negativ dacă un eveniment este întârziat:# 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)
Notă: Nu transmiteți valori
time()cătreticks_diff(), ci ar trebui să folosiți operații matematice normale asupra lor. Dar rețineți cătime()poate (și va) depăși (overflow). Acest lucru este cunoscut sub numele de https://en.wikipedia.org/wiki/Year_2038_problem .
- time.time() int¶
Returnează numărul de secunde, sub formă de întreg, de la epocă, presupunând că RTC-ul subiacent este setat și menținut conform descrierii de mai sus. Dacă un RTC nu este setat, această funcție returnează numărul de secunde de la un punct de referință în timp specific portului (pentru plăcile încorporate fără un RTC cu baterie de rezervă, de obicei de la pornire sau resetare). Dacă doriți să dezvoltați o aplicație MicroPython portabilă, nu ar trebui să vă bazați pe această funcție pentru a oferi o precizie mai mare de o secundă. Dacă aveți nevoie de precizie mai mare, marcaje de timp absolute, folosiți
time_ns(). Dacă timpii relativi sunt acceptabili, atunci folosiți funcțiileticks_ms()șiticks_us(). Dacă aveți nevoie de timp calendaristic,gmtime()saulocaltime()fără argument este o alegere mai bună.Diferență față de CPython
În CPython această funcție returnează numărul de secunde de la epoca Unix (1970-01-01 00:00 UTC) sub formă de valoare în virgulă mobilă, de obicei cu precizie de microsecunde. Pe OpenMV Cam returnează un întreg cu precizie de o secundă – hardware-ul nu poate reprezenta simultan un interval de timp mare și o precizie sub-secundă într-un float – iar epoca diferă în funcție de placă (vezi Epoca de timp de mai sus). Fără un RTC cu baterie de rezervă care a fost setat, numără în schimb secundele de la pornire/resetare.
Constructori¶
- class time.clock¶
Returnează un obiect clock.
Metode¶
- fps() float¶
Oprește urmărirea timpului scurs și returnează valoarea FPS curentă (cadre pe secundă).
Apelați întotdeauna mai întâi
tickînainte de a apela această funcție.