3.2. Timing¶
Modul time mengelompokkan fungsi-fungsi untuk tidur (menjeda skrip selama durasi tertentu) dan untuk mengukur berapa lama sesuatu berlangsung. Pada mikrokontroler, ini bukan sekadar fitur tambahan; ini adalah cara skrip mengatur interaksi dengan dunia luar -- berapa lama menahan pin pada kondisi tinggi, berapa lama menunggu antar sampel, berapa lama sejak tombol terakhir ditekan.
3.2.1. Sleeping¶
Tiga fungsi sleep memblokir skrip selama durasi yang diminta:
time.sleep(s)-- jeda selamasdetik. Menerima float, sehinggatime.sleep(0.5)menunggu setengah detik.time.sleep_ms(ms)-- jeda selamamsmilidetik. Argumen harus berupa integer.time.sleep_us(us)-- jeda selamausmikrodetik.
import time
print("now")
time.sleep_ms(500)
print("half a second later")
Gunakan time.sleep_ms() untuk kebutuhan "tunggu sebentar" biasa dan time.sleep_us() hanya ketika timing harus ketat. time.sleep() biasa juga baik-baik saja, tetapi varian argumen integer menghindari konversi floating-point dan lebih mudah dibaca untuk interval pendek.
Sleep adalah panggilan pemblokiran. Selama skrip sedang tidur, skrip tidak melakukan hal lain -- tidak membaca pin, tidak melayani UART, tidak memperbarui LED. Gunakan sleep ketika pemblokiran adalah yang Anda inginkan; gunakan pola non-blocking di bawah ini ketika bukan itu yang Anda inginkan.
3.2.2. Membaca jam¶
Untuk mengukur berapa lama suatu bagian kode berlangsung, baca jam sebelum dan sesudahnya:
time.ticks_ms()-- nilai tick saat ini dalam milidetik.time.ticks_us()-- sama tetapi dalam mikrodetik.
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_ms() - start
print("took", elapsed, "ms")
Ini bekerja sebagian besar waktu. Penghitung tick bergulir (kembali ke nol) setelah sejumlah besar tick yang terbatas, dan pengurangan sederhana di sekitar guliran tersebut menghasilkan angka negatif atau positif yang sangat salah.
Penghitung tick kembali ke nol ketika mencapai batas integer. Pengurangan sederhana di sekitar guliran tersebut adalah salah.¶
3.2.3. ticks_diff¶
Untuk mendapatkan tick yang telah berlalu dengan benar, bahkan di sekitar guliran, gunakan time.ticks_diff():
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_diff(time.ticks_ms(), start)
print("took", elapsed, "ms")
Urutan argumen adalah ticks_diff(later, earlier) -- ekspresi ini dibaca "seberapa jauh later setelah earlier". Hasilnya adalah integer bertanda; positif berarti later memang lebih belakangan, negatif berarti ia ada di masa lalu. Fungsi ini menangani guliran secara internal.
Tip
Selalu pasangkan time.ticks_ms() / time.ticks_us() dengan time.ticks_diff(). Pengurangan mentah benar sebagian besar waktu; waktu di mana ia salah adalah ketika skrip telah berjalan lama -- biasanya saat yang paling buruk untuk men-debug masalah timing.
3.2.4. Timing non-blocking¶
Skrip mikrokontroler biasanya memiliki lebih dari satu hal yang harus dilakukan "pada saat yang sama": membaca tombol, mengedipkan LED, melakukan polling sensor, melayani UART. sleep tidak berguna untuk itu -- selama satu sleep berjalan, tugas-tugas lain terhenti.
Pola standarnya adalah menyimpan deadline per tugas, dan memeriksa setiap loop apakah deadline telah terlewati. Keputusan untuk bertindak dibangun di atas time.ticks_diff(), bukan pada sleep:
import time
next_blink = time.ticks_ms()
next_poll = time.ticks_ms()
state = False
while True:
now = time.ticks_ms()
if time.ticks_diff(now, next_blink) >= 0:
state = not state
# update LED here
next_blink = time.ticks_add(next_blink, 500)
if time.ticks_diff(now, next_poll) >= 0:
# read sensor here
next_poll = time.ticks_add(next_poll, 100)
LED berkedip setiap 500 ms, sensor di-polling setiap 100 ms, dan tidak ada tugas yang memblokir yang lain. time.ticks_add() memajukan deadline dengan kenaikan tertentu tanpa masalah dengan guliran.
Bentuk ini -- satu loop, beberapa tugas berjadwal, tanpa sleep di dalam tubuhnya -- muncul di mana-mana dalam kode perangkat keras: debouncing perangkat lunak pada sakelar, sekuensing motor, timeout baca UART. Tiga fungsi yang sama (time.ticks_ms(), time.ticks_diff(), time.ticks_add()) mencakup setiap kasus.