
สารบัญ:
- ขั้นตอนที่ 1: BoM - บิลวัสดุ
- ขั้นตอนที่ 2: วิธีการทำงานของ PWM
- ขั้นตอนที่ 3: การติดตั้ง Hw
- ขั้นตอนที่ 4: การปรับเทียบเซอร์โว
- ขั้นตอนที่ 5: การสร้างสคริปต์ Python
- ขั้นตอนที่ 6: กลไกการแพนเอียง
- ขั้นตอนที่ 7: กลไกแพน-เอียง - การก่อสร้างทางกล
- ขั้นตอนที่ 8: ชุดแพน/เอียงไฟฟ้า
- ขั้นตอนที่ 9: สคริปต์ Python
- ขั้นตอนที่ 10: การทดสอบลูปของเซิร์ฟเวอร์
- ขั้นตอนที่ 11: บทสรุป
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-23 15:12

ในบทช่วยสอนนี้ เราจะสำรวจวิธีควบคุมเซอร์โวหลายตัวโดยใช้ Python บน Raspberry Pi เป้าหมายของเราคือกลไก PAN/TILT เพื่อจัดตำแหน่งกล้อง (PiCam)
คุณสามารถดูว่าโครงการสุดท้ายของเราทำงานอย่างไร:
ควบคุมการทดสอบลูปควบคุมเซอร์โว:

ขั้นตอนที่ 1: BoM - บิลวัสดุ
ส่วนหลัก:
- Raspberry Pi V3 - 32.00 เหรียญสหรัฐ
- 5 ล้านพิกเซล 1080p เซนเซอร์ OV5647 Mini กล้อง โมดูลวิดีโอ - US$13.00
- TowerPro SG90 9G 180 องศา Micro Servo (2 X)- US$ 4.00
- Mini Pan/Tilt Camera Platform Anti-Vibration Camera Mount พร้อมเซอร์โว 2 ตัว (*) - US$ 8.00
- ตัวต้านทาน 1K โอห์ม (2X) - อุปกรณ์เสริม
- เบ็ดเตล็ด: ชิ้นส่วนโลหะ สายรัด ฯลฯ (ในกรณีที่คุณจะสร้างกลไกแพน/เอียง)
(*) คุณสามารถซื้อแพลตฟอร์ม Pan/Tilt ที่สมบูรณ์พร้อมเซอร์โวหรือสร้างของคุณเองได้
ขั้นตอนที่ 2: วิธีการทำงานของ PWM
Raspberry Pi ไม่มีเอาต์พุตแบบอะนาล็อก แต่เราสามารถจำลองสิ่งนี้ได้โดยใช้วิธี PWM (Pulse Width Modulation) สิ่งที่เราจะทำคือสร้างสัญญาณดิจิตอลที่มีความถี่คงที่ โดยเราจะเปลี่ยนความกว้างของพัลส์เทรน สิ่งที่จะ "แปล" เป็นระดับแรงดันเอาต์พุต "เฉลี่ย" ดังแสดงด้านล่าง:

เราสามารถใช้ระดับแรงดันไฟฟ้า "เฉลี่ย" นี้เพื่อควบคุมความสว่างของ LED เช่น:

โปรดทราบว่าสิ่งที่สำคัญในที่นี้ไม่ใช่ความถี่ แต่เป็น "วัฏจักรหน้าที่" นั่นคือความสัมพันธ์ระหว่างเวลาที่พัลส์ "สูง" หารด้วยคาบคลื่น ตัวอย่างเช่น สมมติว่าเราจะสร้างความถี่พัลส์ 50Hz บน Raspberry Pi GPIO ตัวใดตัวหนึ่งของเรา ช่วงเวลา (p) จะเป็นค่าผกผันของความถี่หรือ 20ms (1/f) หากเราต้องการให้ LED ของเรามีความสว่าง "ครึ่งหนึ่ง" เราต้องมีวัฏจักรหน้าที่ 50% ซึ่งหมายถึง "ชีพจร" ที่จะ "สูง" เป็นเวลา 10 มิลลิวินาที
หลักการนี้จะสำคัญมากสำหรับเราในการควบคุมตำแหน่งเซอร์โวของเรา เมื่อ "รอบการทำงาน" จะกำหนดตำแหน่งเซอร์โวดังที่แสดงด้านล่าง:
เซอร์โว
ขั้นตอนที่ 3: การติดตั้ง Hw


เซอร์โวจะเชื่อมต่อกับแหล่งจ่ายไฟ 5V ภายนอก โดยมีดาต้าพิน (ในกรณีของฉันคือสายไฟสีเหลือง) เชื่อมต่อกับ Raspberry Pi GPIO ดังนี้:
- GPIO 17 ==> เซอร์โวเอียง
- GPIO 27 ==> แพนเซอร์โว
อย่าลืมเชื่อมต่อ GND เข้าด้วยกัน ==> Raspberry Pi - เซอร์โว - แหล่งจ่ายไฟภายนอก)
คุณสามารถมีตัวต้านทาน 1K โอห์มระหว่าง Raspberry Pi GPIO และขาอินพุตข้อมูลของเซิร์ฟเวอร์เป็นตัวเลือกได้ สิ่งนี้จะปกป้อง RPi ของคุณในกรณีที่เกิดปัญหาเซอร์โว
ขั้นตอนที่ 4: การปรับเทียบเซอร์โว



สิ่งแรกที่ต้องทำคือยืนยันคุณสมบัติหลักของเซอร์โวของคุณ ในกรณีของฉัน ฉันใช้ Power Pro SG90
จากแผ่นข้อมูล เราสามารถพิจารณา:
- ช่วง: 180o
- แหล่งจ่ายไฟ: 4.8V (ภายนอก 5VDC เนื่องจากแหล่งจ่ายไฟ USB ทำงานได้ดี)
- ความถี่ในการทำงาน: 50Hz (ระยะเวลา: 20 ms)
- ความกว้างพัลส์: จาก 1ms ถึง 2ms
ตามทฤษฎีแล้วเซอร์โวจะอยู่ที่
- ตำแหน่งเริ่มต้น (0 องศา) เมื่อใช้พัลส์ 1 มิลลิวินาทีกับขั้วข้อมูล
- ตำแหน่งเป็นกลาง (90 องศา) เมื่อใช้พัลส์ 1.5 มิลลิวินาทีกับขั้วข้อมูล
- ตำแหน่งสุดท้าย (180 องศา) เมื่อใช้พัลส์ 2 มิลลิวินาทีกับขั้วข้อมูล
ในการตั้งโปรแกรมตำแหน่งเซอร์โวโดยใช้ Python เป็นสิ่งสำคัญมากที่จะต้องทราบ "Duty Cycle" ของนักข่าวสำหรับตำแหน่งข้างต้น มาคำนวณกัน:
- ตำแหน่งเริ่มต้น ==> (0 องศา) ความกว้างของพัลส์ ==> 1ms ==> รอบการทำงาน = 1ms/20ms ==> 2.0%
- ตำแหน่งเป็นกลาง (90 องศา) ความกว้างพัลส์ 1.5 ms ==> รอบการทำงาน = 1.5ms/20ms ==> 7.5%
- ตำแหน่งสุดท้าย (180 องศา) ความกว้างพัลส์ 2 ms ==> รอบการทำงาน = 2ms/20ms ==> 10%
ดังนั้นวัฏจักรหน้าที่ควรจะแตกต่างกันไปในช่วง 2 ถึง 10 %
มาทดสอบเซอร์โวทีละตัวกัน สำหรับสิ่งนั้น ให้เปิดเทอร์มินัล Raspberry ของคุณและเปิดตัวแก้ไขเชลล์ Python 3 ของคุณเป็น "sudo" (เพราะคุณควรเป็น "ผู้ใช้ขั้นสูง" เพื่อจัดการกับ GPIO):
sudo python3
บน Python Shell
>>
นำเข้าโมดูล RPI. GPIO และเรียกมันว่า GPIO:
นำเข้า RPi. GPIO เป็น GPIO
กำหนดรูปแบบการกำหนดหมายเลขพินที่คุณต้องการใช้ (BCM หรือ BOARD) ฉันทำการทดสอบนี้กับ BOARD ดังนั้นหมุดที่ฉันใช้คือพินจริง (GPIO 17 = Pin 11 และ GPIO 27 Pin 13) ง่ายสำหรับฉันที่จะระบุพวกเขาและไม่ทำผิดพลาดระหว่างการทดสอบ (ในโปรแกรมสุดท้ายฉันจะใช้ BCM) เลือกหนึ่งที่คุณต้องการ:
GPIO.setmode(GPIO.บอร์ด)
กำหนดเซอร์โวพินที่คุณใช้:
เอียงขา = 11
ถ้าคุณใช้รูปแบบ BCM แทน คำสั่ง 2 คำสั่งสุดท้ายควรถูกแทนที่ด้วย:
GPIO.setmode(GPIO. BCM)
เอียงขา = 17
ตอนนี้เราต้องระบุว่าพินนี้จะเป็น "เอาต์พุต"
GPIO.setup (tiltPin, GPIO. ออก)
และความถี่ที่สร้างขึ้นบนพินนี้จะเป็นอย่างไรสำหรับเซอร์โวของเราจะเป็น 50Hz:
เอียง = GPIO. PWM(tiltPin, 50)
ตอนนี้ มาเริ่มสร้างสัญญาณ PWM บนพินด้วยรอบการทำงานเริ่มต้น (เราจะเก็บเป็น "0"):
เอียง = เริ่ม (0)
ตอนนี้คุณสามารถป้อนค่ารอบการทำงานที่แตกต่างกัน โดยสังเกตการเคลื่อนไหวของเซอร์โวของคุณ เริ่มต้นด้วย 2% และดูว่าเกิดอะไรขึ้น (เรามองว่าเซอร์โวไปที่ "ตำแหน่งศูนย์"):
เอียง. ChangeDutyCycle(2)
ในกรณีของฉัน เซอร์โวไปที่ตำแหน่งศูนย์ แต่เมื่อฉันเปลี่ยนรอบการทำงานเป็น 3% ฉันสังเกตว่าเซอร์โวอยู่ในตำแหน่งเดิม โดยเริ่มเคลื่อนที่ด้วยรอบการทำงานที่มากกว่า 3% ดังนั้น 3% คือตำแหน่งเริ่มต้นของฉัน (o องศา) สิ่งเดียวกันนี้เกิดขึ้นกับ 10% เซอร์โวของฉันอยู่เหนือค่านี้ โดยเพิ่มจุดสิ้นสุดที่ 13% ดังนั้นสำหรับเซอร์โวตัวนี้ ผลลัพธ์คือ:
- 0 องศา ==> รอบการทำงาน 3%
- 90 องศา ==> รอบการทำงาน 8%
- 180 องศา ==> รอบการทำงาน 13%
หลังจากคุณเสร็จสิ้นการทดสอบ คุณต้องหยุด PWM และล้าง GPIO:
เอียง = หยุด ()
GPIO. การล้างข้อมูล ()
หน้าจอการพิมพ์ Terminal ด้านบนแสดงผลลัพธ์สำหรับเซอร์โวทั้งสองของฉัน (ที่มีผลลัพธ์คล้ายกัน) ช่วงของคุณอาจแตกต่างกัน
ขั้นตอนที่ 5: การสร้างสคริปต์ Python

คำสั่ง PWM ที่จะส่งไปยังเซอร์โวของเราอยู่ใน "รอบการทำงาน" ตามที่เราเห็นในขั้นตอนสุดท้าย แต่โดยปกติ เราต้องใช้ "มุม" เป็นองศาเป็นพารามิเตอร์ในการควบคุมเซอร์โว ดังนั้น เราต้องแปลง "มุม" ที่เป็นการวัดที่เป็นธรรมชาติมากขึ้นสำหรับเราในวัฏจักรหน้าที่ตามที่ Pi ของเราเข้าใจ
ทำอย่างไร? ง่ายมาก! เรารู้ว่าช่วงรอบการทำงานเปลี่ยนจาก 3% เป็น 13% และเทียบเท่ากับมุมที่จะอยู่ในช่วงตั้งแต่ 0 ถึง 180 องศา นอกจากนี้ เรารู้ว่ารูปแบบเหล่านั้นเป็นแบบเชิงเส้น เราจึงสามารถสร้างสคีมาตามสัดส่วนดังที่แสดงด้านบน จากมุม เราสามารถมีวัฏจักรหน้าที่สัมพันธ์กัน:
รอบการทำงาน = มุม/18 + 3
เก็บสูตรนี้ไว้ เราจะใช้ในรหัสถัดไป
มาสร้างสคริปต์ Python เพื่อดำเนินการทดสอบกัน โดยพื้นฐานแล้ว เราจะทำซ้ำสิ่งที่เราทำก่อนหน้านี้ใน Python Shell:
จากเวลานำเข้าการนอนหลับ
นำเข้า RPi. GPIO เป็น GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) def setServoAngle(servo, angle): pwm = GPIO. PWM(servo, 50) pwm.start(8) dutyCycle = angle / 18 + 3. pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': import sys servo = int(sys.argv[1]) GPIO.setup(servo, GPIO. OUT) setServoAngle (เซอร์โว, int(sys.argv[2]))) GPIO.cleanup()
แกนหลักของโค้ดด้านบนคือฟังก์ชัน setServoAngle(เซอร์โว, มุม) ฟังก์ชันนี้รับเป็นอาร์กิวเมนต์ หมายเลข GPIO ของเซอร์โว และค่ามุมไปยังตำแหน่งที่เซอร์โวต้องอยู่ในตำแหน่ง เมื่ออินพุตของฟังก์ชันนี้คือ "มุม" เราต้องแปลงเป็นวัฏจักรหน้าที่เป็นเปอร์เซ็นต์ โดยใช้สูตรที่พัฒนามาก่อน
เมื่อสคริปต์ทำงาน คุณต้องป้อนเป็นพารามิเตอร์, เซอร์โว GPIO และมุม
ตัวอย่างเช่น:
sudo python3 angleServoCtrl.py 17 45
คำสั่งดังกล่าวจะกำหนดตำแหน่งเซอร์โวที่เชื่อมต่อกับ GPIO 17 โดยมี 45 องศาใน "ระดับความสูง" สามารถใช้คำสั่งที่คล้ายกันสำหรับการควบคุม Pan Servo (ตำแหน่ง 45 องศาใน "ราบ"):
sudo python angleServoCtrl.py 27 45
ไฟล์ angleServoCtrl.py สามารถดาวน์โหลดได้จาก GitHub. ของฉัน
ขั้นตอนที่ 6: กลไกการแพนเอียง

เซอร์โว "แพน" จะเคลื่อนที่ "ในแนวนอน" กล้องของเรา ("มุมราบ") และเซอร์โว "เอียง" ของเราจะย้าย "ในแนวตั้ง" (มุมยก)
ภาพด้านล่างแสดงให้เห็นว่ากลไกการแพน/เอียงทำงานอย่างไร:

ในระหว่างการพัฒนา เราจะไม่ "สุดขั้ว" และเราจะใช้กลไกการแพน/เอียงของเราตั้งแต่ 30 ถึง 150 องศาเท่านั้น ช่วงนี้จะเพียงพอสำหรับใช้กับกล้อง
ขั้นตอนที่ 7: กลไกแพน-เอียง - การก่อสร้างทางกล



มาประกอบเซอร์โว 2 ตัวของเราเป็นกลไก Pan/Tilt กัน คุณสามารถทำ 2 สิ่งที่นี่ ซื้อกลไกแพลตฟอร์ม Pan-Tilt ตามที่แสดงในขั้นตอนสุดท้ายหรือสร้างของคุณเองตามความจำเป็น
ตัวอย่างหนึ่งอาจเป็นแบบที่ฉันสร้างขึ้น โดยผูกแค่เซอร์โวเข้าด้วยกัน และใช้ชิ้นส่วนโลหะขนาดเล็กจากของเล่นเก่าดังที่แสดงในภาพด้านบน
ขั้นตอนที่ 8: ชุดแพน/เอียงไฟฟ้า




เมื่อคุณประกอบกลไกการแพน/เอียงแล้ว ให้ทำตามรูปถ่ายเพื่อเชื่อมต่อไฟฟ้าอย่างเต็มรูปแบบ
- ปิด Pi ของคุณ
- ทำการเชื่อมต่อไฟฟ้าทั้งหมด
- ตรวจสอบอีกครั้ง
- เปิด Pi ของคุณก่อน
- หากทุกอย่างเรียบร้อย ให้เพิ่มพลังให้เซอร์โวของคุณ
เราจะไม่สำรวจในบทช่วยสอนนี้เกี่ยวกับวิธีตั้งค่ากล้อง ซึ่งจะอธิบายในบทช่วยสอนถัดไป
ขั้นตอนที่ 9: สคริปต์ Python
มาสร้างสคริปต์ Python เพื่อควบคุมเซอร์โวทั้งสองพร้อมกัน:
จากเวลานำเข้าการนอนหลับ
นำเข้า RPi. GPIO เป็น GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT)) # สีเทา ==> PAN def setServoAngle (เซอร์โว, มุม): ยืนยันมุม >=30 และมุม 90 (จุดตรงกลาง) ==> 150 setServoAngle (เอียง, int (sys.argv [2])) # 30 ==> 90 (จุดตรงกลาง) ==> 150 GPIO.cleanup()
เมื่อสคริปต์ทำงาน คุณต้องป้อนเป็นพารามิเตอร์ มุมแพน และ มุมเอียง ตัวอย่างเช่น:
sudo python3 servoCtrl.py 45 120
คำสั่งด้านบนจะกำหนดตำแหน่งกลไกการแพน/เอียง 45 องศาใน "มุมเอียง" (มุมแพน) และ "ระดับความสูง" 120 องศา (มุมเอียง) โปรดทราบว่าหากไม่มีการป้อนพารามิเตอร์ ค่าเริ่มต้นจะเป็นทั้งมุมแพนและเอียงที่ตั้งค่าไว้ที่ 90 องศา
ด้านล่างนี้คุณสามารถดูการทดสอบบางอย่าง:

ไฟล์ servoCtrl.py สามารถดาวน์โหลดได้จาก GitHub ของฉัน
ขั้นตอนที่ 10: การทดสอบลูปของเซิร์ฟเวอร์
มาสร้างสคริปต์ Python เพื่อทดสอบเซอร์โวแบบเต็มช่วงโดยอัตโนมัติ:
จากเวลานำเข้าการนอนหลับ
นำเข้า RPi. GPIO เป็น GPIO GPIO.setmode(GPIO. BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO. OUT) # white => TILT GPIO.setup(pan, GPIO. OUT)) # สีเทา ==> PAN def setServoAngle(เซอร์โว, มุม): มุมยืนยัน >=30 และมุม <= 150 pwm = GPIO. PWM(เซอร์โว, 50) pwm.start(8) dutyCycle = มุม / 18. + 3 pwm. ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if _name_ == '_main_': for i in range (30, 160, 15): setServoAngle(pan, i) setServoAngle(tilt, i) for i in ช่วง (150, 30, -15): setServoAngle(แพน, i) setServoAngle(เอียง, i) setServoAngle(แพน, 100) setServoAngle(เอียง, 90) GPIO.cleanup()
โปรแกรมจะดำเนินการวนซ้ำโดยอัตโนมัติตั้งแต่ 30 ถึง 150 องศาในทั้งสองมุม
ด้านล่างผลลัพธ์:
ฉันเชื่อมต่อออสซิลโลสโคปเพื่อแสดงทฤษฎี PWM ตามที่อธิบายไว้ก่อนหน้านี้เท่านั้น

สามารถดาวน์โหลดรหัสด้านบน servoTest.py ได้จาก GitHub ของฉัน
ขั้นตอนที่ 11: บทสรุป

และเช่นเคย ฉันหวังว่าโครงการนี้จะช่วยให้ผู้อื่นค้นพบหนทางสู่โลกที่น่าตื่นเต้นของอิเล็กทรอนิกส์!
สำหรับรายละเอียดและรหัสสุดท้าย โปรดไปที่ศูนย์ฝาก GitHub ของฉัน: RPi-Pan-Tilt-Servo-Control
สำหรับโครงการเพิ่มเติม โปรดเยี่ยมชมบล็อกของฉัน: MJRoBot.org
ด้านล่างเหลือบของบทช่วยสอนถัดไปของฉัน:

Saludos จากทางใต้ของโลก!
พบกันใหม่ในคำสั่งต่อไปของฉัน!
ขอขอบคุณ, มาร์เซโล
แนะนำ:
Multi-channel Wifi Voltage & Current Meter: 11 ขั้นตอน (พร้อมรูปภาพ)

เครื่องวัดแรงดันและกระแสไฟ Wifi แบบหลายช่องสัญญาณ: เมื่อทำบอร์ดบอร์ด เรามักจะต้องตรวจสอบส่วนต่างๆ ของวงจรในคราวเดียว เพื่อหลีกเลี่ยงความเจ็บปวดที่ต้องติดโพรบมัลติมิเตอร์จากที่หนึ่งไปอีกที่หนึ่ง ฉันต้องการออกแบบมิเตอร์วัดแรงดันและกระแสแบบหลายช่องสัญญาณ บอร์ด Ina260
Arduino Multi Light Controller: 7 ขั้นตอน (พร้อมรูปภาพ)

Arduino Multi Light Controller: เพื่อนร่วมงานและศิลปิน Jim Hobbs กำลังวางแผนที่จะสร้างการติดตั้งอิสระสำหรับนิทรรศการที่เขากำลังรวบรวม การติดตั้งนี้จะประกอบด้วยชั้นวาง 8 ชั้นที่สร้างรูปทรงพาราโบลา ชั้นวาง 8 ชั้นแต่ละชั้นต้องมีหลอดไฟ 10 หลอด
HiFi Multi-room WiFi & Bluetooth Speaker: 10 ขั้นตอน (พร้อมรูปภาพ)

HiFi Multi-room WiFi & Bluetooth Speaker: ลำโพงที่เชื่อมต่อ Wi-Fi สามารถให้คุณภาพเสียงที่ดีกว่าตัวเลือก Bluetooth อย่างเห็นได้ชัด พวกเขาไม่บีบอัดเนื้อหาเสียงก่อนเล่น ซึ่งอาจส่งผลเสียต่อเสียง เนื่องจากจะลดระดับของรายละเอียดข
Multi-Color Light Painter (ไวต่อการสัมผัส): 8 ขั้นตอน (พร้อมรูปภาพ)

Multi-Color Light Painter (Touch Sensitive): การวาดด้วยแสงเป็นเทคนิคการถ่ายภาพที่ใช้เพื่อสร้างเอฟเฟกต์พิเศษที่ความเร็วชัตเตอร์ต่ำ ไฟฉายมักใช้เพื่อ "ระบายสี" ภาพ ในคำแนะนำนี้ ฉันจะแสดงให้คุณเห็นถึงวิธีสร้างจิตรกรแสงแบบออลอินวันด้วยการสัมผัส
One Control Multi LED Strips: 3 ขั้นตอน

One Control Multi LED Strips: ฉันมีเฟอร์นิเจอร์ 5 ชิ้นซึ่งฉันต้องการติดตั้งไฟแถบ LED ไฟ LED จะต้องถูกควบคุมจากระยะไกลพร้อมตัวเลือกสำหรับเปิด/ปิดของ Alexa ไฟ LED ทั้งหมดต้องเปิดเครื่อง & เปลี่ยนสีได้ด้วยการกดที่รีโมทคอนโทรลเพียงครั้งเดียว พวกเขายัง