Qoʻllanma · Uzilishlar · Vaqt
delay() dan voz keching — Arduino va ESP32 da uzilishlar va millis()
Hamma birinchi oʻrganadigan narsa — delay(). Hamma ikkinchi boʻlib uriladigan narsa — uning
devori: delay(1000) ishlab turganda plata hech narsa qilmaydi — tugmani
oʻqiy olmaydi, ekranni yangilay olmaydi, Wi-Fi’ni ushlab tura olmaydi. Chiqish yoʻli ikki qadamda:
millis() bilan bloklamaydigan vaqt va uzilishlar bilan hodisalarni
sodir boʻlgan zahoti ushlash.
1-qadam — delay() oʻrniga millis()
Koʻpincha «menga kechikish kerak» aslida «buni har N da qil, lekin qolgani ishlab tursin» degani. Aynan
shu uchun millis() bor — u ishga tushgandan beri millisekundlarni qaytaradi, va siz muzlatish
oʻrniga qancha vaqt oʻtganini tekshirasiz:
unsigned long prev = 0;
const unsigned long period = 1000; // ms
void loop() {
unsigned long now = millis();
if (now - prev >= period) {
prev = now;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // blink
}
// ...everything else keeps running here, no freeze
} Sikl hech qachon bloklanmaydi — u har oʻtishda faqat soatga qaraydi. Bu bitta usul delay()
chaqiruvlarining 90% ini almashtiradi va aynan u platani bir vaqtning oʻzida svetodiod miltillatish,
datchik soʻrash va sahifa berishga qodir qiladi. Ammo soʻrovda tirqish bor — ikki tekshiruv orasida tez
hodisani oʻtkazib yuborish mumkin. Mana shu yerda uzilishlar keladi.
2-qadam — uzilishlar: soʻramang, xabar oling
Uzilish — bu apparatли «yelkaga urish»: pin oʻzgarsa, CPU ishini tashlab, kichik funksiyani (ISR — uzilishga xizmat routinasi) bajaradi va aniq oʻzi toʻxtagan joyга qaytadi. Uni hodisani oʻtkazib yubormaslik shart boʻlganда va soʻrashga imkon boʻlmaganда olasiz:
- Tugma bosilishi —
loop()nima bilan band boʻlishidan qatʼi nazar, bosilgan zahoti javob bering. - Enkoder — impulslar ishonchli soʻrash uchun juda tez keladi.
- Oqim/impuls datchigi — birontasini oʻtkazmasdan frontlarni sanang.
- Pin orqali chuqur uyqudan uygʻonish (qarang: chuqur uyqu).
Ulanish: yerga tortiladigan tugma
Eng toza tugmaga tashqi detal kerak emas: bir oyoq GPIO ga, ikkinchisi GND ga, va chipning ichki
pull-upi INPUT_PULLUP bilan yoqiladi. Pin tinch holatда HIGH va bosilganда LOW oʻqiladi —
shuning uchun FALLING boʻyicha trigger.
INPUT_PULLUP «tashqi rezistorsiz» degani. BoardLabda yigʻilgan.ESP32 da deyarli har qanday GPIO uzilish boʻla oladi; klassik Uno’da esa faqat D2 va D3.
Pinni doim digitalPinToInterrupt() ichiga oʻrang — u pinni kerakli uzilish liniyasiga
bogʻlaydi. ESP32 nuansi: input-only pinlarda GPIO34–39 ichki pull-up yoʻq —
oʻsha yerda tugmaga 3V3 ga ~10 kΩ tashqi rezistor haqiqatan kerak.
3-qadam — debounce, aks holda bitta bosish beshta boʻlib sanaladi
Mexanik tugma bitta toza front bermaydi — kontaktlar sakraydi, bir necha millisekund HIGH/LOW qiladi. Ishlov bermasangiz, ISR bir bosishда bir necha marta ishlaydi. Yechim — oldingisidan juda tez kelgan har qanday frontni eʼtiborsiz qoldirish:
const byte BUTTON = 19; // your interrupt pin
volatile uint32_t presses = 0;
volatile uint32_t lastUs = 0;
void IRAM_ATTR onPress() { // ESP32: the ISR must live in IRAM
uint32_t now = micros();
if (now - lastUs > 25000) { // ignore bounces within 25 ms
presses++;
lastUs = now;
}
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON, INPUT_PULLUP); // button to GND, no external resistor
attachInterrupt(digitalPinToInterrupt(BUTTON), onPress, FALLING);
}
void loop() {
static uint32_t shown = 0;
if (presses != shown) { // do the slow work OUT here, not in the ISR
shown = presses;
Serial.printf("presses: %u\n", shown);
}
} micros() tekshiruvi 25 ms ichidagi sakrashlarni yutadi, real bosishlarga sezgir qolib.
Apparat xohlaysizmi? Tugmaga 100 nF kondensator (yoki RC-filtr) frontni silliqlaydi — lekin dasturiy
tekshiruv bepul va deyarli hamma narsa uchun yetarli.
Haqiqatan tishlaydigan ISR qoidalari
- Qisqa saqlang. Bayroq qoʻying yoki hisoblagichni oshiring, keyin
loop()da ishlov bering. Uzun ISR hamma narsani, jumladan Wi-Fi’ni bloklaydi. volatilebilan boʻlishing. ISR valoop()ikkalasi tegadigan har qanday oʻzgaruvchivolatileboʻlishi kerak — aks holda kompilyator eski nusxani keshlashi mumkin.- ESP32: ISR’ни
IRAM_ATTRdeb belgilang. U RAM’dan ishlashi kerak — busiz uzilish flash operatsiyasi paytida kelsa plata qulashi mumkin. - ISR ichida
Serial,delay()yoki ogʻir ish yoʻq. Misoldagidekloop()da chop eting va hisoblang. - 8-bit AVR’da koʻp baytli qiymatlar atomar emas. ISR yangilaydigan
longni oʻqiyapsizmi? Oʻqish atrofida uzilishlarni qisqa oʻchiring (noInterrupts()/interrupts()).
Birgalikda: millis() kundalik delay() ni yoʻqotadi, uzilishlar esa oʻtkazib
yuborib boʻlmaydigan hodisalarni ushlaydi. Ikkalasi ham mushak xotirasiga aylanganда plata «duduqlanishни»
toʻxtatib, bir vaqtda bir nechta ish qila boshlaydi — ESP32 da esa yana uzoqroqqa borib, ishni
ikkinchi yadroga qoʻyish mumkin.
Tugma yoki datchikni kerakli pinga ulayapsizmi? Avval u boʻsh va uzilishга qodir ekanini tekshiring.