🔘 دکمه و وقفه (IRQ) با میکروپایتون روی رزبری پای پیکو
در مقالهی قبل یک LED را با میکروپایتون روی رزبری پای پیکو چشمک زدیم. حالا وقت آن است که برد به دنیای بیرون گوش بدهد. در این آموزش یک دکمه را میخوانیم، اول به روش ساده و بعد با وقفه (Interrupt یا IRQ)؛ روشی که در پروژههای جدی همه از آن استفاده میکنند. همهی اینها را میتوانی در یک شبیهساز آنلاین مثل wokwi یا نسخهی فارسی تینکرکد امتحان کنی.
وقفه یعنی چه؟
فرض کن منتظر یک مهمان هستی. یک راه این است که هر ده ثانیه بروی پشت در و نگاه کنی (به این میگویند Polling). راه بهتر این است که زنگ در را نصب کنی و هر کار دیگری که دوست داری بکنی؛ هر وقت زنگ زد، میروی در را باز میکنی. وقفه همان زنگ در است: پردازنده کارش را میکند و هر وقت دکمه فشار داده شد، یک تابع کوچک خودبهخود اجرا میشود.
قطعهها و اتصالها
- یک رزبری پای پیکو
- یک دکمهی فشاری
- LED داخلی برد (یا یک LED بیرونی با مقاومت ۲۲۰ اهم روی GP15)
| قطعه | پایه |
|---|---|
| یک سر دکمه | GP14 (پایهی فیزیکی ۱۹) |
| سر دیگر دکمه | GND (مثلاً پایهی فیزیکی ۱۸) |
| LED | LED داخلی، GP25 روی پیکوی اصلی |
به مقاومت بیرونی نیاز نداریم، چون از مقاومت Pull-up داخلی پیکو استفاده میکنیم.
کد کامل
from machine import Pin
import time
led = Pin(25, Pin.OUT) # روی Pico W بنویس Pin("LED", Pin.OUT)
button = Pin(14, Pin.IN, Pin.PULL_UP)
count = 0
last_ms = 0
def on_press(pin):
global count, last_ms
now = time.ticks_ms()
if time.ticks_diff(now, last_ms) > 200: # رفع لرزش دکمه
count += 1
led.toggle()
last_ms = now
button.irq(trigger=Pin.IRQ_FALLING, handler=on_press)
while True:
print("presses:", count)
time.sleep(1)
خطهای مهم را بشناس
Pin(14, Pin.IN, Pin.PULL_UP): پایه ورودی است و مقاومت داخلی آن را به ۳٫۳ ولت میکشد. پس وقتی دکمه آزاد است مقدارش ۱ است و وقتی فشارش میدهی (به GND وصل میشود) ۰ میشود. بله، برعکس چیزی که انتظار داری!Pin.IRQ_FALLING: وقفه وقتی اجرا شود که ولتاژ از ۱ به ۰ «سقوط» کند؛ یعنی لحظهی فشار دادن دکمه. اگر لحظهی رها کردن را میخواهی،Pin.IRQ_RISINGبنویس.def on_press(pin): تابع وقفه یک ورودی میگیرد که همان پایهای است که وقفه را صدا زده.global count, last_ms: بدون این خط، پایتون فکر میکندcountیک متغیر تازهی محلی است و خطا میدهد.time.ticks_diff(now, last_ms) > 200: دکمههای واقعی موقع فشار چند بار «میلرزند» و در چند میلیثانیه چند بار وصل و قطع میشوند. با این شرط، فشارهایی که کمتر از ۲۰۰ میلیثانیه بعد از قبلی بیایند نادیده گرفته میشوند.- حلقهی
whileفقط هر ثانیه تعداد را چاپ میکند. ببین چطور برنامهی اصلی کار خودش را میکند و دکمه هم هیچوقت از دست نمیرود.
time.sleep نگذار و کار سنگین مثل چاپ زیاد یا کار با نمایشگر نکن. فقط یک پرچم یا شمارنده را عوض کن و بقیهی کار را به حلقهی اصلی بسپار.امتحان در شبیهساز
پروژهی آمادهی دکمه و وقفه با MicroPython روی پیکو در تینکرکد فارسی همین مدار را دارد. با کلیک روی دکمه در شبیهساز، LED عوض میشود و عدد در سریال مانیتور بالا میرود. پیکو و میکروپایتون در اشتراک پلاس هستند: مثال برای خواندن رایگان است و برای اجرا پلاس لازم داری. اگر میخواهی همین مفهوم را رایگان روی آردوینو یاد بگیری، درس وقفه: گوشبهزنگ همیشگی را ببین.
اشکالهای رایج
- با یک بار فشار، عدد چند تا بالا میرود: این همان لرزش دکمه است. عدد ۲۰۰ را بیشتر کن یا مطمئن شو شرط
ticks_diffرا درست نوشتهای. - هیچ اتفاقی نمیافتد: دکمه را به 3V3 وصل کردهای نه GND؟ با
PULL_UPسر دیگر دکمه باید به زمین برود. - دکمهی چهارپایه: دو پایهی همردیف دکمههای چهارپایه همیشه به هم وصلاند. اگر هر دو سیم را به یک طرف بزنی، دکمه همیشه «فشرده» است. سیمها را به دو گوشهی مخالف (قطری) وصل کن.
- UnboundLocalError: خط
globalرا در تابع جا انداختهای. - برنامه هنگ میکند: احتمالاً داخل تابع وقفه
sleepیا حلقه گذاشتهای. آن را به حلقهی اصلی ببر.
اگر هنوز چشمکزن را نساختهای، از اولین برنامهی میکروپایتون روی پیکو شروع کن. برای مرور کامل زبان هم صفحهی میکروپایتون و برای خود برد صفحهی رزبری پای پیکو را ببین.
دکمه و وقفه را روی پیکو امتحان کن 🔘مقالههای مرتبط
نمایشگر OLED و نئوپیکسل با میکروپایتون روی رزبری پای پیکو
آموزش میکروپایتون از صفر: متغیر، شرط، حلقه، تابع، لیست و کار با پایههای برد
پین اوت رزبری پای پیکو: نقشهی کامل ۴۰ پایه، GP، ADC، I2C، SPI، UART و تغذیه
رنگینکمان نئوپیکسل با آردوینو و کتابخانهی Adafruit_NeoPixel
همهی آموزشهای رزبری پای پیکو و میکروپایتون ← · همهی مقالهها