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ı
}Görev
OrtaKimse 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() {
}
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