制作坊python教程--PCA9685PW驱动电机 专区
python教程--PCA9685PW驱动电机

PCA9685PW 是一款 I2C 总线接口的 16 位 LED 控制器,每个 LED 都可以输出 12 位分辨率(4096
级)固定频率的独立 PWM 控制器,通过输出PWM驱动电机动作。
PCA9685PW 连接 micro:bit 的 P19 和 P20 引脚进行I2C 通讯,建立通讯以后就可以控制16路引脚输出PWM了。
以集成了PCA9685PW 的microo:bit高级版扩展板为例,首先是原理图
从原理图中得知使机器人前进只需要使得 LINA(12)输出高电平,LINB(13)输出低电平,RINA(14)输出高电平,RINB(15)输出低电平就可以了。
接下来开始编程,可以选择在线版和离线版,我个人比较习惯使用离线版mu进行编程,注意!
1.所有的英文与符号都应该在英文状态下输入,关键词如“,”与后面的内容之间需要有个空格,使用Tab键(制表键)进行缩进,最后一行以空白程序结尾。
2.如下图所示,点击大拇指图标的Check(检查)键检查一下我们的代码是否有错误。如果某一行出现光标或下划线,表示某一行的程序出错,如果没有出现光标或下划线,则表示代码没有错误。
3.将micro USB数据线连接micro:bit与电脑,接着如下图所示点击Flash(刷入)按键下载程序至micro:bit
4. 下载成功后,可以观察到电机被驱动了,如视频所示。
程序源码:
from microbit import *
import ustruct
import math
# Registers/etc:
PCA9685_ADDRESS = 0x41
MODE1 = 0x00
MODE2 = 0x01
SUBADR1 = 0x02
SUBADR2 = 0x03
SUBADR3 = 0x04
PRESCALE = 0xFE
LED0_ON_L = 0x06
LED0_ON_H = 0x07
LED0_OFF_L = 0x08
LED0_OFF_H = 0x09
ALL_LED_ON_L = 0xFA
ALL_LED_ON_H = 0xFB
ALL_LED_OFF_L = 0xFC
ALL_LED_OFF_H = 0xFD
# Bits:
RESTART = 0x80
SLEEP = 0x10
ALLCALL = 0x01
INVRT = 0x10
OUTDRV = 0x04
RESET = 0x00
class PCA9685():
def __init__(self, address=PCA9685_ADDRESS):
self.address = address
i2c.write(self.address, bytearray([MODE1, RESET]))
self.set_all_pwm(0, 0)
i2c.write(self.address, bytearray([MODE2, OUTDRV]))
i2c.write(self.address, bytearray([MODE1, ALLCALL]))
sleep(5) # wait for oscillator
i2c.write(self.address, bytearray([MODE1]))
mode1 = i2c.read(self.address, 1)
mode1 = ustruct.unpack(' mode1 = mode1 & ~SLEEP # wake up (reset sleep) i2c.write(self.address, bytearray([MODE1, mode1])) sleep(5) # wait for oscillator def set_pwm_freq(self, freq_hz): prescaleval = 25000000.0 # 25MHz prescaleval /= 4096.0 # 12-bit prescaleval /= float(freq_hz) prescaleval -= 1.0 # print('Setting PWM frequency to {0} Hz'.format(freq_hz)) # print('Estimated pre-scale: {0}'.format(prescaleval)) prescale = int(math.floor(prescaleval + 0.5)) # print('Final pre-scale: {0}'.format(prescale)) i2c.write(self.address, bytearray([MODE1])) oldmode = i2c.read(self.address, 1) oldmode = ustruct.unpack(' newmode = (oldmode & 0x7F) | 0x10 # sleep i2c.write(self.address, bytearray([MODE1, newmode])) # go to sleep i2c.write(self.address, bytearray([PRESCALE, prescale])) i2c.write(self.address, bytearray([MODE1, oldmode])) sleep(5) i2c.write(self.address, bytearray([MODE1, oldmode | 0x80])) def set_pwm(self, channel, on, off): if on is None or off is None: i2c.write(self.address, bytearray([LED0_ON_L+4*channel])) data = i2c.read(self.address, 4) return ustruct.unpack('> 8])) i2c.write(self.address, bytearray([LED0_OFF_L+4*channel, off & 0xFF])) i2c.write(self.address, bytearray([LED0_OFF_H+4*channel, off >> 8])) def set_all_pwm(self, on, off): i2c.write(self.address, bytearray([ALL_LED_ON_L, on & 0xFF])) i2c.write(self.address, bytearray([ALL_LED_ON_H, on >> 8])) i2c.write(self.address, bytearray([ALL_LED_OFF_L, off & 0xFF])) i2c.write(self.address, bytearray([ALL_LED_OFF_H, off >> 8])) def duty(self, index, value=None, invert=False): if value is None: pwm = self.set_pwm(index) if pwm == (0, 4096): value = 0 elif pwm == (4096, 0): value = 4095 value = pwm[1] if invert: value = 4095 - value return value if not 0 <= value <= 4095: raise ValueError("Out of range") if invert: value = 4095 - value if value == 0: self.set_pwm(index, 0, 4096) elif value == 4095: self.set_pwm(index, 4096, 0) else: self.set_pwm(index, 0, value) # Initialise the PCA9685 using the default address (0x41). pwm = PCA9685() # Configure min and max servo pulse lengths servo_min = 150 # Min pulse length out of 4096 0? servo_max = 600 # Max pulse length out of 4096: 180? # Set frequency to 60hz, good for servos. pwm.set_pwm_freq(60) pwm.set_pwm(12, 0, 4095) pwm.set_pwm(13, 0, 0) pwm.set_pwm(15, 0, 4095) pwm.set_pwm(14, 0, 0) pwm.set_pwm(3, 0, servo_min) sleep(1000) pwm.set_pwm(3, 0, servo_max) sleep(1000)

用superbit扩展板,使用这个程序,下载到microbit以后,提示i2c write error是怎么回事?
传到microbit板子上是出错的,怎么回事?没有添加pwm = PCA9685()后面的,就没有出错