实例4:树莓派GPIO控制舵机转动
實例4:樹莓派GPIO控制舵機轉動
實驗目的
實驗要求
使用Python語言編程,在編程中使用PWM方法,通過樹莓派GPIO控制外部舵機來回擺動,角度范圍為0°~180°,周期為四秒。
實驗知識
1. 什么是舵機?
舵機(servomotor)是一種簡化版本的伺服電機,是位置伺服的驅動器,能夠通過輸入PWM信號控制旋轉角度,具備輕量、小型、簡化和性價比高的特點。
舵機適用于那些需要角度不斷變化并可以保持的簡單控制系統,它能實現較為精確的電機控制,在航模、遙控玩具、機器狗等品類上運用良好。
圖片1:一般舵機的外觀
2. 舵機的運動方式
舵機的運動方式是繞軸擺動,“舵機”一詞也和它的運動方式有關,舵機常用來擺動調整方向,就像海洋上的水手的舵一樣,航模和船模常常用舵機的擺動來調整一些零部件的角度。
圖片2:舵機的運動動圖
3. 舵機的組成結構
舵機一般是由保護外殼、內部集成控制芯片、小型直流電機、減速器齒輪組、位置檢測單元構成的。
當主控給舵機發出轉動信號時,控制芯片驅動電機開始轉動,通過減速器將動力傳達到輸出軸上的擺臂,由位置檢測單元反饋轉動結果信號給主控進行反饋調節。
一般來說,位置檢測單元可以是可變電阻,當舵機轉動時,可變電阻隨之改變,由此可得轉動的角度信息。舵機包含了電機、傳感器和控制器,是一個集成度高的、完整的伺服電機系統。
圖片3:舵機的內部結構拍攝
4. mini pupper定制舵機的部分硬件參數
芒碭科技MANGDANG針對mini pupper的運動需求,在原型舵機的基礎上優化改進了機械結構,定制了mini pupper專用舵機,這使得mini pupper的控制更加精確、動力更加澎湃。
圖片3:定制舵機的外觀
參考鏈接:mini pupper定制電機規格書 課程附件 MiniPupper-Servo-Spec.pdf
5.mini pupper舵機的控制方法
對于舵機的控制,首先要了解其基本硬件參數以及舵機對信號通訊的要求。
如圖所示,mini pupper一代舵機允許PWM的直接使用,也就是說,舵機可以直接連接到樹莓派上的GPIO_PWM端口使用而不需要考慮通訊協議,這對機器人入門開發者來說較為友好。
圖片4:舵機端口的連線
mini pupper一代舵機部分參數表
| 端口1(黃) | PWM Signal |
| 端口2(紅) | Vcc 4.8v~6v |
| 端口3 (棕) | GND |
| 信號周期 | 20ms |
| 信號頻率 | 50HZ |
| 脈沖長度范圍 | 500us-2500us to 0°~180° |
| 脈沖長度對應占空比 | 2.5% - 12.5% |
| 信號高電平范圍 | 2V-5V |
| 信號低電平范圍 | 0.0V-0.45V |
| 中間位對應脈沖 | 1500 μsec |
需要注意的是:
占空比=脈寬/周期
脈寬500us-2500us對應的占空比為2.5% - 12.5%
6. RPi的GPIO庫中PWM的用法
import RPi.GPIO as GPIO # 引入GPIO庫 GPIO.setmode(GPIO.BOARD) #初始化GPIO引腳編碼方式,需放在代碼正式開始處 GPIO.setup(12, GPIO.OUT) #初始化GPIO引腳設置,需放在代碼正式開始處 p = GPIO.PWM(channel, frequency) # 創建pwm實例 channel為引腳號 frequency為頻率 p.start(dc) # 開始pwm dc為初始占空比(0.0 <= dc <= 100.0) p.stop() # 停止pwm p.ChangeFrequency(freq) # 改變頻率(Hz)freq p.ChangeDutyCycle(dc) # 改變占空比(0.0 <= dc <= 100.0) GPIO.cleanup() # 清理GPIO引腳參考鏈接:RPi GPIO庫中PWM()函數的詳細資料
實驗步驟
1. 編寫Python程序 servo_PWM_GPIO.py
#!/usr/bin/python # coding:utf-8 # servo_PWM_GPIO.py # 樹莓派GPIO控制外部舵機來回擺動,角度范圍為0~180°,周期為4秒。 try:import RPi.GPIO as GPIO except RuntimeError:print("Error importing RPi.GPIO! This is probably because you need superuser privileges. "" You can achieve this by using 'sudo' to run your script") import timedef servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):"""功能:將某個范圍的值映射為另一個范圍的值參數:原范圍某值,原范圍最小值,原范圍最大值,變換后范圍最小值,變換后范圍最大值返回:變換后范圍對應某值"""percent = (before_value - before_range_min) / (before_range_max - before_range_min)after_value = after_range_min + percent * (after_range_max - after_range_min)return after_valueGPIO.setmode(GPIO.BOARD) # 初始化GPIO引腳編碼方式 servo_SIG = 32 servo_VCC = 4 servo_GND = 6 servo_freq = 50 servo_time = 0.01 servo_width_min = 2.5 servo_width_max = 12.5 # servo_degree_div =servo_width_max - servo_width_min)/180 GPIO.setup(servo_SIG, GPIO.OUT) # 如果你需要忽視引腳復用警告,請調用GPIO.setwarnings(False) # GPIO.setwarnings(False) servo = GPIO.PWM(servo_SIG, servo_freq) # 信號引腳=servo_SIG 頻率=servo_freq in HZ servo.start(0) servo.ChangeDutyCycle((servo_width_min+servo_width_max)/2) # 回歸舵機中位 print('預設置完成,兩秒后開始擺動') time.sleep(2) try: # try和except為固定搭配,用于捕捉執行過程中,用戶是否按下ctrl+C終止程序while 1:for dc in range(1, 181, 1):dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)servo.ChangeDutyCycle(dc_trans)# print(dc_trans)time.sleep(servo_time)time.sleep(0.2)for dc in range(180, -1, -1):dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)servo.ChangeDutyCycle(dc_trans)# print(dc_trans)time.sleep(servo_time)time.sleep(0.2) except KeyboardInterrupt:pass servo.stop() # 停止pwm GPIO.cleanup() # 清理GPIO引腳2. 運行程序servo_PWM_GPIO.py并觀察效果
在servo_PWM_GPIO.py的目錄下執行以下命令:
sudo python servo_PWM_GPIO.py此時應觀察到舵機在樹莓派的控制下來回擺動,角度范圍為0°~180°,周期為四秒。
3. 嘗試運行Python程序 servo_PWM_GPIO_2.py[可選]
如果你希望嘗試手動輸入一個角度值來轉動舵機,你可以試試servo_PWM_GPIO_2.py
#!/usr/bin/python # coding:utf-8 # servo_PWM_GPIO_2.py # 輸入一個角度值,舵機將轉動到對應的角度 try:import RPi.GPIO as GPIO except RuntimeError:print("Error importing RPi.GPIO! This is probably because you need superuser privileges. "" You can achieve this by using 'sudo' to run your script") import timedef servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):"""功能:將某個范圍的值映射為另一個范圍的值參數:原范圍某值,原范圍最小值,原范圍最大值,變換后范圍最小值,變換后范圍最大值返回:變換后范圍對應某值"""percent = (before_value - before_range_min) / (before_range_max - before_range_min)after_value = after_range_min + percent * (after_range_max - after_range_min)return after_valueGPIO.setmode(GPIO.BOARD) # 初始化GPIO引腳編碼方式 servo_SIG = 32 servo_VCC = 4 servo_GND = 6 servo_freq = 50 servo_time = 0.01 servo_width_min = 2.5 servo_width_max = 12.5 # servo_degree_div =servo_width_max - servo_width_min)/180 GPIO.setup(servo_SIG, GPIO.OUT) # 如果你需要忽視引腳復用警告,請調用GPIO.setwarnings(False) # GPIO.setwarnings(False) servo = GPIO.PWM(servo_SIG, servo_freq) # 信號引腳=servo_SIG 頻率=servo_freq in HZ servo.start(0) servo.ChangeDutyCycle((servo_width_min+servo_width_max)/2) # 回歸舵機中位 print('預設置完成,兩秒后開始等待輸入') time.sleep(2) # 為舵機指定位置 try: # try和except為固定搭配,用于捕捉執行過程中,用戶是否按下ctrl+C終止程序while 1:position = input("請輸入0°-180°的角度值:\n")if position.isdigit()==1:dc = int(position)if (dc>=0) and (dc<=180):dc_trans=servo_map(dc, 0, 180,servo_width_min,servo_width_max)servo.ChangeDutyCycle(dc_trans)print("已轉動到%d°處"%dc)else:print("Error Input:Exceed Range")else:print("Error Input:Not Int Input") except KeyboardInterrupt:passservo.stop() # 停止pwm GPIO.cleanup() # 清理GPIO引腳4.嘗試整機調零[可選]
為了確保控制精度,mini pupper上的舵機組通常在使用前先進行一次調零。
試試在命令行中運行舵機調零腳本 run_set_neatral.sh
如果希望了解校準的詳細信息,你可以查看mini pupper的官方文檔:校準
確保 Mini Pupper 已預先組裝好,使用GUI校準工具來優化腿部的位置。
對于每條腿,移動桿,使所有腿都成 45 度角。 腿的角度會隨著滑動條在屏幕上的位置而變化。
如果它不動,則說明您執行的步驟不正確。
您可以使用 iPhone 的傾斜傳感器app、尺子或量角器來測量角度。
實驗總結
經過本知識點的學習和實驗操作,你應該能達到以下水平:
| 舵機 | 舵機的外觀及基本運動方式 | ? | ||
| 舵機 | 單個舵機的組成結構 | ? | ||
| PWM | PWM方法對舵機進行轉動控制 | ? | ||
| 調零與校準 | mini pupper舵機組的調零與校準 | ? |
版權信息:教材尚未完善,此處預留版權信息處理方式
mini pupper相關內容可訪問:https://github.com/mangdangroboticsclub
總結
以上是生活随笔為你收集整理的实例4:树莓派GPIO控制舵机转动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赢在中国史玉柱的点评—史玉柱语录
- 下一篇: 基于蓝牙(HC-05)的安卓蓝牙 APP