kopia lustrzana https://github.com/GuyCarver/MicroPython
pca9865.py now a library.
rodzic
2e2fde9d7c
commit
86d4ce9f7b
|
@ -1,14 +1,17 @@
|
||||||
# MicroPython PCA9865 16 servo controller driver.
|
# MicroPython PCA9865 16 servo controller driver.
|
||||||
|
#NOTE: I tried writing 16 bit values for PWM but it crashed the controller requiring a power cycle to reset.
|
||||||
|
|
||||||
import pyb
|
import pyb
|
||||||
from time import sleep_us
|
from time import sleep_us
|
||||||
|
|
||||||
class pca9865(object):
|
class pca9865(object):
|
||||||
|
"""16 servo contoller. Use index 0-15 for the servo #."""
|
||||||
|
|
||||||
_ADDRESS = 0x40
|
_ADDRESS = 0x40
|
||||||
_MODE1 = const(0)
|
_MODE1 = const(0)
|
||||||
_PRESCALE = const(0xFE)
|
_PRESCALE = const(0xFE)
|
||||||
_LED0_ON_L = const(0x6)
|
|
||||||
|
_LED0_ON_L = const(0x6) #We only use LED0 and offset 0-16 from it.
|
||||||
# _LED0_ON_H = const(0x7)
|
# _LED0_ON_H = const(0x7)
|
||||||
# _LED0_OFF_L = const(0x8)
|
# _LED0_OFF_L = const(0x8)
|
||||||
# _LED0_OFF_H = const(0x9)
|
# _LED0_OFF_H = const(0x9)
|
||||||
|
@ -24,7 +27,7 @@ class pca9865(object):
|
||||||
_PULSERANGE = const(450)
|
_PULSERANGE = const(450)
|
||||||
|
|
||||||
def __init__(self, aLoc) :
|
def __init__(self, aLoc) :
|
||||||
"""aLoc I2C pin location is either 1 for 'X' or 2 for 'Y'."""
|
"""aLoc I2C pin location is either 1, 'X', 2 or'Y'."""
|
||||||
super(pca9865, self).__init__()
|
super(pca9865, self).__init__()
|
||||||
self.i2c = pyb.I2C(aLoc, pyb.I2C.MASTER)
|
self.i2c = pyb.I2C(aLoc, pyb.I2C.MASTER)
|
||||||
# print(self.i2c)
|
# print(self.i2c)
|
||||||
|
@ -33,16 +36,20 @@ class pca9865(object):
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def read( self, aLoc ) :
|
def read( self, aLoc ) :
|
||||||
|
"""Read 8 byte value and return in bytearray"""
|
||||||
return self.i2c.mem_read(1, self._ADDRESS, aLoc)
|
return self.i2c.mem_read(1, self._ADDRESS, aLoc)
|
||||||
|
|
||||||
def write( self, aVal, aLoc ) :
|
def write( self, aVal, aLoc ) :
|
||||||
|
"""Write 8 bit value to given address. aVal may be an int buffer."""
|
||||||
self.i2c.mem_write(aVal, self._ADDRESS, aLoc)
|
self.i2c.mem_write(aVal, self._ADDRESS, aLoc)
|
||||||
|
|
||||||
def reset( self ):
|
def reset( self ):
|
||||||
|
"""Reset the controller and set default frequency."""
|
||||||
self.write(0, _MODE1)
|
self.write(0, _MODE1)
|
||||||
self.setfreq(_DEFAULTFREQ)
|
self.setfreq(_DEFAULTFREQ)
|
||||||
|
|
||||||
def setfreq( self, aFreq ) :
|
def setfreq( self, aFreq ) :
|
||||||
|
"""Set frequency for all servos. A good value is 60hz (default)."""
|
||||||
aFreq *= 0.9 #Correct for overshoot in frequency setting.
|
aFreq *= 0.9 #Correct for overshoot in frequency setting.
|
||||||
prescalefloat = (6103.51562 / aFreq) - 1 #25000000 / 4096 / freq.
|
prescalefloat = (6103.51562 / aFreq) - 1 #25000000 / 4096 / freq.
|
||||||
prescale = int(prescalefloat + 0.5)
|
prescale = int(prescalefloat + 0.5)
|
||||||
|
@ -56,33 +63,28 @@ class pca9865(object):
|
||||||
sleep_us(50)
|
sleep_us(50)
|
||||||
self.write(oldmode | 0xA1, _MODE1) #This sets the MODE1 register to turn on auto increment.
|
self.write(oldmode | 0xA1, _MODE1) #This sets the MODE1 register to turn on auto increment.
|
||||||
|
|
||||||
def setPWM( self, aServo, aOn, aOff ) :
|
def setpwm( self, aServo, aOn, aOff ) :
|
||||||
"""aServo = 0-15.
|
"""aServo = 0-15.
|
||||||
aOn = 16 bit on value.
|
aOn = 16 bit on value.
|
||||||
aOff = 16 bit off value.
|
aOff = 16 bit off value.
|
||||||
"""
|
"""
|
||||||
#Data is on low, on high, off low and off high. That's 4 bytes each servo.
|
if 0 <= aServo <= 15 :
|
||||||
|
#Data = on-low, on-high, off-low and off-high. That's 4 bytes each servo.
|
||||||
loc = _LED0_ON_L + (aServo * 4)
|
loc = _LED0_ON_L + (aServo * 4)
|
||||||
# print(loc)
|
# print(loc)
|
||||||
self._buffer[0] = aOn
|
self._buffer[0] = aOn
|
||||||
self._buffer[1] = aOn >> 8
|
self._buffer[1] = aOn >> 8
|
||||||
self._buffer[2] = aOff
|
self._buffer[2] = aOff
|
||||||
self._buffer[3] = aOff >> 8
|
self._buffer[3] = aOff >> 8
|
||||||
self.write(self._buffer, loc)
|
self.write(self._buffer, loc)
|
||||||
|
else:
|
||||||
|
raise Exception('Servo index {} out of range.'.format(str(aServo)))
|
||||||
|
|
||||||
def setpin( self, aServo, aVal ) :
|
def off( self, aServo ) :
|
||||||
on = 0
|
"""Turn off a servo."""
|
||||||
off = min(aVal, 4095)
|
self.setpwm(aServo, 0, 0)
|
||||||
if off == 4095 :
|
|
||||||
on = 4096
|
|
||||||
off = 0
|
|
||||||
elif aVal == 0 :
|
|
||||||
off = 4096
|
|
||||||
|
|
||||||
self.setPWM(aServo, on, off)
|
|
||||||
|
|
||||||
def setangle( self, aServo, aAng ) :
|
def setangle( self, aServo, aAng ) :
|
||||||
"""Set the angle 0-100%"""
|
"""Set the angle 0-100%"""
|
||||||
val = _MINPULSE + ((_PULSERANGE * aAng) // 100)
|
val = _MINPULSE + ((_PULSERANGE * aAng) // 100)
|
||||||
self.setPWM(aServo, 0, val)
|
self.setpwm(aServo, 0, val)
|
||||||
|
|
Ładowanie…
Reference in New Issue