وقفهها (Interrupts) در ESP8266 و ESP32 | آموزش جامع Interrupt در ESP
مقدمه: چرا Interrupt یکی از مهمترین مفاهیم ESP است؟
در بسیاری از پروژههای ESP، مخصوصاً پروژههای IoT، صنعتی، سنسورمحور و Real-Time، واکنش سریع به رویدادها حیاتی است. اگر قرار باشد پردازنده دائماً داخل loop() منتظر بماند تا یک شرط برقرار شود، با مشکلات زیر روبهرو میشویم:
-
تأخیر در پاسخ
-
مصرف بیهوده CPU
-
از دست رفتن رویدادهای سریع
-
ناپایداری سیستم
اینجاست که وقفهها (Interrupts) نقش کلیدی بازی میکنند.
Interrupt به ESP اجازه میدهد در لحظه وقوع یک رویداد مهم، اجرای برنامه را متوقف کرده و فوراً به آن پاسخ دهد. تسلط بر وقفهها، مرز بین یک پروژه آماتور و یک پروژه حرفهای را مشخص میکند.
این مقاله مکمل مستقیم مباحث:
Interrupt چیست؟ (تعریف ساده و فنی)
وقفه یا Interrupt مکانیزمی سختافزاری/نرمافزاری است که به پردازنده اعلام میکند یک رویداد مهم خارج از جریان عادی برنامه رخ داده است.
مراحل کار Interrupt:
-
وقوع رویداد (مثلاً تغییر وضعیت GPIO)
-
توقف موقت اجرای کد اصلی
-
اجرای تابع وقفه (ISR)
-
بازگشت به ادامه برنامه
این فرآیند معمولاً در چند میکروثانیه انجام میشود.
Polling در مقابل Interrupt
Polling چیست؟
در Polling پردازنده بهصورت مداوم وضعیت یک ورودی را بررسی میکند:
مشکلات Polling:
-
اشغال دائمی CPU
-
مصرف انرژی بالا
-
احتمال از دست رفتن پالسهای سریع
مزایای Interrupt:
-
واکنش فوری
-
مصرف انرژی کمتر
-
مناسب پروژههای دقیق و Real-Time
به همین دلیل در سیستمهای حرفهای، Interrupt همیشه به Polling ترجیح داده میشود.
انواع وقفهها در ESP
در ESP8266 و ESP32 چند نوع وقفه وجود دارد:
-
وقفه خارجی (GPIO Interrupt)
-
وقفه تایمر (Timer Interrupt)
-
وقفه نرمافزاری
-
وقفههای مرتبط با FreeRTOS (در ESP32)
در این مقاله هرکدام را بهصورت کامل بررسی میکنیم.
وقفه خارجی (GPIO Interrupt)
رایجترین نوع Interrupt، وقفهای است که با تغییر وضعیت یک پایه GPIO فعال میشود.
حالتهای فعالسازی (Trigger Mode)
-
RISING: تغییر از LOW به HIGH -
FALLING: تغییر از HIGH به LOW -
CHANGE: هر تغییری -
HIGH/LOW: سطح ثابت (محدود)
پیادهسازی GPIO Interrupt در Arduino IDE
ساختار کلی استفاده از وقفه:
مثال ساده: وقفه کلید
در ESP32 استفاده از IRAM_ATTR ضروری است تا تابع ISR از RAM اجرا شود، نه از Flash.
ISR چیست و چرا باید سبک باشد؟
ISR یا Interrupt Service Routine تابعی است که هنگام وقوع وقفه اجرا میشود.
قوانین طلایی ISR
در ISR نباید:
-
از
delay()استفاده شود -
از
Serial.print()استفاده شود -
حافظه رزرو یا آزاد شود
-
عملیات سنگین انجام شود
ISR فقط باید:
-
فلگ ست کند
-
شمارنده افزایش دهد
-
زمان ثبت کند
نقض این قوانین یکی از دلایل اصلی ریست شدن ESP است.
volatile چیست و چرا حیاتی است؟
متغیرهایی که هم در ISR و هم در کد اصلی استفاده میشوند، باید با کلیدواژه volatile تعریف شوند.
بدون volatile، کامپایلر ممکن است مقدار متغیر را بهروزرسانی نکند و رفتار برنامه غیرقابل پیشبینی شود.
این خطا در مقاله
«دیباگ و رفع خطاهای رایج در ESP»
بهعنوان یکی از اشتباهات رایج بررسی شده است.
وقفه تایمر (Timer Interrupt)
Timer Interrupt وقفهای است که در بازههای زمانی مشخص اجرا میشود.
کاربردها:
-
نمونهبرداری دقیق سنسورها
-
تولید سیگنال
-
زمانبندی حرفهای
-
کنترل موتور و PWM نرمافزاری
تایمرها در ESP32
ESP32 دارای تایمرهای سختافزاری بسیار دقیق است که میتوانند در سطح میکروثانیه وقفه ایجاد کنند.
تفاوت Interrupt در ESP8266 و ESP32
| ویژگی | ESP8266 | ESP32 |
|---|---|---|
| تعداد وقفه | محدود | زیاد |
| هسته پردازنده | تکهسته | دو هسته |
| FreeRTOS | ❌ | ✅ |
| Timer پیشرفته | محدود | کامل |
ESP32 برای پروژههای حرفهای انتخاب بهتری است.
Interrupt و FreeRTOS در ESP32
در ESP32، وقفهها میتوانند با Taskهای FreeRTOS تعامل داشته باشند.
ارتباط ISR با Task
-
ارسال سیگنال
-
استفاده از Queue
-
استفاده از Semaphore
این مبحث بهصورت کامل در مقاله
«اجرای چندین Task با FreeRTOS در ESP32»
بررسی میشود.
Debounce کلید در Interrupt
کلیدهای مکانیکی دارای پرش (Bounce) هستند.
راهحل نرمافزاری:
انتخاب GPIO مناسب برای Interrupt
همه پایهها برای وقفه مناسب نیستند.
❌ پایههای بوت
❌ پایههای متصل به Flash
❌ پایههای خاص ESP32-CAM
لیست کامل این پایهها در مقاله
«بوتلودر ESP و حالتهای بوت»
بررسی شده است.
Interrupt و مصرف انرژی
Interrupt نقش مهمی در کاهش مصرف انرژی دارد:
-
CPU میتواند در حالت Idle یا Sleep بماند
-
فقط هنگام رویداد بیدار شود
این مفهوم پایه اصلی Deep Sleep است.
مقاله مکمل:
«Deep Sleep و کاهش مصرف انرژی در ESP»
خطاهای رایج هنگام استفاده از Interrupt
❌ ریست شدن ESP
-
ISR سنگین
-
دسترسی به Flash در ISR
❌ اجرا نشدن وقفه
-
انتخاب GPIO اشتباه
-
تداخل با پایههای بوت
کاربردهای واقعی Interrupt در پروژهها
-
شمارنده پالس و RPM
-
انکودر چرخشی
-
سنسور PIR
-
کلید اضطراری
-
دیتالاگر
-
سیستم هشدار
بیشتر پروژههای حرفهای بدون Interrupt عملاً غیرممکن هستند.
جمعبندی نهایی
Interrupt یکی از پایههای اصلی برنامهنویسی حرفهای ESP است.
اگر:
-
ISR را سبک بنویسی
-
از volatile درست استفاده کنی
-
GPIO مناسب انتخاب کنی
پروژههایی خواهی داشت که:
-
سریعتر هستند
-
پایدارترند
-
کممصرفترند
-
و مقیاسپذیرند
این مقاله یکی از ستونهای اصلی مرجع ESP تو خواهد بود.