🐍 آموزش میکروپایتون از صفر: متغیر، شرط، حلقه، تابع، لیست و کار با پایه‌های برد

✍️ تیم ووکوی فارسی ·

اگر دنبال یک آموزش میکروپایتون هستی که از صفر شروع کند و آخرش بتوانی یک LED و دکمه را با کد خودت کنترل کنی، این صفحه برای توست. میکروپایتون (MicroPython) همان پایتون ۳ است که آن‌قدر کوچک شده که روی یک میکروکنترلر ارزان مثل رزبری پای پیکو یا ESP32 جا شود. نه کامپایل لازم دارد و نه نصب پیچیده؛ می‌نویسی، اجرا می‌کنی و نتیجه را بلافاصله می‌بینی. در این درس قدم‌به‌قدم متغیر، نوع داده، شرط، حلقه، تابع، لیست، مدیریت خطا، ماژول‌ها و در آخر کار با پایه‌های برد را یاد می‌گیری؛ هر بخش با یک کد کوتاه که می‌توانی همین حالا اجرایش کنی.

این آموزش را چطور بخوانی؟

هر بخش یک مفهوم است و یک مثال کوچک. توصیه‌ی ما این است که فقط نخوانی: هر کد را اجرا کن، یک عددش را عوض کن و ببین چه اتفاقی می‌افتد. برای اجرا دو راه داری:

همه‌ی مثال‌های این صفحه با یک خط import (مثل import time) شروع می‌شوند. روی برد واقعی این خط برای مثال‌های ساده اجباری نیست، ولی در شبیه‌ساز کمک می‌کند ادیتور بفهمد برنامه‌ی تو میکروپایتون است، نه ++C آردوینو.

۱. اولین برنامه: print

تابع print هر چیزی را که به آن بدهی چاپ می‌کند. روی میکروکنترلر، خروجی آن به سریال مانیتور (یا پنجره‌ی Shell در Thonny) می‌رود و مهم‌ترین ابزار تو برای فهمیدن این است که برنامه کجاست و چه می‌کند.

import time

print("Salam, MicroPython!")
print(2 + 3)
print("2 + 3 =", 2 + 3)

وقتی چند چیز را با کاما جدا می‌کنی، print بینشان یک فاصله می‌گذارد. متن باید بین دو علامت نقل‌قول باشد؛ "..." یا '...' فرقی ندارد.

۲. متغیرها و نوع داده‌ها

متغیر یک اسم است برای یک مقدار؛ مثل برچسبی که روی یک جعبه می‌چسبانی. در پایتون لازم نیست نوع متغیر را از قبل بگویی (برخلاف int x; در آردوینو)؛ خود زبان از روی مقدار می‌فهمد.

import time

name = "Sara"        # str   : text
age = 13             # int   : whole number
height = 1.52        # float : decimal number
likes_robots = True  # bool  : True or False

print(name, age, height, likes_robots)
print(type(age), type(height))

age = age + 1
print("Next year:", age)

print(7 / 2)    # 3.5  normal division
print(7 // 2)   # 3    integer division
print(7 % 2)    # 1    remainder

text = "42"
number = int(text)          # str -> int
print(number * 2)           # 84
print("Age: " + str(age))   # int -> str
print(f"{name} is {age} years old")

۳. شرط: if، elif و else

برنامه‌ها باید تصمیم بگیرند: اگر هوا گرم است پنکه روشن شود، اگر دکمه فشار داده شد چراغ عوض شود. این کار با if انجام می‌شود.

import time

temp = 31

if temp > 30:
    print("Hot! Fan ON")
elif temp > 20:
    print("Nice weather")
else:
    print("Cold")

light = 150
is_night = light < 200
if is_night and temp < 35:
    print("Night lamp ON")
if not is_night:
    print("It is day")

۴. حلقه‌ها: for و while

حلقه یعنی «این کار را چند بار تکرار کن». for وقتی است که تعداد تکرار را می‌دانی، و while وقتی که تا برقرار بودن یک شرط ادامه می‌دهی.

import time

for i in range(5):
    print("i =", i)        # 0 1 2 3 4

for i in range(10, 0, -2):
    print(i)               # 10 8 6 4 2

count = 3
while count > 0:
    print("Countdown:", count)
    count -= 1
    time.sleep(1)
print("Go!")

n = 0
while True:
    n += 1
    if n % 2 == 0:
        continue           # skip even numbers
    if n > 9:
        break              # leave the loop
    print("odd:", n)

۵. تابع: کد را یک بار بنویس، بارها صدا بزن

وقتی یک تکه کد را چند جا لازم داری، آن را در یک تابع می‌گذاری و به آن اسم می‌دهی. تابع می‌تواند ورودی (پارامتر) بگیرد و با return جواب برگرداند.

import time

def square(x):
    return x * x

def greet(name, times=1):
    for i in range(times):
        print("Salam", name)

def c_to_f(c):
    return c * 9 / 5 + 32

print(square(4))        # 16
greet("Ali")            # times = 1 (default)
greet("Mina", 3)

for c in [0, 25, 100]:
    print(c, "C =", c_to_f(c), "F")

score = 0

def add_point():
    global score        # change the variable outside the function
    score += 1

add_point()
add_point()
print("score:", score)  # 2

۶. لیست، تاپل و دیکشنری

لیست چند مقدار را پشت سر هم در یک متغیر نگه می‌دارد؛ مثلاً شماره‌ی پایه‌های چند LED یا ده خوانش آخر یک سنسور. همان آرایه‌ی آردوینو است، با این فرق که می‌تواند بزرگ و کوچک شود.

import time

pins = [15, 14, 13]
notes = ["do", "re", "mi"]

print(pins[0])        # 15  (first item, index 0)
print(pins[-1])       # 13  (last item)
print(len(pins))      # 3

pins.append(12)
print(pins)           # [15, 14, 13, 12]
print(pins[1:3])      # [14, 13]

for note in notes:
    print("Play", note)

for i, note in enumerate(notes):
    print(i, note)

readings = [512, 498, 530, 505]
avg = sum(readings) / len(readings)
print("average:", avg, "max:", max(readings))

color = (255, 0, 0)             # tuple: cannot be changed
ages = {"Ali": 12, "Sara": 13}  # dict: key -> value
print(ages["Sara"])             # 13

۷. مدیریت خطا: try و except

وقتی چیزی خراب می‌شود (مثلاً کاربر به جای عدد حرف تایپ می‌کند)، پایتون یک «استثنا» پرتاب می‌کند و اگر کسی آن را نگیرد، برنامه می‌ایستد. با try می‌گویی «این را امتحان کن» و با except می‌گویی «اگر این خطا آمد، به جای توقف این کار را بکن».

import time

text = "12a"
try:
    n = int(text)
    print("number:", n)
except ValueError:
    print("Not a number:", text)

def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        print("Cannot divide by zero")
        return 0

print(safe_divide(10, 2))   # 5.0
print(safe_divide(1, 0))    # message, then 0

چند خطایی که در شروع زیاد می‌بینی و معنی‌شان:

پیام خطایعنی چه؟
IndentationErrorتورفتگی خط‌ها یکسان نیست یا Tab و Space قاطی شده.
SyntaxErrorدونقطه‌ی آخر if/for/def جا افتاده، یا پرانتز و نقل‌قول بسته نشده.
NameErrorاسمی را صدا زده‌ای که تعریف نشده؛ معمولاً غلط تایپی یا import جاافتاده.
TypeErrorدو نوع ناجور را با هم قاطی کرده‌ای، مثلاً "Age: " + 13.
ValueErrorنوع درست است ولی مقدار نه، مثل int("12a").

در صفحه‌ی گفت‌وگو با input() در میکروپایتون همین try/except را در عمل می‌بینی: برنامه از سریال مانیتور عدد می‌پرسد و اگر حرف تایپ کنی، به جای خراب شدن دوباره می‌پرسد.

۸. ماژول‌ها و import؛ و ماژول time

میکروپایتون همه‌ی ابزارهایش را یک‌جا بار نمی‌کند تا حافظه هدر نرود. هر چه لازم داری با import می‌آوری. سه شکل رایج:

دو ماژولی که تقریباً در هر برنامه‌ی سخت‌افزاری می‌بینی time و machine هستند. اول time:

import time

start = time.ticks_ms()

time.sleep(0.5)          # seconds (a float is fine)
time.sleep_ms(250)       # milliseconds
time.sleep_us(100)       # microseconds

elapsed = time.ticks_diff(time.ticks_ms(), start)
print("elapsed ms:", elapsed)    # about 750

۹. machine.Pin: حرف زدن با پایه‌های برد

این‌جاست که پایتون به الکترونیک وصل می‌شود. کلاس Pin از ماژول machine یک پایه‌ی برد را نشان می‌دهد. یک LED با مقاومت ۲۲۰ اهم به GP15 و یک دکمه بین GP14 و GND وصل کن:

from machine import Pin
import time

led = Pin(15, Pin.OUT)
button = Pin(14, Pin.IN, Pin.PULL_UP)

led.on()
time.sleep(1)
led.off()
led.value(1)        # same as led.on()
led.toggle()        # flip: on -> off

while True:
    if button.value() == 0:     # PULL_UP: pressed = 0
        led.on()
    else:
        led.off()
    time.sleep_ms(20)

۱۰. همه با هم: چراغ مورس با دکمه

حالا همه‌ی چیزهایی که یاد گرفتی را در یک برنامه‌ی واقعی کنار هم می‌گذاریم: دیکشنری برای جدول مورس، تابع برای چشمک کوتاه و بلند، حلقه روی حروف، شرط برای دکمه و try/except برای توقف تمیز. با هر بار فشار دکمه، LED پیام SOS را مورس می‌زند.

from machine import Pin
import time

led = Pin(15, Pin.OUT)
button = Pin(14, Pin.IN, Pin.PULL_UP)

# dot = short flash, dash = long flash
MORSE = {"S": "...", "O": "---", "A": ".-", "B": "-..."}
UNIT_MS = 150

def flash(symbol):
    led.on()
    if symbol == ".":
        time.sleep_ms(UNIT_MS)
    else:
        time.sleep_ms(UNIT_MS * 3)
    led.off()
    time.sleep_ms(UNIT_MS)

def send(word):
    for letter in word:
        code = MORSE.get(letter, "")
        print(letter, code)
        for symbol in code:
            flash(symbol)
        time.sleep_ms(UNIT_MS * 2)   # gap between letters

presses = 0
try:
    while True:
        if button.value() == 0:
            presses += 1
            print("press", presses)
            send("SOS")
        time.sleep_ms(20)
except KeyboardInterrupt:
    led.off()
    print("stopped")

MORSE.get(letter, "") اگر حرفی در جدول نباشد، به جای خطا یک متن خالی برمی‌گرداند. KeyboardInterrupt خطایی است که روی برد واقعی با Ctrl+C یا دکمه‌ی Stop در Thonny ایجاد می‌شود؛ گرفتنش باعث می‌شود LED روشن نماند. برای تمرین، حروف بیشتری به جدول اضافه کن و اسم خودت را مورس بزن.

میکروپایتون با پایتون معمولی چه فرقی دارد؟

اجرا در شبیه‌ساز

ساده‌ترین شروع، مثال آماده‌ی چشمک‌زن با MicroPython روی پیکو است. کد را پاک کن، هر کدام از مثال‌های بالا را جایش بگذار و اجرا کن؛ خروجی‌ها در سریال مانیتور می‌آیند. برای بخش ۹ و ۱۰ یک LED، یک مقاومت و یک دکمه به مدار اضافه کن و روی دکمه‌ی مجازی کلیک کن. اگر هنوز مطمئن نیستی، مقاله‌ی میکروپایتون روی رزبری پای پیکو هم یک معرفی کوتاه دارد. برای آشنایی با محیط اجرای آنلاین هم صفحه‌ی میکروپایتون را ببین.

اشکال‌های رایج مبتدی‌ها

قدم بعدی

حالا که زبان را بلدی، وقت ساختن است. به این ترتیب جلو برو: اولین چشمک‌زن روی پیکو، دکمه و وقفه، PWM و LED نفس‌کش و خواندن پتانسیومتر با ADC. همه‌ی آموزش‌های این برد در بخش رزبری پای پیکو جمع شده‌اند.

مثال input() و try/except را باز کن 🐍

سؤال‌های رایج

برای یادگیری میکروپایتون باید اول پایتون بلد باشم؟

نه. میکروپایتون خودش پایتون ۳ است، فقط کوچک‌تر. همین صفحه هر چیزی را که برای شروع لازم داری، از متغیر تا تابع و لیست، از صفر توضیح می‌دهد. اگر پایتون بلدی، فقط بخش machine و time برایت تازه است.

فرق میکروپایتون با پایتون معمولی چیست؟

زبان یکی است، ولی میکروپایتون برای حافظه‌ی چندصدکیلوبایتی ساخته شده: pip و کتابخانه‌های بزرگی مثل numpy ندارد، و به جایش ماژول machine را دارد که با پایه‌ها، PWM، ADC و I2C حرف می‌زند. ماژول time هم sleep_ms و ticks_ms اضافه دارد.

بدون برد واقعی می‌شود میکروپایتون تمرین کرد؟

بله. در شبیه‌ساز فارسی تینکرکد یک رزبری پای پیکوی مجازی با میکروپایتون واقعی اجرا می‌شود و LED، دکمه، پتانسیومتر و سریال مانیتور دارد. اجرای پیکو و میکروپایتون به اشتراک پلاس نیاز دارد و مثال‌های آماده برای خواندن رایگان باز می‌شوند.

چرا خطای IndentationError می‌گیرم؟

پایتون بلوک‌ها را با فاصله‌ی اول خط می‌شناسد، نه با آکولاد. همه‌ی خط‌های داخل یک if، for، while یا def باید دقیقاً به یک اندازه (معمولاً چهار فاصله) جلو رفته باشند و Tab و Space را با هم قاطی نکنی.

مقاله‌های مرتبط

📌

پین اوت رزبری پای پیکو: نقشه‌ی کامل ۴۰ پایه، GP، ADC، I2C، SPI، UART و تغذیه

🌗

PWM با میکروپایتون روی رزبری پای پیکو: LED نفس‌کش با duty_u16 و freq

🎛️

ADC رزبری پای پیکو با میکروپایتون: خواندن پتانسیومتر با read_u16 و تبدیل به ولتاژ

📟

نمایشگر LCD کاراکتری ۱۶×۲ با ماژول I2C در آردوینو

همه‌ی آموزش‌های رزبری پای پیکو و میکروپایتون ← · همه‌ی مقاله‌ها