Menu
CoddyTech

millis() Taştığında

Coddy'nin Arduino Journey'sinin delay() Kullanmadan Zamanlama bölümünün bir parçası. Ders 17 / 18.

Bir unsigned long, 4,294,967,295 değerinde durur. Yaklaşık 49.7 gün sonra millis() bu değere ulaşır ve yeniden 0'dan başlar. Buna taşma denir.

Daha küçük bir tür de aynı şeyi gösterir. Bir unsigned int, 65535 değerinde durur:

unsigned int a = 65530;
a = a + 10;   // 65540 sığmaz: a artık 4

Çıkarma da aynı şekilde başa sarar ve bu onu güvenli kılar: 65530'da başlayan ve şu anda 4 gösteren bir saat 10 adım saymıştır; unsigned int türünde saklanan 4 eksi 65530 tam olarak 10'dur. Aynı şekilde, millis() - start, taşma olsa bile her zaman start değerinden beri geçen süredir.

Toplama güvenli değildir. now >= start + interval ifadesinde toplam en üst değeri aşarak küçük bir sayıya sarabilir; bu durumda zamanlayıcı hemen tamamlanmış olur. Ayrıca now başa sarıp toplam sarılmadığında zamanlayıcı hiçbir zaman tamamlanmaz. Her zaman çıkarma yapın:

if (now - start >= interval) {
  // tamamlandı
}
challenge icon

Görev

Orta

Kimse bir test için 49 gün bekleyemez; bu yüzden bu taslak, isDone() işlevine devir noktasına yakın zamanlar verir ve yanıtlarını yazdırır. Çok erken "done" diyor ve sonsuza kadar "waiting" diyor. isDone() içindeki tek satırı, start üzerinden geçen süreyi interval ile karşılaştıracak şekilde düzelt.

Çalıştır'a bas, dört yanıtı oku, satırı düzelt, sonra Kontrol Et'e bas.

Kendin dene

const unsigned long interval = 2000;

// start anında başlayan zamanlayıcı now anında tamamlandı mı?
bool isDone(unsigned long start, unsigned long now) {
  return now >= start + interval;   // bu satırı düzelt
}

// Geçen süreyi ve isDone() işlevinin ne döndürdüğünü yazdırır.
void test(unsigned long start, unsigned long now) {
  Serial.print(now - start);
  Serial.print(" ms: ");
  if (isDone(start, now)) {
    Serial.println("done");
  } else {
    Serial.println("waiting");
  }
}

void setup() {
  Serial.begin(9600);
  // millis() 4294967295 değerinde durur, ardından 0 değerinden yeniden başlar
  test(4294966000, 4294966500);   // taşmadan hemen önce
  test(4294966000, 4294967200);   // hâlâ taşmadan önce
  test(4294966000, 900);          // saat 0 değerini geçti
  test(4294964000, 500);          // daha önce başlamış bir zamanlayıcı
}

void loop() {
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

delay() Kullanmadan Zamanlama bölümündeki tüm dersler

Kendi başına pratik yap: Arduino playground