La classe utilisée par la carte Kiktronik (celle qui fonctionne bien) est complexe (pour moi) et en tout cas beaucoup plus que l'autre dont la fonction est très simple.
Voici celle de la carte kiktronik:
import machine
import utime
class KitronikPicoRobotics:
#Class variables - these should be the same for all instances of the class.
# If you wanted to write some code that stepped through
# the servos or motors then this is the Base and size to do that
SRV_REG_BASE = 0x08
MOT_REG_BASE = 0x28
REG_OFFSET = 4
PRESCALE_VAL = b'\x79'
#setup the PCA chip for 50Hz and zero out registers.
def initPCA(self):
# Make sure we are in a known position
# Soft reset of the I2C chip
self.i2c.writeto(0,"\x06")
# setup the prescale to have 20mS pulse repetition - this is dictated by the servos.
# set PWM Frequency Pre Scale. The prescale value is determined with the formunla:
# presscale value = round(osc clock / (4096 * update rate))
# Where update rate is the output modulation frequency required.
# For example, the output frequency of 50Hz (20ms) for the servo, with the internal oscillator
# clock frequency of 25 Mhz is as follows:
# prescale value = round( 25MHZ / (4096 * 50Hz) ) - 1
# prescale value = round (25000000 / (4096 * 50)) - 1
# presscale value = 121 = 79h = 0x79
self.i2c.writeto_mem(108,0xfe,self.PRESCALE_VAL)
#block write outputs to off
self.i2c.writeto_mem(108,0xfa,"\x00")
self.i2c.writeto_mem(108,0xfb,"\x00")
self.i2c.writeto_mem(108,0xfc,"\x00")
self.i2c.writeto_mem(108,0xfd,"\x00")
# come out of sleep
self.i2c.writeto_mem(108,0x00,"\x01")
# It takes 500uS max for the oscillator to be up and running once the SLEEP bit (bit 4) has
# been set to logic 0. Timings on outputs are not guranteed if the PWM control registers are
# accessed within the 500uS window.
utime.sleep_us(500)
# Adjusts the servos.
# This block should be used if the connected servo does not respond correctly to the 'servoWrite' command.
# Try changing the value by small amounts and testing the servo until it correctly sets to the angle.
def adjustServos(self, change):
if change < -25:
change = -25
if change > 25:
change = 25
self.PRESCALE_VAL = (121 + change).to_bytes(1,"big")
self.initPCA()
# To get the PWM pulses to the correct size and zero
# offset these are the default numbers.
#Servo multiplier is calcualted as follows:
# 4096 pulses ->20mS 1mS-> count of 204.8
# 1mS is 90 degrees of travel, so each degree is a count of 204.8/90->2.2755
# servo pulses always have aminimum value - so there is guarentees to be a pulse.
# in the servos Ive examined this is 0.5ms or a count of 102
#to clauclate the count for the corect pulse is simply:
# (degrees x count per degree )+ offset
def servoWrite(self,servo, degrees):
#check the degrees is a reasonable number. we expect 0-180, so cap at those values.
if(degrees>180):
degrees = 180
elif (degrees<0):
degrees = 0
#check the servo number
if((servo<1) or (servo>8)):
raise Exception("INVALID SERVO NUMBER") #harsh, but at least you'll know
calcServo = self.SRV_REG_BASE + ((servo - 1) * self.REG_OFFSET)
PWMVal = int((degrees*2.2755)+102) # see comment above for maths
lowByte = PWMVal & 0xFF
highByte = (PWMVal>>8)&0x01 #cap high byte at 1 - shoud never be more than 2.5mS.
self.i2c.writeto_mem(self.CHIP_ADDRESS, calcServo,bytes([lowByte]))
self.i2c.writeto_mem(self.CHIP_ADDRESS, calcServo+1,bytes([highByte]))