
قسمت ۴ آموزش میکروپایتون: ورودی و خروجی دیجیتال
آموزش GPIO در میکروپایتون؛ از کنترل LED تا خواندن کلید
برای ارتباط میکروکنترلر با دنیای بیرون، باید بتوانیم قطعاتی مانند LED را کنترل کنیم و وضعیت کلیدها و حسگرها را بخوانیم؛ پینهای ورودی/خروجی همهمنظوره یا GPIO این امکان را فراهم میکنند. در جلسه چهارم آموزش میکروپایتون، با ورودی و خروجی دیجیتال آشنا میشویم و یاد میگیریم چگونه با استفاده از کلاس Pin، پینها را پیکربندی کنیم، LED را روشن و خاموش کنیم و فشرده شدن کلید را تشخیص دهیم. همچنین، نقش مقاومتهای داخلی Pull-up و Pull-down در پایدارسازی ورودی و روش کاهش اثر جهشهای مکانیکی کلید (Debouncing) را بررسی میکنیم تا با اجرای چند تمرین کاربردی، برای ساخت پروژههای تعاملی آماده شویم.
اهداف:
- آشنایی با مفهوم GPIO و پینهای همهمنظوره
- یادگیری پیکربندی پین به عنوان خروجی دیجیتال
- کنترل LED با روشهای مختلف (value، on/off، toggle)
- یادگیری پیکربندی پین به عنوان ورودی دیجیتال
- آشنایی با مقاومتهای Pull-up و Pull-down داخلی
- خواندن وضعیت کلید و تشخیص فشرده شدن آن
1. مقدمهای بر GPIO
GPIO (General Purpose Input/Output) یا ورودی/خروجی همهمنظوره، پینهای فیزیکی روی میکروکنترلر هستند که میتوانند به عنوان ورودی یا خروجی دیجیتال برنامهریزی شوند.
حالتهای اصلی GPIO:
- خروجی دیجیتال: پین ولتاژ بالا (۳٫۳ ولت) یا پایین (۰ ولت) تولید میکند. مناسب برای روشن/خاموش کردن LED، رله، ترانزیستور و …
- ورودی دیجیتال: پین وضعیت ولتاژ اعمال شده به آن را میخواند (۰ یا ۱). مناسب برای خواندن کلید، سنسورهای خروجی دیجیتال و …
نکات مهم:
- ولتاژ کاری اکثر میکروکنترلرها ۳٫۳ ولت است. اعمال ولتاژ بالاتر (مثلاً ۵ ولت) ممکن است به برد آسیب بزند.
- جریان خروجی هر پین محدود است (معمولاً ۱۲-۲۰ میلیآمپر). برای مصرفکنندههای پرجریان باید از ترانزیستور یا ماژول رله استفاده کرد.
2. خروجی دیجیتال (کنترل LED)
ایجاد یک پین خروجی:
برای استفاده از پینها، باید ماژول machine را import کرده و یک شیء Pin بسازیم .
|
1 2 3 4 5 |
from machine import Pin # ایجاد پین شماره 2 به عنوان خروجی led = Pin(2, Pin.OUT) |
پس از ایجاد پین خروجی، میتوانیم مقدار آن را با روشهای مختلف تغییر دهیم :
روش اول: استفاده از متد value()
|
1 2 3 4 5 6 7 |
led.value(1) # روشن (ولتاژ بالا) led.value(0) # خاموش (ولتاژ پایین) # میتوان از True/False هم استفاده کرد led.value(True) # روشن led.value(False) # خاموش |
روش دوم: استفاده از متدهای on() و off()
|
1 2 3 |
led.on() # روشن led.off() # خاموش |
این متدها در اکثر پورتها (از جمله ESP32، ESP8266، RP2) در دسترس هستند .
روش سوم: استفاده از متد toggle() (معمولاً موجود)
|
1 2 |
led.toggle() # اگر روشن بود خاموش، اگر خاموش بود روشن میکند |
برنامه LED چشمکزن (Blink):
|
1 2 3 4 5 6 7 8 9 10 11 12 |
from machine import Pin import time # ایجاد پین LED (برای Pico: پین 25، برای ESP32: پین 2) led = Pin(2, Pin.OUT) while True: led.on() # روشن time.sleep(0.5) # نیم ثانیه صبر کن led.off() # خاموش time.sleep(0.5) # نیم ثانیه صبر کن |
کنترل چند LED:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from machine import Pin import time # تعریف سه LED روی پینهای مختلف led_red = Pin(2, Pin.OUT) led_green = Pin(4, Pin.OUT) led_blue = Pin(5, Pin.OUT) while True: led_red.on() time.sleep(0.3) led_red.off() led_green.on() time.sleep(0.3) led_green.off() led_blue.on() time.sleep(0.3) led_blue.off() |
3. ورودی دیجیتال (خواندن کلید)
برای خواندن ورودی دیجیتال، پین را در حالت Pin.IN قرار میدهیم.
ایجاد یک پین ورودی:
|
1 2 3 4 5 |
from machine import Pin # ایجاد پین شماره 0 به عنوان ورودی button = Pin(0, Pin.IN) |
خواندن مقدار ورودی:
|
1 2 3 4 5 6 7 |
value = button.value() # 0 یا 1 برمیگرداند if value == 1: print("دکمه فشرده شده") else: print("دکمه آزاد است") |
نکته مهم: مقاومتهای Pull-up و Pull-down
وقتی کلید فشرده نیست، پین ورودی در حالت شناور (Floating) قرار میگیرد و مقدار آن نامشخص و نویزپذیر میشود. برای حل این مشکل، از مقاومتهای pull-up یا pull-down استفاده میکنیم .
- Pull-up: وقتی کلید آزاد است، پین به ولتاژ بالا (۱) وصل میشود. با فشردن کلید، پین به زمین (۰) وصل میشود.
- Pull-down: وقتی کلید آزاد است، پین به زمین (۰) وصل میشود. با فشردن کلید، پین به ولتاژ بالا (۱) وصل میشود.
میکروپایتون امکان فعالسازی مقاومتهای داخلی میکروکنترلر را فراهم میکند :
|
1 2 3 4 5 6 |
# مقاومت pull-up داخلی (حالت نرمال: 1، با فشردن کلید: 0) button = Pin(0, Pin.IN, Pin.PULL_UP) # مقاومت pull-down داخلی (حالت نرمال: 0، با فشردن کلید: 1) button = Pin(0, Pin.IN, Pin.PULL_DOWN) |
مدار پیشنهادی برای کلید با pull-up داخلی:
اگر از PULL_UP استفاده میکنید:
- یک سر کلید به پین GPIO
- سر دیگر کلید به GND
- نیازی به مقاومت خارجی نیست (مقاومت داخلی فعال است)
اگر از PULL_DOWN استفاده میکنید:
- یک سر کلید به پین GPIO
- سر دیگر کلید به ۳٫۳V
- نیازی به مقاومت خارجی نیست
4. پروژه ترکیبی: کنترل LED با کلید
برنامه ساده: روشن شدن LED با فشردن کلید
|
1 2 3 4 5 6 7 8 9 10 11 |
from machine import Pin led = Pin(2, Pin.OUT) # LED روی پین ۲ button = Pin(0, Pin.IN, Pin.PULL_UP) # کلید با pull-up داخلی while True: if button.value() == 0: # کلید فشرده شده (چون pull-up است) led.on() else: led.off() |
برنامه پیشرفتهتر: تغییر وضعیت LED با هر بار فشردن کلید (Toggle)
در این برنامه باید از debouncing (حذف نویز مکانیکی کلید) استفاده کنیم:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
from machine import Pin import time led = Pin(2, Pin.OUT) button = Pin(0, Pin.IN, Pin.PULL_UP) led_state = False last_button_state = 1 # وضعیت قبلی کلید (آزاد) while True: current_state = button.value() # تشخیص تغییر وضعیت از آزاد به فشرده (لبه پایینرونده) if last_button_state == 1 and current_state == 0: # تأخیر کوتاه برای حذف نویز time.sleep(0.02) # دوباره بررسی میکنیم if button.value() == 0: led_state = not led_state led.value(led_state) print("LED:", "ON" if led_state else "OFF") # منتظر میمانیم تا کلید آزاد شود while button.value() == 0: time.sleep(0.01) last_button_state = current_state time.sleep(0.01) |
5. توابع مهم کلاس Pin
جدول زیر توابع مهم کلاس Pin را خلاصه میکند :
| تابع | توضیح | مثال |
|---|---|---|
Pin(id, mode, pull) |
ایجاد پین با تنظیمات مشخص | Pin(2, Pin.OUT) |
value([x]) |
اگر آرگومان ندهیم: مقدار را میخواند. اگر بدهیم: مقدار را تنظیم میکند | led.value(1) یا state = button.value() |
on() |
پین را روشن میکند (۱) | led.on() |
off() |
پین را خاموش میکند (۰) | led.off() |
toggle() |
وضعیت پین را معکوس میکند | led.toggle() |
high() |
معادل on() (در برخی پورتها) | led.high() |
low() |
معادل off() (در برخی پورتها) | led.low() |
init(mode, pull) |
تنظیم مجدد پین | led.init(Pin.IN, Pin.PULL_UP) |
ثابتهای حالت پین :
Pin.OUT: خروجیPin.IN: ورودیPin.OPEN_DRAIN: خروجی کلکتور بازPin.ALT: عملکرد جایگزینPin.ALT_OPEN_DRAIN: عملکرد جایگزین با کلکتور باز
ثابتهای مقاومت pull :
Pin.PULL_UP: مقاومت pull-up داخلیPin.PULL_DOWN: مقاومت pull-down داخلیNone: بدون مقاومت داخلی
6. نکات مهم و عیبیابی
تشخیص شماره پین صحیح:
شماره پینها در بردهای مختلف متفاوت است:
- ESP32: معمولاً پینهای GPIO با شماره (مثلاً ۲، ۴، ۵، …)
- ESP8266: پینهای GPIO با شماره (مثلاً ۰، ۲، ۴، ۵، …) اما برخی پینها محدودیت دارند
- Raspberry Pi Pico: پینهای GP با شماره (مثلاً GP0، GP1، …) که با عدد مشخص میشوند (0, 1, …)
مشکلات رایج:
- LED روشن نمیشود:
- قطبیت LED را بررسی کنید (پایه بلند به پین، پایه کوتاه به GND از طریق مقاومت)
- مقاومت مناسب (۲۲۰ تا ۵۶۰ اهم) استفاده کنید
- پین صحیح را انتخاب کردهاید؟
- کلید کار نمیکند:
- از مقاومت pull-up/down استفاده کنید (داخلی یا خارجی)
- سیمبندی را بررسی کنید
- از debouncing استفاده کنید
- رفتار غیرمنتظره:
- برخی پینها در زمان بوت حالت خاصی دارند (مثلاً پین ۲ در ESP8266 برای LED داخلی)
- از پینهای مناسب برای ورودی/خروجی استفاده کنید
7. تمرینهای عملی
تمرین ۱: چراغ راهنمایی ساده
سه LED (قرمز، زرد، سبز) روی پینهای ۲، ۴ و ۵ وصل کنید. برنامهای بنویسید که به ترتیب:
- ۳ ثانیه سبز
- ۱ ثانیه زرد
- ۳ ثانیه قرمز
- ۱ ثانیه زرد
- و تکرار…
تمرین ۲: کنترل LED با دو کلید
دو کلید به پینهای ۰ و ۱ وصل کنید. با کلید اول LED را روشن و با کلید دوم خاموش کنید. (بدون toggle)
تمرین ۳: شمارشگر ضربه
هر بار که کلید فشرده میشود، یک شمارنده افزایش یابد و مقدار آن روی REPL چاپ شود. (از debouncing استفاده کنید)
تمرین ۴: الگوی چشمکزن متغیر
با هر بار فشردن کلید، سرعت چشمک زدن LED تغییر کند (مثلاً ۰.۵ ثانیه، ۰.۲ ثانیه، ۰.۱ ثانیه و دوباره تکرار).
تمرین ۵: تشخیص فشردن طولانی
تشخیص دهید کلید کمتر از ۱ ثانیه فشرده شده (یک ضربه) یا بیشتر از ۱ ثانیه (فشردن طولانی) و برای هرکدام کاری متفاوت انجام دهید.
8. جمعبندی
در این جلسه با مفاهیم پایهای ورودی/خروجی دیجیتال آشنا شدیم:
- خروجی دیجیتال: کنترل LED با متدهای
value()،on()،off()وtoggle() - ورودی دیجیتال: خواندن وضعیت کلید با متد
value() - مقاومتهای داخلی: استفاده از
Pin.PULL_UPوPin.PULL_DOWNبرای پایدارسازی ورودی - Debouncing: تکنیک حذف نویز مکانیکی کلید
این مبنا برای پروژههای بعدی بسیار مهم است. در جلسه آینده به ورودی/خروجی آنالوگ میپردازیم و با ADC و PWM آشنا خواهیم شد.



