PCA9685采用数字方式驱动步进电机,不是采用PWM方式驱动。(采用此扩展板驱动,将增加16个模拟/数字输出引脚)。程序用mu调试通过
Code: Select all
from microbit import *
import math
class PCA9685:
def __init__(self, freq, init):
self.I2C = i2c
self.I2C.init(freq=100000, sda=pin20, scl=pin19)
if not init:
self.i2cW(0x00, 0x00)
self.freq(freq)
def i2cW(self, reg, value):
buf = bytearray(2)
buf[0] = reg
buf[1] = value
self.I2C.write(0x40, buf)
def i2cR(self, reg):
buf = bytearray(1)
buf[0] = reg
self.I2C.write(0x40, buf)
return self.I2C.read(0x40, 1)
def freq(self, freq):
pre = math.floor(((25000000/4096/(freq))-1) + 0.5)
oldmode = self.i2cR(0x00)
self.i2cW(0x00, (oldmode[0] & 0x7F) | 0x10)
self.i2cW(0xFE, pre)
self.i2cW(0x00, oldmode[0])
sleep(5)
self.i2cW(0x00, oldmode[0] | 0xa1)
# 16个输出脚作模拟使用(channel 0-15)
def pwm(self, channel, on, off):
if ((channel < 0) or (channel > 15)):
return
buf = bytearray(5)
buf[0] = 0x06 + 4 * channel
buf[1] = on & 0xff
buf[2] = (on >> 8) & 0xff
buf[3] = off & 0xff
buf[4] = (off >> 8) & 0xff
self.I2C.write(0x40,buf)
# 16个输出脚作数字使用(channel 0-15)
def write_digital(self, channel, value):
if value == 1: # OFF优先
self.i2cW((0x06 + channel * 4 + 3), 0x00)
self.i2cW((0x06 + channel * 4 + 1), 0xFF)
else:
self.i2cW((0x06 + channel * 4 + 3), 0xFF)
# 转一圈需要509步多一点
FULL_ROTATION = 509
# 半步励磁
HALF_STEP = [
[0, 0, 0, 1],
[0, 0, 1, 1],
[0, 0, 1, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[1, 1, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 1],
]
# 全步励磁
FULL_STEP = [
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 0]
]
class MultiStepper():
def __init__(self):
self.pca = PCA9685(1500, 0)
self.servoList = [[7, 6, 5, 4],[3, 2, 1, 0]]
# servoIndexList--电机索引列表,第一个添加的电机索引为0
# directionList --电机转动方向列表 1表示逆时候,-1表示顺时针
def doAction(self, servoIndexList, directionList, stepCount, mode=FULL_STEP, delay=3):
for x in range(stepCount):
for y in range(len(mode)):
for z in range(len(servoIndexList)):
pinList = self.servoList[servoIndexList[z]]
bit = mode[::directionList[z]][y]
self.pca.write_digital(pinList[0], bit[0])
self.pca.write_digital(pinList[1], bit[1])
self.pca.write_digital(pinList[2], bit[2])
self.pca.write_digital(pinList[3], bit[3])
sleep(delay)
for i in range(len(servoIndexList)):
pinList = self.servoList[servoIndexList[i]]
self.pca.write_digital(pinList[0], 0)
self.pca.write_digital(pinList[1], 0)
self.pca.write_digital(pinList[2], 0)
self.pca.write_digital(pinList[3], 0)
if __name__ == '__main__':
s = MultiStepper()
# 第一个电机顺时针走255步,全步励磁
s.doAction([0],[-1],255, FULL_STEP,3)
# 第一个电机逆时针和第二个电机顺时针各转一圈,全步励磁
s.doAction([0, 1], [1, -1], FULL_ROTATION, FULL_STEP, 0)
# 第二个电机逆时针走255步,全步励磁
s.doAction([1],[1],255, FULL_STEP,3)[/i]