3.16. בקרת סרוו¶
סרוו תחביבני (RC) הוא מנוע ממוזער עם ממסרה בתוך מארז אטום עם בקרת מיקום בלולאה סגורה מובנית. בתוך המארז יושבים מנוע DC, תיבת הילוכים מפחיתה, פוטנציומטר המחובר לציר היציאה, ולוח מנהל התקן קטן המשווה את קריאת הפוטנציומטר מול נקודת היעד המגיעה מבחוץ. מנהל ההתקן מריץ את המנוע בכיוון שמקטין את השגיאה, ועוצר כשהמיקום תואם. מצד המצלמה כל זה אינו נראה – אתה פשוט אומר לסרוו לאן ללכת.
3.16.1. אות ה-PWM¶
סרוו מקבל את נקודת היעד שלו כאות PWM בקצב פריימים קבוע של 50 Hz, כאשר רוחב הפולס בוחר את המיקום:
פולס של 1.0 ms מניע את הציר אל קצה אחד של טווח התנועה שלו.
פולס של 1.5 ms מחנה את הציר במרכז.
פולס של 2.0 ms מניע את הציר אל הקצה השני.
כל ערך ביניהם ממופה למיקום ביניים.
פריים ה-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)