สารบัญ:

Pan-Tilt Multi Servo Control: 11 ขั้นตอน (พร้อมรูปภาพ)
Pan-Tilt Multi Servo Control: 11 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: Pan-Tilt Multi Servo Control: 11 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: Pan-Tilt Multi Servo Control: 11 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: Pan Tilt Control using Servos for ESP32 Cam | WiFi Security Camera 2024, พฤศจิกายน
Anonim
การควบคุมเซอร์โวแบบแพนเอียงหลายตัว
การควบคุมเซอร์โวแบบแพนเอียงหลายตัว

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

คุณสามารถดูว่าโครงการสุดท้ายของเราทำงานอย่างไร:

ควบคุมการทดสอบลูปควบคุมเซอร์โว:

ภาพ
ภาพ

ขั้นตอนที่ 1: BoM - บิลวัสดุ

ส่วนหลัก:

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

(*) คุณสามารถซื้อแพลตฟอร์ม Pan/Tilt ที่สมบูรณ์พร้อมเซอร์โวหรือสร้างของคุณเองได้

ขั้นตอนที่ 2: วิธีการทำงานของ PWM

Raspberry Pi ไม่มีเอาต์พุตแบบอะนาล็อก แต่เราสามารถจำลองสิ่งนี้ได้โดยใช้วิธี PWM (Pulse Width Modulation) สิ่งที่เราจะทำคือสร้างสัญญาณดิจิตอลที่มีความถี่คงที่ โดยเราจะเปลี่ยนความกว้างของพัลส์เทรน สิ่งที่จะ "แปล" เป็นระดับแรงดันเอาต์พุต "เฉลี่ย" ดังแสดงด้านล่าง:

ภาพ
ภาพ

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

ภาพ
ภาพ

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

หลักการนี้จะสำคัญมากสำหรับเราในการควบคุมตำแหน่งเซอร์โวของเรา เมื่อ "รอบการทำงาน" จะกำหนดตำแหน่งเซอร์โวดังที่แสดงด้านล่าง:

เซอร์โว

ขั้นตอนที่ 3: การติดตั้ง Hw

การติดตั้ง Hw
การติดตั้ง Hw
การติดตั้ง Hw
การติดตั้ง 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

การสร้างสคริปต์ Python
การสร้างสคริปต์ 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: ชุดแพน/เอียงไฟฟ้า

ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า
ชุดแพน/เอียงไฟฟ้า

เมื่อคุณประกอบกลไกการแพน/เอียงแล้ว ให้ทำตามรูปถ่ายเพื่อเชื่อมต่อไฟฟ้าอย่างเต็มรูปแบบ

  1. ปิด Pi ของคุณ
  2. ทำการเชื่อมต่อไฟฟ้าทั้งหมด
  3. ตรวจสอบอีกครั้ง
  4. เปิด Pi ของคุณก่อน
  5. หากทุกอย่างเรียบร้อย ให้เพิ่มพลังให้เซอร์โวของคุณ

เราจะไม่สำรวจในบทช่วยสอนนี้เกี่ยวกับวิธีตั้งค่ากล้อง ซึ่งจะอธิบายในบทช่วยสอนถัดไป

ขั้นตอนที่ 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 จากทางใต้ของโลก!

พบกันใหม่ในคำสั่งต่อไปของฉัน!

ขอขอบคุณ, มาร์เซโล

แนะนำ: