Saat millis() Berputar Kembali
Termasuk bagian Pengaturan Waktu Tanpa Delay dalam perjalanan Arduino di Coddy. Pelajaran 17 dari 18.
unsigned long berhenti pada 4,294,967,295. Setelah sekitar 49.7 hari, millis() mencapainya lalu mulai lagi dari 0. Ini disebut berputar ulang.
Tipe yang lebih kecil menunjukkan hal yang sama. unsigned int berhenti pada 65535:
unsigned int a = 65530;
a = a + 10; // 65540 tidak muat: a sekarang bernilai 4Pengurangan berputar dengan cara yang sama, dan itu membuatnya aman: jam yang dimulai dari 65530 dan kini menunjukkan 4 telah menghitung 10 langkah, dan 4 dikurangi 65530, yang disimpan dalam unsigned int, hasilnya tepat 10. Dengan cara yang sama, millis() - start selalu menunjukkan waktu sejak start, bahkan saat melewati putaran ulang.
Penjumlahan tidak aman. Dalam now >= start + interval, hasil penjumlahan dapat melewati batas atas dan berputar ke angka kecil, sehingga timer langsung selesai. Dan ketika now sudah berputar ulang tetapi hasil penjumlahannya belum, timer tidak pernah selesai. Selalu gunakan pengurangan:
if (now - start >= interval) {
// selesai
}Tantangan
SedangTidak ada yang bisa menunggu 49 hari untuk sebuah pengujian, jadi sketch ini memberikan nilai waktu yang mendekati saat rollover kepada isDone() dan mencetak jawabannya. Hasilnya menyatakan "done" terlalu cepat dan "waiting" selamanya. Perbaiki satu baris di isDone() agar fungsi itu membandingkan waktu yang berlalu sejak start dengan interval.
Tekan Run, baca keempat jawabannya, perbaiki baris tersebut, lalu tekan Check.
Coba sendiri
const unsigned long interval = 2000;
// Apakah timer yang dimulai pada start sudah selesai pada waktu now?
bool isDone(unsigned long start, unsigned long now) {
return now >= start + interval; // perbaiki baris ini
}
// Menampilkan waktu yang telah berlalu dan hasil dari isDone().
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() berhenti di 4294967295, lalu mulai lagi dari 0
test(4294966000, 4294966500); // tepat sebelum kembali ke 0
test(4294966000, 4294967200); // masih sebelum kembali ke 0
test(4294966000, 900); // jam sudah melewati 0
test(4294964000, 500); // timer yang dimulai lebih awal
}
void loop() {
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pengaturan Waktu Tanpa Delay
1millis()
Jam millis()Waktu dalam unsigned longLED Berkedip Tanpa JedaDua LED, Dua KecepatanLED Berkedip Saat Tombol Mengubah StatusLampu dengan Pengatur Waktu4Pengaturan Waktu yang Presisi
Mengukur dengan micros()Saat millis() Berputar KembaliStopwatch TombolLatihan sendiri: Playground Arduino