3.16. בקרת סרוו

סרוו תחביבני (RC) הוא מנוע ממוזער עם ממסרה בתוך מארז אטום עם בקרת מיקום בלולאה סגורה מובנית. בתוך המארז יושבים מנוע DC, תיבת הילוכים מפחיתה, פוטנציומטר המחובר לציר היציאה, ולוח מנהל התקן קטן המשווה את קריאת הפוטנציומטר מול נקודת היעד המגיעה מבחוץ. מנהל ההתקן מריץ את המנוע בכיוון שמקטין את השגיאה, ועוצר כשהמיקום תואם. מצד המצלמה כל זה אינו נראה – אתה פשוט אומר לסרוו לאן ללכת.

3.16.1. אות ה-PWM

סרוו מקבל את נקודת היעד שלו כאות PWM בקצב פריימים קבוע של 50 Hz, כאשר רוחב הפולס בוחר את המיקום:

  • פולס של 1.0 ms מניע את הציר אל קצה אחד של טווח התנועה שלו.

  • פולס של 1.5 ms מחנה את הציר במרכז.

  • פולס של 2.0 ms מניע את הציר אל הקצה השני.

כל ערך ביניהם ממופה למיקום ביניים.

Three rows of square-wave traces stacked vertically. Each row shows one 20 ms period of a 50 Hz PWM with a narrow high pulse at the start: 1.0 ms in the top row, 1.5 ms in the middle, 2.0 ms in the bottom.

פריים ה-PWM של הסרוו אורכו 20 ms; רוחב הפולס (1.0 – 2.0 ms) בוחר את המיקום.

בניגוד לנוריות LED ולמנועים, הסרוו אינו ממצע את ה-PWM. רוחב הפולס עצמו הוא הפקודה: הלוגיקה הפנימית של הסרוו מודדת כל פולס, מגדירה את היעד שלה בהתאם, ומריצה את המנוע עד שהיציאה תואמת. מחזור העבודה כשבר (בין 5 % ל-10 % על פני הטווח המלא) הוא משני – זהו רוחב הפולס המוחלט שחשוב, וזה מה שהתוכנה צריכה לשלוט בו.

3.16.2. חיווט

סרוו תחביבני משתמש במחבר תלת-חוטי:

  • הספק (בדרך כלל אדום): אספקת החשמל של הסרוו עצמו, בדרך כלל 4.8 V עד 6 V. אל תזין את הסרוו ממסילת ה-3.3 V של המצלמה – היא אינה יכולה לספק את זרם העצירה, והמסילה תיפול במתח.

  • הארקה (בדרך כלל שחור או חום): נתיב החזרה עבור הספק הסרוו, קשור להארקת המצלמה כך שגם לאות יש ייחוס משותף.

  • אות (בדרך כלל לבן, צהוב, או כתום): קו ה-PWM מ-GPIO של המצלמה.

3.16.3. קוד

duty_u16() היה עובד, אך הוא מגדיר את מחזור העבודה כשבר מהמחזור – מסורבל עבור אות שבו רוחב הפולס המוחלט הוא מה שחשוב והמחזור קבוע. duty_ns() מגדיר את רוחב הפולס ישירות בננו-שניות:

from machine import PWM, Pin

servo = PWM(Pin("P7"), freq=50, duty_ns=1_500_000)  # centre

הנשא הוא 50 Hz (מחזור של 20 ms); הזמן הגבוה בכל מחזור הוא בדיוק 1500 µs. עוזר קטן הופך את מיפוי המיקום-לפולס למפורש:

def set_position(angle):
    # angle: 0..180 degrees mapped to 1.0..2.0 ms
    pulse_us = 1000 + (angle * 1000) // 180
    servo.duty_ns(pulse_us * 1000)

set_position(0)      # full one way
set_position(90)     # centre
set_position(180)    # full the other way

סריקה איטית על פני הטווח:

import time

for angle in range(0, 181, 5):
    set_position(angle)
    time.sleep_ms(20)
for angle in range(180, -1, -5):
    set_position(angle)
    time.sleep_ms(20)

הטווח 1.0 – 2.0 ms הוא הסטנדרט, אך סרוו רבים מקבלים טווח רחב יותר (לעיתים קרובות 500 µs עד 2500 µs) לטווח תנועה מלא. גיליון הנתונים של הסרוו מפרט את מגבלות רוחב הפולס המדויקות; מספרים מחוץ לטווח זה עלולים לטרוק את המנוע אל העצרים המכניים שלו.

עבור סרוו עם טווח לא-סטנדרטי, הרם את המגבלות לקבועים ופרמטרֵז את המיפוי:

PULSE_MIN_US = 500     # full one way (from the data sheet)
PULSE_MAX_US = 2500    # full the other way

def set_position(angle):
    span_us = PULSE_MAX_US - PULSE_MIN_US
    pulse_us = PULSE_MIN_US + (angle * span_us) // 180
    servo.duty_ns(pulse_us * 1000)