更新PE-G1库,同时支持MBD电机驱动库
This commit is contained in:
@@ -1,30 +1,31 @@
|
|||||||
"""
|
"""
|
||||||
PE_G1
|
Micropython library for
|
||||||
|
PE_G1 (Motor*5*2 & Servo*4)
|
||||||
Micropython library for the PE_G1(Motor*5*2 & Servo*4)
|
MDB (Motor*4*2 & Servo*6)
|
||||||
=======================================================
|
===============================
|
||||||
|
|
||||||
#Preliminary composition 20230120
|
|
||||||
|
|
||||||
@dahanzimin From the Mixly Team
|
@dahanzimin From the Mixly Team
|
||||||
"""
|
"""
|
||||||
from time import sleep_ms
|
from time import sleep_ms
|
||||||
from micropython import const
|
from micropython import const
|
||||||
|
|
||||||
_PE_G1_ADDRESS = const(0x25)
|
_PE_GX_ADDRESS = const(0x25)
|
||||||
_PE_G1_ID = const(0x00)
|
_PE_GX_ID = const(0x00)
|
||||||
_PE_G1_VBAT = const(0x01)
|
_PE_GX_VBAT = const(0x01)
|
||||||
_PE_G1_MOTOR = const(0x03)
|
_PE_GX_MOTOR = const(0x03)
|
||||||
_PE_G1_SERVO = const(0x0D)
|
|
||||||
_PE_G1_OFF = const(0x16)
|
|
||||||
|
|
||||||
class PE_G1:
|
class PE_G1:
|
||||||
def __init__(self, i2c_bus, addr=_PE_G1_ADDRESS):
|
def __init__(self, i2c_bus, addr=_PE_GX_ADDRESS):
|
||||||
self._i2c = i2c_bus
|
self._i2c = i2c_bus
|
||||||
self._addr = addr
|
self._addr = addr
|
||||||
sleep_ms(500)
|
sleep_ms(500)
|
||||||
if self._rreg(_PE_G1_ID)!= 0x25:
|
if self._rreg(_PE_GX_ID) == 0x25:
|
||||||
raise AttributeError("Cannot find a PE_G1")
|
self._PE_GX_SERVO = 0x0D
|
||||||
|
self._type = 1 #PE_G1
|
||||||
|
elif self._rreg(_PE_GX_ID) == 0x26:
|
||||||
|
self._PE_GX_SERVO = 0x0B
|
||||||
|
self._type = 2 #MDB
|
||||||
|
else:
|
||||||
|
raise AttributeError("Cannot find a PE_G1 or MDB")
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def _wreg(self, reg, val):
|
def _wreg(self, reg, val):
|
||||||
@@ -38,44 +39,57 @@ class PE_G1:
|
|||||||
'''Read memory address'''
|
'''Read memory address'''
|
||||||
try:
|
try:
|
||||||
self._i2c.writeto(self._addr, reg.to_bytes(1, 'little'))
|
self._i2c.writeto(self._addr, reg.to_bytes(1, 'little'))
|
||||||
return self._i2c.readfrom(self._addr, nbytes)[0] if nbytes<=1 else self._i2c.readfrom(self._addr, nbytes)[0:nbytes]
|
return self._i2c.readfrom(self._addr, nbytes)[0] if nbytes <= 1 else self._i2c.readfrom(self._addr, nbytes)
|
||||||
except:
|
except:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset all registers to default state"""
|
"""Reset all registers to default state"""
|
||||||
for reg in range(_PE_G1_MOTOR,_PE_G1_MOTOR+18):
|
if self._type == 1:
|
||||||
self._wreg(reg,0x00)
|
self._i2c.writeto_mem(self._addr, _PE_GX_MOTOR, bytes(18))
|
||||||
|
if self._type == 2:
|
||||||
|
self._i2c.writeto_mem(self._addr, _PE_GX_MOTOR, bytes(20))
|
||||||
|
|
||||||
def read_bat(self,ratio=0.0097):
|
def read_bat(self, ratio=1):
|
||||||
'''Read battery power'''
|
'''Read battery power'''
|
||||||
vbat= self._rreg(_PE_G1_VBAT)<<2 | self._rreg(_PE_G1_VBAT+1)>>6
|
vbat = self._rreg(_PE_GX_VBAT) << 2 | self._rreg(_PE_GX_VBAT+1) >> 6
|
||||||
return round(vbat*ratio,2)
|
if self._type == 1:
|
||||||
|
return round(vbat * ratio * 0.00968, 2)
|
||||||
|
if self._type == 2:
|
||||||
|
return round(vbat * ratio * 0.01398, 2)
|
||||||
|
|
||||||
def m_pwm(self, index, duty=None):
|
def m_pwm(self, index, duty=None):
|
||||||
"""Motor*5*2 PWM duty cycle data register"""
|
"""Motor PWM duty cycle data register"""
|
||||||
|
if self._type == 1: # Motor*5*2
|
||||||
if not 0 <= index <= 9:
|
if not 0 <= index <= 9:
|
||||||
raise ValueError("Motor port must be a number in the range: 0~9")
|
raise ValueError("Motor port must be a number in the range: 0~4")
|
||||||
|
if self._type == 2: # Motor*4*2
|
||||||
|
if not 0 <= index <= 7:
|
||||||
|
raise ValueError("Motor port must be a number in the range: 0~3")
|
||||||
if duty is None:
|
if duty is None:
|
||||||
return self._rreg(_PE_G1_MOTOR+index)
|
return self._rreg(_PE_GX_MOTOR + index)
|
||||||
else:
|
else:
|
||||||
if not 0 <= duty <= 255:
|
if not 0 <= duty <= 255:
|
||||||
raise ValueError("Duty must be a number in the range: 0~255")
|
raise ValueError("Duty must be a number in the range: 0~255")
|
||||||
self._wreg(_PE_G1_MOTOR+index,duty)
|
self._wreg(_PE_GX_MOTOR + index, duty)
|
||||||
|
|
||||||
def s_pwm(self, index, duty=None):
|
def s_pwm(self, index, duty=None):
|
||||||
"""Servo*4 PWM duty cycle data register"""
|
"""Servo PWM duty cycle data register"""
|
||||||
|
if self._type == 1: # Servo*4
|
||||||
if not 0 <= index <= 3:
|
if not 0 <= index <= 3:
|
||||||
raise ValueError("Servo port must be a number in the range: 0~3")
|
raise ValueError("Servo port must be a number in the range: 0~3")
|
||||||
|
if self._type == 2: # Servo*6
|
||||||
|
if not 0 <= index <= 5:
|
||||||
|
raise ValueError("Servo port must be a number in the range: 0~5")
|
||||||
if duty is None:
|
if duty is None:
|
||||||
return self._rreg(_PE_G1_SERVO+index*2)<<8 | self._rreg(_PE_G1_SERVO+index*2+1)
|
return self._rreg(self._PE_GX_SERVO + index * 2) << 8 | self._rreg(self._PE_GX_SERVO + index * 2 + 1)
|
||||||
else:
|
else:
|
||||||
if not 0 <= duty <= 4095:
|
if not 0 <= duty <= 4095:
|
||||||
raise ValueError("Duty must be a number in the range: 0~4095")
|
raise ValueError("Duty must be a number in the range: 0~4095")
|
||||||
self._wreg(_PE_G1_SERVO+index*2,duty>>8)
|
self._wreg(self._PE_GX_SERVO + index * 2,duty >> 8)
|
||||||
self._wreg(_PE_G1_SERVO+index*2+1,duty&0xff)
|
self._wreg(self._PE_GX_SERVO + index * 2 + 1,duty & 0xff)
|
||||||
|
|
||||||
def motor(self,index,action,speed=0):
|
def motor(self, index, action="NC", speed=0):
|
||||||
if not 0 <= speed <= 100:
|
if not 0 <= speed <= 100:
|
||||||
raise ValueError("Speed parameters must be a number in the range: 0~100")
|
raise ValueError("Speed parameters must be a number in the range: 0~100")
|
||||||
if action == "N":
|
if action == "N":
|
||||||
|
|||||||
Reference in New Issue
Block a user