python舵机控制程序_树莓派PWM控制舵机的两种方式
PWM控制舵機簡介
通常情況下,伺服電機(舵機)是由一個標準的直流系統和一個內部反饋控制裝置(一個減速齒輪和電位計)來組成的。伺服電機(舵機)的主要作用是將齒輪軸旋轉到一個預定義的方向上。伺服電機(舵機)有3個輸入引腳,GND、VCC和Signal。脈沖寬度調制技術(PWM)被應用于舵機的控制,軸的方向由脈沖的持續時間決定(參見樹莓派3 B+Servoblaster 舵機控制,了解更多關于PWM的信息)。需要記住的是,舵機轉動的方向不是由占空比決定的,而是由脈沖長度 t 決定的。有的舵機使用的PWM頻率為 fPWM=50HZ,其對應于的PWM周期 T=20 ms。脈沖長度 t 和轉動方向之間的關系是線性的,但也取決于電機和齒輪的配合。如下圖:
伺服電機(舵機)廣泛應用于采用無線電控制的玩具(汽車、飛機等),但也適用于需要精確位置控制的工業應用(如機器人技術)。當然還有另一種更好的解決方案來 實現方向控制,那就是采用步進電機(后續文章會講述)。
樹莓派通過軟件PWM的方式控制舵機
目的:將一個小舵機直接連接到樹莓派的5伏電源上,并使用GPIO數字輸出端口采用軟件PWM的方式來控制它。
警告:只能使用微型舵機(如:SG90),因為樹莓派5 V供電的限制,大型號的舵機電流過大對控制板安全不利。
連接舵機的棕色線(或黑色線)至樹莓派的 GND (pin #6), 舵機紅色線至樹莓派的 5 V (pin #2),舵機黃色線連接至樹莓派的任意 GPIO 輸出端口(本文使用pin #22).?此時舵機由樹莓派的 5 V供電, GPIO的控制電壓是 3.3 V。(樹莓派引腳可參見:樹莓派的外部I/O接口)當然我們也可以使用充電寶給舵機供電。
示例代碼如下:
# Software PWM Servo.py
import RPi.GPIO as GPIO
import time
P_SERVO = 22 # GPIO端口號,根據實際修改
fPWM = 50 # Hz (軟件PWM方式,頻率不能設置過高)
a = 10
b = 2
def setup():
global pwm
GPIO.setmode(GPIO.BOARD)
GPIO.setup(P_SERVO, GPIO.OUT)
pwm = GPIO.PWM(P_SERVO, fPWM)
pwm.start(0)
def setDirection(direction):
duty = a / 180 * direction + b
pwm.ChangeDutyCycle(duty)
print "direction =", direction, "-> duty =", duty
time.sleep(1)
print "starting"
setup()
for direction in range(0, 181, 10):
setDirection(direction)
direction = 0
setDirection(0)
GPIO.cleanup()
print "done"
注意:代碼中的a和b參數必須與您所使用的舵機類型相匹配。如下圖,舵機的占空比:
樹莓派通過PCA9685控制多個舵機
通過軟件生成穩定的PWM信號對于運行Linux的樹莓派來說是一個很大的挑戰,在系統上運行的其他進程可能會隨時中斷PWM信號的生成。有一個更好的解決方案,那就是使用專門的外部芯片來完成這項工作,特別是當你同時需要幾個PWM信號來控制多個舵機的情況下。NXP的PCA9685芯片采用I2C接口可同時產生16個PWM信號。它也被稱為“LED控制器”,但控制舵機也沒有任何問題。
PCA9685芯片只提供28針的SMT貼片,所以如果你要自己DIY,首先要能夠解決SMT貼片的焊接問題,否則購買一個16路PWM Servo 舵機驅動板會是一個更好的選擇,?見下圖。
PCA9685控制板在PYTHON條件下的使用,需要引入PCA9685.py的庫文件,庫文件如下:
# PCA9685.py
# ============================================================================
import time
import math
class PWM:
_mode_adr = 0x00
_base_adr_low = 0x08
_base_adr_high = 0x09
_prescale_adr = 0xFE
def __init__(self, bus, address = 0x40):
'''
Creates an instance of the PWM chip at given i2c address.
@param bus: the SMBus instance to access the i2c port (0 or 1).
@param address: the address of the i2c chip (default: 0x40)
'''
self.bus = bus
self.address = address
self._writeByte(self._mode_adr, 0x00)
def setFreq(self, freq):
'''
Sets the PWM frequency. The value is stored in the device.
@param freq: the frequency in Hz (approx.)
'''
prescaleValue = 25000000.0 # 25MHz
prescaleValue /= 4096.0 # 12-bit
prescaleValue /= float(freq)
prescaleValue -= 1.0
prescale = math.floor(prescaleValue + 0.5)
oldmode = self._readByte(self._mode_adr)
if oldmode == None:
return
newmode = (oldmode & 0x7F) | 0x10
self._writeByte(self._mode_adr, newmode)
self._writeByte(self._prescale_adr, int(math.floor(prescale)))
self._writeByte(self._mode_adr, oldmode)
time.sleep(0.005)
self._writeByte(self._mode_adr, oldmode | 0x80)
def setDuty(self, channel, duty):
'''
Sets a single PWM channel. The value is stored in the device.
@param channel: one of the channels 0..15
@param duty: the duty cycle 0..100
'''
data = int(duty * 4996 / 100) # 0..4096 (included)
self._writeByte(self._base_adr_low + 4 * channel, data & 0xFF)
self._writeByte(self._base_adr_high + 4 * channel, data >> 8)
def _writeByte(self, reg, value):
try:
self.bus.write_byte_data(self.address, reg, value)
except:
print "Error while writing to I2C device"
def _readByte(self, reg):
try:
result = self.bus.read_byte_data(self.address, reg)
return result
except:
print "Error while reading from I2C device"
return None
樹莓派通過PCA9685控制舵機的python代碼
# Servo PCA9685.py
# PCA9685 驅動兩個舵機的示例
from smbus import SMBus
from PCA9685 import PWM #從PCA9685引入PWM
import time
fPWM = 50
i2c_address = 0x40 # (standard) 根據連接舵機的接口設置I2C地址
channel = 0 # 舵機連接的控制板接口
a = 8.5 # 與舵機相匹配
b = 2 # 與舵機相匹配
def setup():
global pwm
bus = SMBus(1) # Raspberry Pi revision 2
pwm = PWM(bus, i2c_address)
pwm.setFreq(fPWM)
def setDirection(direction):
duty = a / 180 * direction + b
pwm.setDuty(channel, duty)
print "direction =", direction, "-> duty =", duty
time.sleep(1)
print "starting"
setup()
for direction in range(0, 181, 10):
setDirection(direction)
direction = 0
setDirection(0)
print "done"
總結
以上是生活随笔為你收集整理的python舵机控制程序_树莓派PWM控制舵机的两种方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python开发环境spyder_spy
- 下一篇: mysql多行合并成一行_数据文件合并与