3.2. Zamanlama¶
time modülü, uyumak (betiği bilinen bir süre boyunca duraklatmak) ve bir şeyin ne kadar sürdüğünü ölçmek için kullanılan işlevleri bir araya getirir. Bir mikrodenetleyicide bunlar olsa iyi olur türünden şeyler değildir; betiğin dış dünyayla etkileşimlerini bunlarla ayarladığı yollardır – bir pinin ne kadar süre yüksek tutulacağı, örnekler arasında ne kadar beklenileceği, bir düğmeye en son ne kadar süre önce basıldığı.
3.2.1. Uyumak¶
Üç uyku işlevi betiği istenen süre boyunca engeller:
time.sleep(s)–ssaniye duraklat. Bir kayan noktalı sayı kabul eder, yanitime.sleep(0.5)yarım saniye bekler.time.sleep_ms(ms)–msmilisaniye duraklat. Argüman bir tamsayı olmalıdır.time.sleep_us(us)–usmikrosaniye duraklat.
import time
print("now")
time.sleep_ms(500)
print("half a second later")
Tipik “biraz bekle” ihtiyaçları için time.sleep_ms() kullanın ve yalnızca zamanlamanın sıkı olması gerektiğinde time.sleep_us() kullanın. Sade time.sleep() de gayet iyidir, ancak tamsayı argümanlı varyantlar kayan noktalı sayı dönüşümünden kaçınır ve kısa aralıklar için daha doğal okunur.
Uyku, engelleyici bir çağrıdır. Betik uyurken başka hiçbir şey yapmaz – bir pini okumaz, bir UART’a hizmet vermez, bir LED’i güncellemez. Engelleme istediğiniz şey olduğunda sleep‘e başvurun; olmadığında ise aşağıdaki engellemeyen deseni kullanın.
3.2.2. Saati okumak¶
Bir kod parçasının ne kadar sürdüğünü ölçmek için, öncesinde ve sonrasında saati okuyun:
time.ticks_ms()– milisaniye cinsinden mevcut tik değeri.time.ticks_us()– mikrosaniye cinsinden aynısı.
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_ms() - start
print("took", elapsed, "ms")
Bu, çoğu zaman işe yarar. Tik sayacı, büyük ama sonlu bir tik sayısından sonra başa döner (sıfıra geri sarar) ve bu sarmanın ötesinde yapılan saf çıkarma, son derece yanlış bir negatif veya pozitif sayı üretir.
Tik sayacı tamsayı sınırına ulaştığında sıfıra geri döner. Bu sarmanın ötesinde yapılan sade bir çıkarma yanlıştır.¶
3.2.3. ticks_diff¶
Sarma boyunca bile, geçen tikleri doğru almak için time.ticks_diff() kullanın:
import time
start = time.ticks_ms()
do_work()
elapsed = time.ticks_diff(time.ticks_ms(), start)
print("took", elapsed, "ms")
Argüman sırası ticks_diff(later, earlier) şeklindedir – ifade “later, earlier‘dan ne kadar sonradır” diye okunur. Sonuç işaretli bir tamsayıdır; pozitif later‘ın gerçekten daha sonra olduğu, negatif ise geçmişte olduğu anlamına gelir. İşlev sarmayı dahili olarak ele alır.
Tüyo
time.ticks_ms() / time.ticks_us() işlevlerini her zaman time.ticks_diff() ile birlikte kullanın. Ham çıkarma çoğu zaman doğrudur; yanlış olduğu zaman ise bir betik uzun süredir çalışıyorken ortaya çıkar – ki bu genellikle bir zamanlama aksaklığının hatalarını ayıklamak için en kötü zamandır.
3.2.4. Engellemeyen zamanlama¶
Bir mikrodenetleyici betiğinin genellikle “aynı anda” yapması gereken birden fazla şey vardır: bir düğmeyi okumak, bir LED’i yakıp söndürmek, bir sensörü yoklamak, bir UART’a hizmet vermek. sleep bunun için iyi değildir – bir sleep çalışırken diğer görevler durmuştur.
Standart desen, her görev için bir son teslim süresi (deadline) tutmak ve her döngüde son teslim süresinin geçip geçmediğini kontrol etmektir. Harekete geçme kararı sleep üzerine değil, her zaman time.ticks_diff() üzerine kurulur:
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 her 500 ms’de bir değişir, sensör her 100 ms’de bir yoklanır ve hiçbir görev diğerini engellemez. time.ticks_add() bir son teslim süresini, sarmaya takılmadan bilinen bir artış kadar ilerletir.
Bu şekil – tek bir döngü, birkaç zamanlanmış görev, gövdede sleep olmadan – donanım kodunun gittiği her yerde ortaya çıkar: anahtarların yazılımsal seğirme giderme işlemi (debouncing), motor sıralaması, UART okuma zaman aşımları. Aynı üç işlev (time.ticks_ms(), time.ticks_diff(), time.ticks_add()) her durumu kapsar.