🦾 سروو موتور با میکروپایتون روی رزبری پای پیکو: PWM پنجاه هرتز و کنترل زاویه

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

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

سروو چطور زاویه را می‌فهمد؟

سروو هر ۲۰ میلی‌ثانیه (یعنی ۵۰ بار در ثانیه) منتظر یک پالس است. پهنای این پالس زاویه را می‌گوید:

زاویهپهنای پالس (SG90)معادل duty_u16
۰ درجهحدود ۰٫۵ میلی‌ثانیه (۵۰۰ میکروثانیه)حدود ۱۶۳۸
۹۰ درجهحدود ۱٫۵ میلی‌ثانیهحدود ۴۹۱۵
۱۸۰ درجهحدود ۲٫۵ میلی‌ثانیهحدود ۸۱۹۱

عدد ستون آخر از این‌جا می‌آید: کل چرخه ۲۰۰۰۰ میکروثانیه است و duty_u16 کل چرخه را ۶۵۵۳۵ می‌داند؛ پس دیوتی برابر پهنای پالس ضرب در ۶۵۵۳۵ تقسیم بر ۲۰۰۰۰ است. داخل سروو یک موتور کوچک، چرخ‌دنده و یک پتانسیومتر هست که مدام زاویه‌ی واقعی را با زاویه‌ی خواسته‌شده مقایسه و اصلاح می‌کند. برای همین سروو در زاویه‌اش «قفل» می‌ماند. فرقش با موتور DC معمولی را در سروو یا موتور DC؟ بخوان.

قطعه‌ها و سیم‌کشی

سیم سرووپایه‌ی پیکو
قهوه‌ای یا مشکی (GND)GND، مثلاً پایه‌ی فیزیکی ۳۸
قرمز (VCC)VBUS، پایه‌ی فیزیکی ۴۰ (پنج ولت USB)
نارنجی یا زرد (سیگنال)GP15، پایه‌ی فیزیکی ۲۰

پتانسیومتر: دو پایه‌ی کناری به 3V3(OUT) و GND، پایه‌ی وسط به GP26. سیگنال ۳٫۳ ولتی پیکو برای سرووهای رایج کافی است و مبدل سطح لازم نیست.

سروو موقع شروع حرکت یک لحظه جریان زیادی (چند صد میلی‌آمپر) می‌کشد. اگر پیکو هنگام حرکت سروو ری‌استارت شد یا برنامه عجیب رفتار کرد، یک خازن ۴۷۰ میکروفاراد بین VBUS و GND نزدیک سروو بگذار یا سروو را از منبع جدا تغذیه کن.

کد ۱: جاروب ۰ تا ۱۸۰ درجه

from machine import Pin, PWM
import time

servo = PWM(Pin(15))
servo.freq(50)                 # 50 Hz: one pulse every 20 ms

MIN_US = 500                   # pulse for 0 degrees (SG90)
MAX_US = 2500                  # pulse for 180 degrees

def set_angle(angle):
    angle = max(0, min(180, angle))
    pulse_us = MIN_US + (MAX_US - MIN_US) * angle / 180
    servo.duty_ns(int(pulse_us * 1000))   # microseconds -> nanoseconds

while True:
    for a in range(0, 181, 5):
        set_angle(a)
        time.sleep_ms(30)
    time.sleep(0.5)
    for a in range(180, -1, -5):
        set_angle(a)
        time.sleep_ms(30)
    time.sleep(0.5)

توضیح خط به خط

کد ۲: کنترل زاویه با پتانسیومتر

حالا عدد ADC پتانسیومتر را به زاویه تبدیل می‌کنیم. این بار برای اینکه هر دو راه را دیده باشی، پالس را با duty_u16 می‌سازیم:

from machine import Pin, PWM, ADC
import time

servo = PWM(Pin(15))
servo.freq(50)
knob = ADC(26)                 # potentiometer on GP26

def set_angle(angle):
    pulse_us = 500 + 2000 * angle / 180
    servo.duty_u16(int(pulse_us * 65535 / 20000))

last = -1
while True:
    angle = knob.read_u16() * 180 // 65535
    if abs(angle - last) > 1:          # ignore tiny jitter
        set_angle(angle)
        last = angle
        print("angle:", angle)
    time.sleep_ms(20)

شرط abs(angle - last) > 1 لرزش کوچک ADC را نادیده می‌گیرد؛ بدون آن سروو مدام یک درجه این‌طرف و آن‌طرف می‌رود و صدای ریز می‌دهد. knob.read_u16() * 180 // 65535 همان map است که ۰ تا ۶۵۵۳۵ را به ۰ تا ۱۸۰ می‌برد.

چند سروو و سروو پیوسته

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

در شبیه‌ساز تینکرکد فارسی یک رزبری پای پیکو، یک سروو و یک پتانسیومتر بگذار، سیم‌ها را مثل جدول بالا بکش و هر کدام از دو کد را اجرا کن. شبیه‌ساز سیگنال ۵۰ هرتز را مثل سروو واقعی به زاویه تبدیل می‌کند و بازوی سروو را می‌چرخاند. پیکو و میکروپایتون جزو اشتراک پلاس هستند. اگر می‌خواهی اول رایگان تمرین کنی، همین پروژه به زبان آردوینو آماده است: پتانسیومتر کنترل سروو و سروو موتور — جاروب، و درس کاملش کنترل سروو با ولوم.

اشکال‌های رایج

این آموزش همان سروو آردوینو است به زبان پایتون؛ نسخه‌ی ++C را در سروو موتور با آردوینو و نسخه‌ی ESP32 را در سروو با ESP32 ببین. اگر PWM برایت تازه است، اول PWM با میکروپایتون را بخوان. ایده‌ی بعدی: یک سنسور اولتراسونیک روی سروو بگذار و یک رادار بساز.

پیکو و سروو را در شبیه‌ساز بچین 🦾

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

برای سروو در میکروپایتون کتابخانه لازم است؟

نه. سروو فقط یک سیگنال PWM با فرکانس ۵۰ هرتز می‌خواهد که پهنای پالسش زاویه را تعیین می‌کند. با کلاس PWM از ماژول machine و یک تابع چندخطی set_angle کار تمام است.

سروو را به کدام پایه‌ی تغذیه‌ی پیکو وصل کنم؟

یک سروو کوچک مثل SG90 را وقتی پیکو با USB تغذیه می‌شود می‌توانی به VBUS (پایه‌ی ۴۰، پنج ولت) بزنی. هرگز آن را به 3V3(OUT) وصل نکن. برای سرووهای بزرگ مثل MG996R یا چند سروو، منبع ۵ تا ۶ ولت جدا بگذار و زمین‌ها را به هم وصل کن.

چرا سروو به ۰ یا ۱۸۰ درجه‌ی کامل نمی‌رسد؟

پهنای پالس مناسب هر مدل فرق دارد. SG90 معمولاً با ۵۰۰ تا ۲۵۰۰ میکروثانیه کل بازه را می‌رود و بعضی سرووها با ۱۰۰۰ تا ۲۰۰۰. عددهای MIN_US و MAX_US را کم‌کم تغییر بده تا بازه‌ی کامل را بگیری، ولی آن‌قدر زیاد نکن که سروو به ته برسد و وزوز کند.

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

📏

سنسور اولتراسونیک HC-SR04 با میکروپایتون روی رزبری پای پیکو (time_pulse_us)

📟

راه‌اندازی LCD I2C با میکروپایتون روی رزبری پای پیکو (درایور i2c_lcd)

🌡️

سنسور دما و رطوبت DHT11 و DHT22 با میکروپایتون روی رزبری پای پیکو

🚶

سنسور حرکت PIR با آردوینو: از دزدگیر ساده تا چراغ راهروی هوشمند

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