⏰ چرا delay برنامهات را خراب میکند — و millis چطور نجاتش میدهد
delay() اولین دستوری است که یاد میگیری و اولین چیزی است که باید کنارش بگذاری. دلیلش ساده است: در طول delay، آردوینو هیچ کار دیگری نمیکند.
مشکل را ببین
void loop() {
digitalWrite(13, HIGH);
delay(5000); // پنج ثانیه هیچ اتفاقی نمیافتد
digitalWrite(13, LOW);
delay(5000);
// اگر در این ده ثانیه دکمه را بزنی، آردوینو اصلاً نمیفهمد
}
راهحل: بهجای «صبر کن»، بگو «آیا وقتش شده؟»
millis() تعداد میلیثانیههای گذشته از روشنشدن برد را میدهد — مثل کرنومتری که هیچوقت متوقف نمیشود. بهجای متوقفکردن برنامه، هر دور میپرسیم آیا زمان کافی گذشته است.
الگوی استاندارد
unsigned long lastBlink = 0;
const long interval = 1000;
bool ledOn = false;
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT_PULLUP);
}
void loop() {
// کار ۱: چشمک زدن، هر یک ثانیه
if (millis() - lastBlink >= interval) {
lastBlink = millis();
ledOn = !ledOn;
digitalWrite(13, ledOn);
}
// کار ۲: خواندن دکمه — بدون هیچ وقفهای
if (digitalRead(2) == LOW) {
tone(8, 880, 100);
}
}
حالا هم چراغ چشمک میزند و هم دکمه بلافاصله جواب میدهد.
دو نکتهی فنی
- حتماً از نوع
unsigned longاستفاده کن، نهint— عدد millis خیلی زود از ظرفیت int بیرون میزند. - عدد بعد از حدود ۵۰ روز سرریز میشود و به صفر برمیگردد. چون ما تفریق میکنیم (
millis() - last)، الگوی بالا حتی در آن لحظه هم درست کار میکند.
پس delay هیچوقت خوب نیست؟
چرا، برای برنامههای خیلی ساده و برای شروع کاملاً مناسب است. وقتی پروژهات بیشتر از یک کار انجام میدهد، وقت مهاجرت به millis است.
الگوی millis را توی شبیهساز امتحان کن ⏰