time --- fungsi-fungsi terkait waktu

Modul time menyediakan fungsi untuk mendapatkan waktu dan tanggal saat ini, mengukur interval waktu, serta untuk penundaan.

Epoch Waktu: OpenMV Cam berbasis Alif dan i.MX RT menggunakan epoch POSIX yaitu 1970-01-01 00:00:00 UTC. OpenMV Cam berbasis STM32 menggunakan epoch 2000-01-01 00:00:00 UTC. Tahun epoch dapat ditentukan saat runtime dengan gmtime(0)[0].

Mempertahankan tanggal/waktu kalender aktual: Ini memerlukan Real Time Clock (RTC). Pada OpenMV Cam, waktu sistem disediakan oleh objek machine.RTC. Waktu kalender saat ini dapat diatur dengan machine.RTC().datetime(tuple) dan dipertahankan oleh salah satu dari:

  • Baterai cadangan (komponen opsional pada beberapa OpenMV Cam).

  • Protokol waktu berbasis jaringan seperti ntptime (memerlukan koneksi jaringan).

  • Mengaturnya secara manual setiap kali dinyalakan. RTC kemudian biasanya dipertahankan saat soft reset, tetapi akan hilang saat kehilangan daya kecuali jika baterai cadangan dipasang.

Jika waktu kalender tidak dipertahankan, fungsi-fungsi di bawah ini yang merujuk ke waktu absolut saat ini tidak akan berperilaku sebagaimana mestinya.

Fungsi

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]

Mengonversi waktu secs yang dinyatakan dalam detik sejak Epoch (lihat di atas) menjadi 8-tuple yang berisi: (year, month, mday, hour, minute, second, weekday, yearday) Jika secs tidak diberikan atau None, maka waktu saat ini dari RTC yang digunakan.

Fungsi gmtime() mengembalikan tuple tanggal-waktu dalam UTC, dan localtime() mengembalikan tuple tanggal-waktu dalam waktu lokal.

Format entri dalam 8-tuple adalah:

  • year mencakup abad (misalnya 2014).

  • month adalah 1-12

  • mday adalah 1-31

  • hour adalah 0-23

  • minute adalah 0-59

  • second adalah 0-59

  • weekday adalah 0-6 untuk Sen-Min

  • yearday adalah 1-366

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

Ini adalah fungsi kebalikan dari localtime. Argumennya adalah 8-tuple lengkap yang menyatakan waktu sesuai dengan localtime. Fungsi ini mengembalikan integer yang merupakan jumlah detik sejak epoch waktu.

time.sleep(seconds: float) None

Tidur selama jumlah detik yang diberikan. seconds dapat berupa angka floating-point, untuk tidur selama sebagian detik. Untuk penundaan yang lebih halus atau hanya integer, gunakan fungsi sleep_ms() dan sleep_us().

Memanggil sleep(), termasuk sleep(0) dijamin akan memanggil fungsi callback yang tertunda.

time.sleep_ms(ms: int) None

Menunda selama jumlah milidetik yang diberikan, harus positif atau 0.

Fungsi ini akan menunda setidaknya selama jumlah milidetik yang diberikan, tetapi mungkin memakan waktu lebih lama jika pemrosesan lain harus berlangsung, misalnya handler interupsi atau thread lain. Meneruskan 0 untuk ms tetap memungkinkan pemrosesan lain ini terjadi. Gunakan sleep_us() untuk penundaan yang lebih presisi.

Memanggil sleep_ms(), termasuk sleep_ms(0) dijamin akan memanggil fungsi callback yang tertunda.

time.sleep_us(us: int) None

Menunda selama jumlah mikrodetik yang diberikan, harus positif atau 0.

Fungsi ini berusaha memberikan penundaan akurat setidaknya selama us mikrodetik, tetapi mungkin memakan waktu lebih lama jika sistem memiliki pemrosesan berprioritas lebih tinggi yang harus dilakukan.

time.ticks_ms() int

Mengembalikan penghitung milidetik yang terus bertambah dengan titik referensi sembarang, yang akan memutar balik setelah mencapai nilai tertentu.

Nilai wrap-around tidak diekspos secara eksplisit, tetapi kita akan menyebutnya sebagai TICKS_MAX untuk menyederhanakan diskusi. Periode nilainya adalah TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD dijamin merupakan pangkat dua, tetapi selain itu dapat berbeda dari port ke port. Nilai periode yang sama digunakan untuk semua fungsi ticks_ms(), ticks_us(), ticks_cpu() (untuk kesederhanaan). Dengan demikian, fungsi-fungsi ini akan mengembalikan nilai dalam rentang [0 .. TICKS_MAX], inklusif, total TICKS_PERIOD nilai. Perhatikan bahwa hanya nilai non-negatif yang digunakan. Sebagian besar, Anda harus memperlakukan nilai yang dikembalikan oleh fungsi-fungsi ini sebagai nilai buram. Satu-satunya operasi yang tersedia untuk nilainya adalah fungsi ticks_diff() dan ticks_add() yang dijelaskan di bawah ini.

Catatan: Melakukan operasi matematika standar (+, -) atau operator relasional (<, <=, >, >=) langsung pada nilai ini akan menghasilkan hasil yang tidak valid. Melakukan operasi matematika dan kemudian meneruskan hasilnya sebagai argumen ke ticks_diff() atau ticks_add() juga akan menghasilkan hasil yang tidak valid dari fungsi-fungsi tersebut.

time.ticks_us() int

Sama seperti ticks_ms() di atas, tetapi dalam mikrodetik.

time.ticks_cpu() int

Mirip dengan ticks_ms() dan ticks_us(), tetapi dengan resolusi tertinggi yang mungkin dalam sistem. Ini biasanya adalah clock CPU, itulah mengapa fungsinya diberi nama seperti itu. Namun tidak harus berupa clock CPU, sumber waktu lain yang tersedia dalam sistem (misalnya timer resolusi tinggi) dapat digunakan sebagai gantinya. Satuan waktu tepat (resolusi) dari fungsi ini tidak ditentukan di tingkat modul time, tetapi dokumentasi untuk port tertentu mungkin memberikan informasi yang lebih spesifik. Fungsi ini dimaksudkan untuk benchmarking yang sangat halus atau loop real-time yang sangat ketat. Hindari penggunaannya dalam kode portabel. Fungsi ini tersedia di semua OpenMV Cam.

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

Menggeser nilai ticks dengan jumlah tertentu, yang dapat berupa positif atau negatif. Diberikan nilai ticks, fungsi ini memungkinkan penghitungan nilai ticks delta ticks sebelum atau sesudahnya, mengikuti definisi aritmetika modular nilai tick (lihat ticks_ms() di atas). Parameter ticks harus berupa hasil langsung dari pemanggilan fungsi ticks_ms(), ticks_us(), atau ticks_cpu() (atau dari pemanggilan ticks_add() sebelumnya). Namun, delta dapat berupa integer sembarang atau ekspresi numerik. ticks_add() berguna untuk menghitung tenggat waktu untuk event/tugas. (Catatan: Anda harus menggunakan fungsi ticks_diff() untuk bekerja dengan tenggat waktu.)

Contoh:

# 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

Mengukur selisih ticks antara nilai yang dikembalikan dari fungsi ticks_ms(), ticks_us(), atau ticks_cpu(), sebagai nilai bertanda yang dapat memutar balik.

Urutan argumen sama dengan operator pengurangan, ticks_diff(ticks1, ticks2) memiliki arti yang sama dengan ticks1 - ticks2. Namun, nilai yang dikembalikan oleh fungsi ticks_ms(), dst. mungkin memutar balik, sehingga menggunakan pengurangan langsung pada nilai tersebut akan menghasilkan hasil yang salah. Itulah mengapa ticks_diff() diperlukan; fungsi ini mengimplementasikan aritmetika modular (lebih spesifiknya, ring) untuk menghasilkan hasil yang benar bahkan untuk nilai wrap-around (selama nilainya tidak terlalu jauh satu sama lain, lihat di bawah). Fungsi ini mengembalikan nilai bertanda dalam rentang [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (itu adalah definisi rentang tipikal untuk integer biner bertanda komplemen dua). Jika hasilnya negatif, berarti ticks1 terjadi lebih awal dari ticks2. Jika tidak, berarti ticks1 terjadi setelah ticks2. Ini berlaku hanya jika ticks1 dan ticks2 berjarak tidak lebih dari TICKS_PERIOD/2-1 ticks satu sama lain. Jika tidak, hasil yang salah akan dikembalikan. Secara khusus, jika dua nilai tick berjarak TICKS_PERIOD/2-1 ticks, nilai tersebut akan dikembalikan oleh fungsi. Namun, jika TICKS_PERIOD/2 ticks waktu nyata telah berlalu di antara keduanya, fungsi akan mengembalikan -TICKS_PERIOD/2 sebagai gantinya, yaitu nilai hasil akan memutar balik ke rentang negatif dari nilai-nilai yang mungkin.

Alasan informal dari batasan di atas: Misalkan Anda terkunci di sebuah ruangan tanpa cara untuk memantau berlalunya waktu kecuali jam standar 12 angka. Kemudian jika Anda melihat jam sekarang, dan tidak melihat lagi selama 13 jam berikutnya (misalnya, jika Anda tertidur panjang), maka ketika Anda akhirnya melihat lagi, mungkin tampak bagi Anda bahwa hanya 1 jam yang telah berlalu. Untuk menghindari kesalahan ini, cukup lihat jam secara teratur. Aplikasi Anda harus melakukan hal yang sama. Metafora "tidur terlalu lama" juga secara langsung memetakan perilaku aplikasi: jangan biarkan aplikasi Anda menjalankan satu tugas terlalu lama. Jalankan tugas dalam langkah-langkah, dan lakukan pencatatan waktu di antaranya.

ticks_diff() dirancang untuk mengakomodasi berbagai pola penggunaan, di antaranya:

  • Polling dengan timeout. Dalam kasus ini, urutan event diketahui, dan Anda hanya akan menangani hasil positif dari 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
    
  • Penjadwalan event. Dalam kasus ini, hasil ticks_diff() mungkin negatif jika suatu event terlambat:

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

Catatan: Jangan teruskan nilai time() ke ticks_diff(), gunakan operasi matematika normal untuk nilainya. Namun perhatikan bahwa time() juga bisa (dan akan) overflow. Ini dikenal sebagai https://en.wikipedia.org/wiki/Year_2038_problem .

time.time() int

Mengembalikan jumlah detik, sebagai integer, sejak Epoch, dengan asumsi bahwa RTC yang mendasarinya telah diatur dan dipertahankan seperti yang dijelaskan di atas. Jika RTC tidak diatur, fungsi ini mengembalikan jumlah detik sejak titik referensi waktu khusus port (untuk board embedded tanpa RTC berbaterai, biasanya sejak dinyalakan atau direset). Jika Anda ingin mengembangkan aplikasi MicroPython yang portabel, Anda tidak boleh mengandalkan fungsi ini untuk memberikan presisi lebih dari satu detik. Jika Anda membutuhkan presisi lebih tinggi dengan stempel waktu absolut, gunakan time_ns(). Jika waktu relatif dapat diterima, gunakan fungsi ticks_ms() dan ticks_us(). Jika Anda membutuhkan waktu kalender, gmtime() atau localtime() tanpa argumen adalah pilihan yang lebih baik.

Perbedaan dengan CPython

Dalam CPython, fungsi ini mengembalikan jumlah detik sejak Unix epoch (1970-01-01 00:00 UTC) sebagai nilai floating-point, biasanya dengan presisi mikrodetik. Pada OpenMV Cam, fungsi ini mengembalikan integer dengan presisi satu detik -- perangkat keras tidak dapat merepresentasikan rentang waktu yang panjang sekaligus presisi sub-detik dalam float -- dan epoch berbeda menurut board (lihat Epoch Waktu di atas). Tanpa RTC berbaterai yang telah diatur, fungsi ini menghitung detik sejak dinyalakan/direset.

time.time_ns() int

Mirip dengan time() tetapi mengembalikan nanodetik sejak Epoch, sebagai integer (biasanya integer besar, sehingga akan mengalokasikan di heap).

Konstruktor

class time.clock

Mengembalikan objek clock.

Metode

tick() None

Mulai melacak waktu yang telah berlalu.

fps() float

Menghentikan pelacakan waktu yang telah berlalu dan mengembalikan FPS (frame per detik) saat ini.

Selalu panggil tick terlebih dahulu sebelum memanggil fungsi ini.

avg() float

Menghentikan pelacakan waktu yang telah berlalu dan mengembalikan rata-rata waktu yang berlalu saat ini dalam milidetik.

Selalu panggil tick terlebih dahulu sebelum memanggil fungsi ini.

reset() None

Mereset objek clock.