树莓派:16路舵机扩展板

一、安装 Adafruit-PCA9685

sudo pip install adafruit-pca9685

二、引入包

import Adafruit_PCA9685	

三、内部方法

class PCA9685(object):
    """PCA9685 PWM LED/servo controller."""

    def __init__(self, address=PCA9685_ADDRESS, i2c=None, **kwargs):
        """Initialize the PCA9685."""
        # Setup I2C interface for the device.
        if i2c is None:
            import Adafruit_GPIO.I2C as I2C
            i2c = I2C
        self._device = i2c.get_i2c_device(address, **kwargs)
        self.set_all_pwm(0, 0)
        self._device.write8(MODE2, OUTDRV)
        self._device.write8(MODE1, ALLCALL)
        time.sleep(0.005)  # wait for oscillator
        mode1 = self._device.readU8(MODE1)
        mode1 = mode1 & ~SLEEP  # wake up (reset sleep)
        self._device.write8(MODE1, mode1)
        time.sleep(0.005)  # wait for oscillator

    def set_pwm_freq(self, freq_hz):
        """Set the PWM frequency to the provided value in hertz."""
        prescaleval = 25000000.0    # 25MHz
        prescaleval /= 4096.0       # 12-bit
        prescaleval /= float(freq_hz)
        prescaleval -= 1.0
        logger.debug('Setting PWM frequency to {0} Hz'.format(freq_hz))
        logger.debug('Estimated pre-scale: {0}'.format(prescaleval))
        prescale = int(math.floor(prescaleval + 0.5))
        logger.debug('Final pre-scale: {0}'.format(prescale))
        oldmode = self._device.readU8(MODE1);
        newmode = (oldmode & 0x7F) | 0x10    # sleep
        self._device.write8(MODE1, newmode)  # go to sleep
        self._device.write8(PRESCALE, prescale)
        self._device.write8(MODE1, oldmode)
        time.sleep(0.005)
        self._device.write8(MODE1, oldmode | 0x80)

    def set_pwm(self, channel, on, off):
        """Sets a single PWM channel."""
        self._device.write8(LED0_ON_L+4*channel, on & 0xFF)
        self._device.write8(LED0_ON_H+4*channel, on >> 8)
        self._device.write8(LED0_OFF_L+4*channel, off & 0xFF)
        self._device.write8(LED0_OFF_H+4*channel, off >> 8)

    def set_all_pwm(self, on, off):
        """Sets all PWM channels."""
        self._device.write8(ALL_LED_ON_L, on & 0xFF)
        self._device.write8(ALL_LED_ON_H, on >> 8)
        self._device.write8(ALL_LED_OFF_L, off & 0xFF)
        self._device.write8(ALL_LED_OFF_H, off >> 8)

各个通道的ON和OFF寄存器

总共16个通道,每个通道都有 LEDX_ON_L、LEDX_ON_H、LEDX_OFF_L、LEDX_OFF_H 四个寄存器。
系统中有一个12位的计数ACK,ACK根据PRE_SCALE寄存器设置的周期进行增加,没增加一次就会和上述四个寄存器对比:
当发现 ACK == LEDX_ON_H[3:0]:LEDX_ON_L 时,X通道输出高电平;
当发现 ACK == LEDX_OFF_H[3:0]:LEDX_OFF_L 时,X通道输出低电平。

set_pwm要注意on和 off的赋值

on寄存器为0,off寄存器存入数值

on寄存器存入数值,off寄存器为0

三、用法

3.1 创建一个PWM实例

pwm = Adafruit_PCA9685.PCA9685()
# 地址默认为这个 address=PCA9685_ADDRESS
# 如果修改了模块上的地址,则需要修改。

3.2 设置频率

pwm.set_pwm_freq(50)

3.3 更改占空比

# 单独通道修改
pwm.set_pwm(channel,on,off)

# 一次性修改
set_all_pwm(self, on, off):

3.4 实列

import Adafruit_PCA9685
import time

pwm = Adafruit_PCA9685.PCA9685()


def set_servo_angle(channel, angle):              #输入角度转换成12^精度的数值
    date=4096*((angle*11)+500)/20000              #进行四舍五入运算 date=int(4096*((angle*11)+500)/(20000)+0.5)
    pwm.set_pwm(channel, 0,int(date))

pwm.set_pwm_freq(50)


print('Moving servo on channel x, press Ctrl-C to quit...')
while True:
    # Move servo on channel O between extremes.
    channel=int(input('pleas input channel:'))
    angle=int(input('pleas input angle:'))
    set_servo_angle(0, angle)


    #time.sleep(1)

四、PCA9685 模块的一些小细节

4.1   7位的I2C地址为:0x40 + A5:A0,A5到A0如果不做任何处理的话是0,想要把哪一位置1就把那个引脚焊到一起。生成实列的时候需要修改默认值。另外用i2cdetect检测出还有一个0x70地址一直存在,这是一个通用地址,可以给所有从机下达指令。

4.2   模块有一个OE反使能脚,这个引脚低电平使能,不接的话模块内部默认已经接地使能了,所以正常使用可以不接。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值