修复 特殊板子RGB反电平驱动固件向上兼容问题

This commit is contained in:
dahanzimin
2024-10-16 21:28:05 +08:00
parent 39c573c42e
commit 752eb8b804
2 changed files with 528 additions and 528 deletions

View File

@@ -1,354 +1,354 @@
"""
Mixbot-Onboard resources
Micropython library for the Mixbot-Onboard resources
=======================================================
@dahanzimin From the Mixly Team
"""
import time, gc, random, uframebuf
from micropython import const
from machine import Pin, SoftI2C, ADC, PWM, RTC
'''RTC'''
rtc_clock=RTC()
'''2RGB_WS2812'''
from ws2812 import NeoPixel
onboard_rgb = NeoPixel(Pin(12), 2, default=1)
'''1Buzzer-Music'''
from music import MIDI
onboard_music =MIDI(25)
spk_en = Pin(27, Pin.OUT)
spk_en.value(0)
'''i2c-onboard & ext'''
class I2C_device(SoftI2C):
CRC8_Table =b'\x00^\xbc\xe2a?\xdd\x83\xc2\x9c~ \xa3\xfd\x1fA\x9d\xc3!\x7f\xfc\xa2@\x1e_\x01\xe3\xbd>`\x82\xdc#}\x9f\xc1B\x1c\xfe\xa0\xe1\xbf]\x03\x80\xde<b\xbe\xe0\x02\\\xdf\x81c=|"\xc0\x9e\x1dC\xa1\xffF\x18\xfa\xa4\'y\x9b\xc5\x84\xda8f\xe5\xbbY\x07\xdb\x85g9\xba\xe4\x06X\x19G\xa5\xfbx&\xc4\x9ae;\xd9\x87\x04Z\xb8\xe6\xa7\xf9\x1bE\xc6\x98z$\xf8\xa6D\x1a\x99\xc7%{:d\x86\xd8[\x05\xe7\xb9\x8c\xd20n\xed\xb3Q\x0fN\x10\xf2\xac/q\x93\xcd\x11O\xad\xf3p.\xcc\x92\xd3\x8do1\xb2\xec\x0eP\xaf\xf1\x13M\xce\x90r,m3\xd1\x8f\x0cR\xb0\xee2l\x8e\xd0S\r\xef\xb1\xf0\xaeL\x12\x91\xcf-s\xca\x94v(\xab\xf5\x17I\x08V\xb4\xeai7\xd5\x8bW\t\xeb\xb56h\x8a\xd4\x95\xcb)w\xf4\xaaH\x16\xe9\xb7U\x0b\x88\xd64j+u\x97\xc9J\x14\xf6\xa8t*\xc8\x96\x15K\xa9\xf7\xb6\xe8\nT\xd7\x89k5'
def _crc8(self, buf):
_sum = 0
for i in range(0, len(buf)):
_sum = self.CRC8_Table[_sum ^ buf[i]]
return _sum
def read_device(self, addr, cmd, nbytes=1):
buf = self.readfrom_mem(addr, cmd, nbytes+2)
if self._crc8(buf[:-1]) == buf[-1]:
return buf[1] if nbytes<=1 else buf[1:-1]
def write_device(self, addr, cmd, buf=0):
buf = buf.to_bytes(1, 'little') if type(buf) is int else buf
buf = bytearray([cmd, random.randint(0, 255)]) + buf
crc8 = self._crc8(buf).to_bytes(1, 'little')
self.writeto(addr, buf + crc8)
if crc8 == self.readfrom(addr, 1):
return True
onboard_i2c = I2C_device(scl=Pin(18), sda=Pin(23) , freq=400000)
ext_i2c = I2C_device(scl=Pin(22), sda=Pin(21), freq=200000)
'''Version judgment'''
if 0x68 in onboard_i2c.scan():
version=1
else:
version=0
'''Accelerometer+Gyroscope'''
if version:
import icm42670
acc_gyr = icm42670.ICM42670(onboard_i2c)
'''2-Button'''
class Button:
def __init__(self, pin, level=True):
self._pin = Pin(pin, Pin.IN)
self._flag = True
self._level = level
def get_presses(self, delay = 1):
last_time,presses = time.time(), 0
while time.time() < last_time + delay:
time.sleep(0.05)
if self.was_pressed():
presses += 1
return presses
def is_pressed(self):
return self._pin.value() == self._level
def was_pressed(self):
if self._pin.value() != self._flag:
time.sleep(0.01)
self._flag = self._pin.value()
return self._level if self._flag else not self._level
def irq(self, handler, trigger):
self._pin.irq(handler = handler, trigger = trigger)
button_p = Button(34, True)
button_a = Button(35, False)
button_b = Button(39, False)
'''2-LED'''
class LED:
def __init__(self, pin):
self._pin =PWM(Pin(pin), freq=5000, duty_u16=65535)
self.setbrightness(0)
def setbrightness(self,val):
if not 0 <= val <= 100:
raise ValueError("Brightness must be in the range: 0-100%")
self._brightness=val
self._pin.duty_u16(val * 65535 // 100)
def getbrightness(self):
return self._brightness
def setonoff(self,val):
if(val == -1):
self.setbrightness(100) if self._brightness < 50 else self.setbrightness(0)
elif(val == 1):
self.setbrightness(100)
elif(val == 0):
self.setbrightness(0)
def getonoff(self):
return True if self._brightness > 0 else False
def value(self,val=None):
if val is None:
return self.getonoff()
else:
self.setbrightness(100) if val else self.setbrightness(0)
rled = LED(2)
gled = LED(4)
'''3-ADCSensor'''
class ADCSensor:
def __init__(self, pin):
self.adc=ADC(Pin(pin))
self.adc.atten(ADC.ATTN_11DB)
def read(self):
return self.adc.read_u16()
def voltage(self, scale=4.6):
return round(self.adc.read_uv() * scale / 1000000, 2)
def loudness(self):
values = []
for i in range(200):
val = self.adc.read_u16()
values.append(val)
return max(values) - min(values)
adc1 = ADCSensor(33)
adc2 = ADCSensor(32)
battery = ADCSensor(36)
sound = ADCSensor(38)
'''4-FindLine /i2c'''
class FindLine(object):
CORRECTING_WHITE = const(0x01)
CORRECTING_BLACK = const(0x02)
CORRECTING_RESET_TO_FAB = const(0x04)
def __init__(self, i2c_bus, addr=0x01):
self._i2c = i2c_bus
self._addr = addr
self._data = (0,0,0,0)
def getdata(self):
_buf = self._i2c.read_device(self._addr, 0x10, 4)
if _buf:
self._data = tuple(_buf)
return self._data
def correct(self,type):
'''type 0x01 校正白色 0x02 校正黑色 0x04 恢复出厂 '''
if type not in [CORRECTING_WHITE, CORRECTING_BLACK, CORRECTING_RESET_TO_FAB]:
raise ValueError('Invalid parameter')
self._i2c.write_device(self._addr, 0xA0, type)
patrol = FindLine(onboard_i2c)
'''4-LEDmatrix /i2c'''
class Matrix5x5(uframebuf.FrameBuffer_Ascall):
"""Graph module 5x5"""
HEART = b'\n\x1f\x1f\x0e\x04'
HEART_SMALL = b'\x00\n\x0e\x04\x00'
HAPPY = b'\x00\n\x00\x11\x0e'
SAD = b'\x00\n\x00\x0e\x11'
SMILE = b'\x00\x00\x00\x11\x0e'
SILLY = b'\x11\x00\x1f\x14\x1c'
FABULOUS = b'\x1f\x1b\x00\n\x0e'
SURPRISED = b'\n\x00\x04\n\x04'
ASLEEP = b'\x00\x1b\x00\x0e\x00'
ANGRY = b'\x11\n\x00\x1f\x15'
CONFUSED = b'\x00\n\x00\n\x15'
NO = b'\x11\n\x04\n\x11'
YES = b'\x00\x10\x08\x05\x02'
LEFT_ARROW = b'\x04\x02\x1f\x02\x04'
RIGHT_ARROW = b'\x04\x08\x1f\x08\x04'
DRESS = b'\n\x1b\x0e\x0e\x1f'
TRANSFORMERS = b'\x04\x0e\x15\n\x11'
SCISSORS = b'\x13\x0b\x04\x0b\x13'
EXIT = b'\x04\x0e\x15\x0b\x10'
TREE = b'\x04\x0e\x1f\x04\x04'
PACMAN = b'\x1e\x0b\x07\x0f\x1e'
TARGET = b'\x04\x0e\x1b\x0e\x04'
TSHIRT = b'\x1b\x1f\x0e\x0e\x0e'
ROLLERSKATE = b'\x18\x18\x1f\x1f\n'
DUCK = b'\x06\x07\x1e\x0e\x00'
HOUSE = b'\x04\x0e\x1f\x0e\n'
TORTOISE = b'\x00\x0e\x1f\n\x00'
BUTTERFLY = b'\x1b\x1f\x04\x1f\x1b'
STICKFIGURE = b'\x04\x1f\x04\n\x11'
GHOST = b'\x1f\x15\x1f\x1f\x15'
PITCHFORK = b'\x15\x15\x1f\x04\x04'
MUSIC_QUAVERS = b'\x1e\x12\x12\x1b\x1b'
MUSIC_QUAVER = b'\x04\x0c\x14\x07\x07'
MUSIC_CROTCHET = b'\x04\x04\x04\x07\x07'
COW = b'\x11\x11\x1f\x0e\x04'
RABBIT = b'\x05\x05\x0f\x0b\x0f'
SQUARE_SMALL = b'\x00\x0e\n\x0e\x00'
SQUARE = b'\x1f\x11\x11\x11\x1f'
DIAMOND_SMALL = b'\x00\x04\n\x04\x00'
DIAMOND = b'\x04\n\x11\n\x04'
CHESSBOARD = b'\n\x15\n\x15\n'
TRIANGLE_LEFT = b'\x01\x03\x05\t\x1f'
TRIANGLE = b'\x00\x04\n\x1f\x00'
SNAKE = b'\x03\x1b\n\x0e\x00'
UMBRELLA = b'\x0e\x1f\x04\x05\x06'
SKULL = b'\x0e\x15\x1f\x0e\x0e'
GIRAFFE = b'\x03\x02\x02\x0e\n'
SWORD = b'\x04\x04\x04\x0e\x04'
def __init__(self, i2c_bus, addr=0x03, brightness=0.5):
self._i2c = i2c_bus
self._addr = addr
self._brightness= brightness
self._buffer = bytearray(5)
super().__init__(self._buffer, 5, 5, uframebuf.MONO_HMSB)
self.font("5x5")
self.screenbright(self._brightness)
self.clear()
def screenbright(self, brightness=None, background=0):
if brightness is None :
return self._brightness
else:
if not 0.0 <= brightness <= 1.0:
raise ValueError("Brightness must be a decimal number in the range: 0.0-1.0")
self._brightness = brightness
self._i2c.write_device(self._addr, 0xA5, bytes([round(255 * brightness), round(255 * background)]))
def ambientbright(self):
bright = self._i2c.read_device(self._addr, 0x10)
if bright:
return bright
def direction(self,mode = 0):
'''set display direction '''
self._i2c.write_device(self._addr, 0xA7, mode)
def show(self):
'''Refresh the display and show the changes'''
buf = bytearray(4)
buf[0] = (self._buffer[4] & 0xF0) >> 4
buf[1] = (self._buffer[3] & 0x1E) >> 1 | (self._buffer[4] & 0x0F) << 4
buf[2] = (self._buffer[1] & 0x18) >> 3 | (self._buffer[2] & 0x1F) << 2 | (self._buffer[3] & 0x01) << 7
buf[3] = (self._buffer[0] & 0x1F) | (self._buffer[1] & 0x07) << 5
self._i2c.write_device(self._addr, 0xA1, buf)
def clear(self):
''' clear display'''
self._i2c.write_device(self._addr, 0xA6)
onboard_matrix = Matrix5x5(onboard_i2c)
'''2 Motor /i2c'''
class Motor(object):
STOP_MODE = const(0x00)
BRAKE_MODE = const(0x01)
PWR_MODE = const(0x02)
SPEED_MODE = const(0x03)
TURNS_MODE = const(0x04)
def __init__(self, i2c_bus, addr=0x02, scale=90 * 4):
self._i2c = i2c_bus
self._addr = addr
self._scale = scale
self._signala = PWM(Pin(13), freq=500, duty_u16=49150)
self._signalb = PWM(Pin(14), freq=500, duty_u16=49150)
self._status = ((0,0,0,0), (0,0,0,0))
self._motor = ([0,0], [0,0])
def _u2s(self, value, n=8):
return value if value < (1 << (n-1)) else value - (1 << n)
def status(self):
_buf = self._i2c.read_device(self._addr, 0x10, 9)
if _buf:
self._status = ((_buf[0] >> 4, -self._u2s(_buf[1]), -self._u2s(_buf[3]), abs(self._u2s(_buf[6] << 8 | _buf[5], 16))),
(_buf[0] & 0x0F, self._u2s(_buf[2]), self._u2s(_buf[4]), abs(self._u2s(_buf[8] << 8 | _buf[7], 16))))
return self._status
def run(self, idx, mode, value):
if idx == 1 or idx == 2:
self._motor[idx-1][0], self._motor[idx-1][1] = mode, value
else:
self._motor = ([mode, value], [mode, value])
buf = bytearray(5)
m1_pwr_speed, m2_pwr_speed = 0, 0
buf[0] = (self._motor[0][0] << 4) | self._motor[1][0]
if self._motor[0][0] == self.TURNS_MODE:
_turns = round(self._motor[0][1] * self._scale)
buf[1] = (- _turns) & 0xFF
buf[2] = ((- _turns) >> 8) & 0xFF
else:
m1_pwr_speed = - max(min(self._motor[0][1], 100), -100)
if self._motor[1][0] == self.TURNS_MODE:
_turns = round(self._motor[1][1] * self._scale)
buf[3] = _turns & 0xFF
buf[4] = (_turns >> 8) & 0xFF
else:
m2_pwr_speed = max(min(self._motor[1][1], 100), -100)
self._i2c.write_device(self._addr, 0xA0, buf)
self._signala.duty_u16(33422 + 31457 * (m1_pwr_speed + 100) // 200)
self._signalb.duty_u16(33422 + 31457 * (m2_pwr_speed + 100) // 200)
def move(self, action, mode, value=100):
if action=="N":
self.run(0, self.STOP_MODE, 0)
elif action=="P":
self.run(0, self.BRAKE_MODE, 0)
elif action=="F":
self.run(0, mode, value)
elif action=="B":
self.run(0, mode, -value)
elif action=="L":
self.run(1, mode, -value)
self.run(2, mode, value)
elif action=="R":
self.run(1, mode, value)
self.run(2, mode, -value)
else:
raise ValueError('Invalid input, valid are "N","P","F","B","L","R"')
motor = Motor(onboard_i2c)
'''Reclaim memory'''
gc.collect()
"""
Mixbot-Onboard resources
Micropython library for the Mixbot-Onboard resources
=======================================================
@dahanzimin From the Mixly Team
"""
import time, gc, random, uframebuf
from micropython import const
from machine import Pin, SoftI2C, ADC, PWM, RTC
'''RTC'''
rtc_clock=RTC()
'''2RGB_WS2812'''
from ws2812 import NeoPixel
onboard_rgb = NeoPixel(Pin(12), 2, default=1, timing=(450, 900, 850, 500))
'''1Buzzer-Music'''
from music import MIDI
onboard_music =MIDI(25)
spk_en = Pin(27, Pin.OUT)
spk_en.value(0)
'''i2c-onboard & ext'''
class I2C_device(SoftI2C):
CRC8_Table =b'\x00^\xbc\xe2a?\xdd\x83\xc2\x9c~ \xa3\xfd\x1fA\x9d\xc3!\x7f\xfc\xa2@\x1e_\x01\xe3\xbd>`\x82\xdc#}\x9f\xc1B\x1c\xfe\xa0\xe1\xbf]\x03\x80\xde<b\xbe\xe0\x02\\\xdf\x81c=|"\xc0\x9e\x1dC\xa1\xffF\x18\xfa\xa4\'y\x9b\xc5\x84\xda8f\xe5\xbbY\x07\xdb\x85g9\xba\xe4\x06X\x19G\xa5\xfbx&\xc4\x9ae;\xd9\x87\x04Z\xb8\xe6\xa7\xf9\x1bE\xc6\x98z$\xf8\xa6D\x1a\x99\xc7%{:d\x86\xd8[\x05\xe7\xb9\x8c\xd20n\xed\xb3Q\x0fN\x10\xf2\xac/q\x93\xcd\x11O\xad\xf3p.\xcc\x92\xd3\x8do1\xb2\xec\x0eP\xaf\xf1\x13M\xce\x90r,m3\xd1\x8f\x0cR\xb0\xee2l\x8e\xd0S\r\xef\xb1\xf0\xaeL\x12\x91\xcf-s\xca\x94v(\xab\xf5\x17I\x08V\xb4\xeai7\xd5\x8bW\t\xeb\xb56h\x8a\xd4\x95\xcb)w\xf4\xaaH\x16\xe9\xb7U\x0b\x88\xd64j+u\x97\xc9J\x14\xf6\xa8t*\xc8\x96\x15K\xa9\xf7\xb6\xe8\nT\xd7\x89k5'
def _crc8(self, buf):
_sum = 0
for i in range(0, len(buf)):
_sum = self.CRC8_Table[_sum ^ buf[i]]
return _sum
def read_device(self, addr, cmd, nbytes=1):
buf = self.readfrom_mem(addr, cmd, nbytes+2)
if self._crc8(buf[:-1]) == buf[-1]:
return buf[1] if nbytes<=1 else buf[1:-1]
def write_device(self, addr, cmd, buf=0):
buf = buf.to_bytes(1, 'little') if type(buf) is int else buf
buf = bytearray([cmd, random.randint(0, 255)]) + buf
crc8 = self._crc8(buf).to_bytes(1, 'little')
self.writeto(addr, buf + crc8)
if crc8 == self.readfrom(addr, 1):
return True
onboard_i2c = I2C_device(scl=Pin(18), sda=Pin(23) , freq=400000)
ext_i2c = I2C_device(scl=Pin(22), sda=Pin(21), freq=200000)
'''Version judgment'''
if 0x68 in onboard_i2c.scan():
version=1
else:
version=0
'''Accelerometer+Gyroscope'''
if version:
import icm42670
acc_gyr = icm42670.ICM42670(onboard_i2c)
'''2-Button'''
class Button:
def __init__(self, pin, level=True):
self._pin = Pin(pin, Pin.IN)
self._flag = True
self._level = level
def get_presses(self, delay = 1):
last_time,presses = time.time(), 0
while time.time() < last_time + delay:
time.sleep(0.05)
if self.was_pressed():
presses += 1
return presses
def is_pressed(self):
return self._pin.value() == self._level
def was_pressed(self):
if self._pin.value() != self._flag:
time.sleep(0.01)
self._flag = self._pin.value()
return self._level if self._flag else not self._level
def irq(self, handler, trigger):
self._pin.irq(handler = handler, trigger = trigger)
button_p = Button(34, True)
button_a = Button(35, False)
button_b = Button(39, False)
'''2-LED'''
class LED:
def __init__(self, pin):
self._pin =PWM(Pin(pin), freq=5000, duty_u16=65535)
self.setbrightness(0)
def setbrightness(self,val):
if not 0 <= val <= 100:
raise ValueError("Brightness must be in the range: 0-100%")
self._brightness=val
self._pin.duty_u16(val * 65535 // 100)
def getbrightness(self):
return self._brightness
def setonoff(self,val):
if(val == -1):
self.setbrightness(100) if self._brightness < 50 else self.setbrightness(0)
elif(val == 1):
self.setbrightness(100)
elif(val == 0):
self.setbrightness(0)
def getonoff(self):
return True if self._brightness > 0 else False
def value(self,val=None):
if val is None:
return self.getonoff()
else:
self.setbrightness(100) if val else self.setbrightness(0)
rled = LED(2)
gled = LED(4)
'''3-ADCSensor'''
class ADCSensor:
def __init__(self, pin):
self.adc=ADC(Pin(pin))
self.adc.atten(ADC.ATTN_11DB)
def read(self):
return self.adc.read_u16()
def voltage(self, scale=4.6):
return round(self.adc.read_uv() * scale / 1000000, 2)
def loudness(self):
values = []
for i in range(200):
val = self.adc.read_u16()
values.append(val)
return max(values) - min(values)
adc1 = ADCSensor(33)
adc2 = ADCSensor(32)
battery = ADCSensor(36)
sound = ADCSensor(38)
'''4-FindLine /i2c'''
class FindLine(object):
CORRECTING_WHITE = const(0x01)
CORRECTING_BLACK = const(0x02)
CORRECTING_RESET_TO_FAB = const(0x04)
def __init__(self, i2c_bus, addr=0x01):
self._i2c = i2c_bus
self._addr = addr
self._data = (0,0,0,0)
def getdata(self):
_buf = self._i2c.read_device(self._addr, 0x10, 4)
if _buf:
self._data = tuple(_buf)
return self._data
def correct(self,type):
'''type 0x01 校正白色 0x02 校正黑色 0x04 恢复出厂 '''
if type not in [CORRECTING_WHITE, CORRECTING_BLACK, CORRECTING_RESET_TO_FAB]:
raise ValueError('Invalid parameter')
self._i2c.write_device(self._addr, 0xA0, type)
patrol = FindLine(onboard_i2c)
'''4-LEDmatrix /i2c'''
class Matrix5x5(uframebuf.FrameBuffer_Ascall):
"""Graph module 5x5"""
HEART = b'\n\x1f\x1f\x0e\x04'
HEART_SMALL = b'\x00\n\x0e\x04\x00'
HAPPY = b'\x00\n\x00\x11\x0e'
SAD = b'\x00\n\x00\x0e\x11'
SMILE = b'\x00\x00\x00\x11\x0e'
SILLY = b'\x11\x00\x1f\x14\x1c'
FABULOUS = b'\x1f\x1b\x00\n\x0e'
SURPRISED = b'\n\x00\x04\n\x04'
ASLEEP = b'\x00\x1b\x00\x0e\x00'
ANGRY = b'\x11\n\x00\x1f\x15'
CONFUSED = b'\x00\n\x00\n\x15'
NO = b'\x11\n\x04\n\x11'
YES = b'\x00\x10\x08\x05\x02'
LEFT_ARROW = b'\x04\x02\x1f\x02\x04'
RIGHT_ARROW = b'\x04\x08\x1f\x08\x04'
DRESS = b'\n\x1b\x0e\x0e\x1f'
TRANSFORMERS = b'\x04\x0e\x15\n\x11'
SCISSORS = b'\x13\x0b\x04\x0b\x13'
EXIT = b'\x04\x0e\x15\x0b\x10'
TREE = b'\x04\x0e\x1f\x04\x04'
PACMAN = b'\x1e\x0b\x07\x0f\x1e'
TARGET = b'\x04\x0e\x1b\x0e\x04'
TSHIRT = b'\x1b\x1f\x0e\x0e\x0e'
ROLLERSKATE = b'\x18\x18\x1f\x1f\n'
DUCK = b'\x06\x07\x1e\x0e\x00'
HOUSE = b'\x04\x0e\x1f\x0e\n'
TORTOISE = b'\x00\x0e\x1f\n\x00'
BUTTERFLY = b'\x1b\x1f\x04\x1f\x1b'
STICKFIGURE = b'\x04\x1f\x04\n\x11'
GHOST = b'\x1f\x15\x1f\x1f\x15'
PITCHFORK = b'\x15\x15\x1f\x04\x04'
MUSIC_QUAVERS = b'\x1e\x12\x12\x1b\x1b'
MUSIC_QUAVER = b'\x04\x0c\x14\x07\x07'
MUSIC_CROTCHET = b'\x04\x04\x04\x07\x07'
COW = b'\x11\x11\x1f\x0e\x04'
RABBIT = b'\x05\x05\x0f\x0b\x0f'
SQUARE_SMALL = b'\x00\x0e\n\x0e\x00'
SQUARE = b'\x1f\x11\x11\x11\x1f'
DIAMOND_SMALL = b'\x00\x04\n\x04\x00'
DIAMOND = b'\x04\n\x11\n\x04'
CHESSBOARD = b'\n\x15\n\x15\n'
TRIANGLE_LEFT = b'\x01\x03\x05\t\x1f'
TRIANGLE = b'\x00\x04\n\x1f\x00'
SNAKE = b'\x03\x1b\n\x0e\x00'
UMBRELLA = b'\x0e\x1f\x04\x05\x06'
SKULL = b'\x0e\x15\x1f\x0e\x0e'
GIRAFFE = b'\x03\x02\x02\x0e\n'
SWORD = b'\x04\x04\x04\x0e\x04'
def __init__(self, i2c_bus, addr=0x03, brightness=0.5):
self._i2c = i2c_bus
self._addr = addr
self._brightness= brightness
self._buffer = bytearray(5)
super().__init__(self._buffer, 5, 5, uframebuf.MONO_HMSB)
self.font("5x5")
self.screenbright(self._brightness)
self.clear()
def screenbright(self, brightness=None, background=0):
if brightness is None :
return self._brightness
else:
if not 0.0 <= brightness <= 1.0:
raise ValueError("Brightness must be a decimal number in the range: 0.0-1.0")
self._brightness = brightness
self._i2c.write_device(self._addr, 0xA5, bytes([round(255 * brightness), round(255 * background)]))
def ambientbright(self):
bright = self._i2c.read_device(self._addr, 0x10)
if bright:
return bright
def direction(self,mode = 0):
'''set display direction '''
self._i2c.write_device(self._addr, 0xA7, mode)
def show(self):
'''Refresh the display and show the changes'''
buf = bytearray(4)
buf[0] = (self._buffer[4] & 0xF0) >> 4
buf[1] = (self._buffer[3] & 0x1E) >> 1 | (self._buffer[4] & 0x0F) << 4
buf[2] = (self._buffer[1] & 0x18) >> 3 | (self._buffer[2] & 0x1F) << 2 | (self._buffer[3] & 0x01) << 7
buf[3] = (self._buffer[0] & 0x1F) | (self._buffer[1] & 0x07) << 5
self._i2c.write_device(self._addr, 0xA1, buf)
def clear(self):
''' clear display'''
self._i2c.write_device(self._addr, 0xA6)
onboard_matrix = Matrix5x5(onboard_i2c)
'''2 Motor /i2c'''
class Motor(object):
STOP_MODE = const(0x00)
BRAKE_MODE = const(0x01)
PWR_MODE = const(0x02)
SPEED_MODE = const(0x03)
TURNS_MODE = const(0x04)
def __init__(self, i2c_bus, addr=0x02, scale=90 * 4):
self._i2c = i2c_bus
self._addr = addr
self._scale = scale
self._signala = PWM(Pin(13), freq=500, duty_u16=49150)
self._signalb = PWM(Pin(14), freq=500, duty_u16=49150)
self._status = ((0,0,0,0), (0,0,0,0))
self._motor = ([0,0], [0,0])
def _u2s(self, value, n=8):
return value if value < (1 << (n-1)) else value - (1 << n)
def status(self):
_buf = self._i2c.read_device(self._addr, 0x10, 9)
if _buf:
self._status = ((_buf[0] >> 4, -self._u2s(_buf[1]), -self._u2s(_buf[3]), abs(self._u2s(_buf[6] << 8 | _buf[5], 16))),
(_buf[0] & 0x0F, self._u2s(_buf[2]), self._u2s(_buf[4]), abs(self._u2s(_buf[8] << 8 | _buf[7], 16))))
return self._status
def run(self, idx, mode, value):
if idx == 1 or idx == 2:
self._motor[idx-1][0], self._motor[idx-1][1] = mode, value
else:
self._motor = ([mode, value], [mode, value])
buf = bytearray(5)
m1_pwr_speed, m2_pwr_speed = 0, 0
buf[0] = (self._motor[0][0] << 4) | self._motor[1][0]
if self._motor[0][0] == self.TURNS_MODE:
_turns = round(self._motor[0][1] * self._scale)
buf[1] = (- _turns) & 0xFF
buf[2] = ((- _turns) >> 8) & 0xFF
else:
m1_pwr_speed = - max(min(self._motor[0][1], 100), -100)
if self._motor[1][0] == self.TURNS_MODE:
_turns = round(self._motor[1][1] * self._scale)
buf[3] = _turns & 0xFF
buf[4] = (_turns >> 8) & 0xFF
else:
m2_pwr_speed = max(min(self._motor[1][1], 100), -100)
self._i2c.write_device(self._addr, 0xA0, buf)
self._signala.duty_u16(33422 + 31457 * (m1_pwr_speed + 100) // 200)
self._signalb.duty_u16(33422 + 31457 * (m2_pwr_speed + 100) // 200)
def move(self, action, mode, value=100):
if action=="N":
self.run(0, self.STOP_MODE, 0)
elif action=="P":
self.run(0, self.BRAKE_MODE, 0)
elif action=="F":
self.run(0, mode, value)
elif action=="B":
self.run(0, mode, -value)
elif action=="L":
self.run(1, mode, -value)
self.run(2, mode, value)
elif action=="R":
self.run(1, mode, value)
self.run(2, mode, -value)
else:
raise ValueError('Invalid input, valid are "N","P","F","B","L","R"')
motor = Motor(onboard_i2c)
'''Reclaim memory'''
gc.collect()

View File

@@ -1,174 +1,174 @@
"""
RM E1 -Onboard resources
MicroPython library for the RM E1 -Onboard resources
=======================================================
#Preliminary composition 20220703
dahanzimin From the Mixly Team
"""
import time,gc
#import ble_handle
from machine import Pin,SoftI2C,ADC,PWM,RTC
'''Bluetooth-handle'''
#handle=ble_handle.Handle()
'''i2c-onboard'''
onboard_i2c=SoftI2C(scl = Pin(22), sda = Pin(21), freq = 400000)
'''RTC'''
rtc_clock=RTC()
'''ACC-Sensor'''
class ACC:
def __init__(self,i2c_bus):
self._device = i2c_bus
self._address = 0x09
def _rreg(self,nbytes):
'''Read memory address'''
return self._device.readfrom(self._address, nbytes)
def acceleration(self):
data_reg=self._rreg(3)
return data_reg[0],data_reg[1],data_reg[2] #返回x y轴数值(0~180)及晃动值
try :
gyro=ACC(onboard_i2c)
except Exception as e:
print("Warning: Failed to communicate with ACC or",e)
'''2RGB_WS2812''' #color_chase(),rainbow_cycle()方法移至类里
from ws2812 import NeoPixel
onboard_rgb = NeoPixel(Pin(12), 2, default=1)
'''3-Button'''
class Button:
def __init__(self, pin):
self._pin = Pin(pin, Pin.IN)
self._flag = True
def get_presses(self, delay = 1):
last_time,presses = time.time(), 0
while time.time() < last_time + delay:
time.sleep(0.05)
if self.was_pressed():
presses += 1
return presses
def is_pressed(self):
return self._pin.value() == False
def was_pressed(self):
if self._pin.value() != self._flag:
time.sleep(0.01)
self._flag = self._pin.value()
if self._flag:
return False
else:
return True
def irq(self, handler, trigger):
self._pin.irq(handler = handler, trigger = trigger)
button_p = Button(35)
button_cw = Button(39)
button_ccw = Button(36)
'''3-ADCSensor'''
class ADCSensor:
def __init__(self, pin):
self._adc=ADC(Pin(pin))
self._adc.atten(ADC.ATTN_11DB)
def read(self):
return self._adc.read_u16()
def voltage(self):
return round(self._adc.read_uv()*4.6/1000000,2)
adc1=ADCSensor(32)
adc2=ADCSensor(33)
'''ADC conflicts with WiFi'''
try:
battery=ADCSensor(26)
except:
class Clash:
def voltage(self):
print("Warning: battery power collection conflicts with WiFi")
return None
battery=Clash()
'''2-LED''' #Repair brightness adjustment range 0-100%
class LED:
def __init__(self, pin):
self._pin =PWM(Pin(pin),freq=5000,duty_u16=0)
self.setbrightness(0)
def value(self, val):
self.setonoff(val)
def setbrightness(self,val):
if not 0 <= val <= 100:
raise ValueError("Brightness must be in the range: 0-100%")
self._brightness=val
self._pin.duty_u16(val*65535//100)
def getbrightness(self):
return self._brightness
def setonoff(self,val):
if(val == -1):
self.setbrightness(100) if self._brightness<50 else self.setbrightness(0)
elif(val == 1):
self.setbrightness(100)
elif(val == 0):
self.setbrightness(0)
def getonoff(self):
return True if self._brightness>0 else False
rled = LED(2)
gled = LED(4)
'''3-Motor'''
class Motor:
def __init__(self, apin,bpin):
self._apin =PWM(Pin(apin),freq=5000,duty_u16=65535)
self._bpin =PWM(Pin(bpin),freq=5000,duty_u16=65535)
self.motion("P")
def motion(self,action,speed=0):
if action=="N":
self._apin.duty_u16(0)
self._bpin.duty_u16(0)
elif action=="P":
self._apin.duty_u16(65535)
self._bpin.duty_u16(65535)
elif action=="CW":
if speed >=0:
self._apin.duty_u16(speed*65535//100)
self._bpin.duty_u16(0)
else:
self._apin.duty_u16(0)
self._bpin.duty_u16(-speed*65535//100)
elif action=="CCW":
if speed >=0:
self._apin.duty_u16(0)
self._bpin.duty_u16(speed*65535//100)
else:
self._apin.duty_u16(-speed*65535//100)
self._bpin.duty_u16(0)
else:
raise ValueError('Invalid input, valid are "N","P","CW","CCW"')
motor1=Motor(23,27)
motor2=Motor(18,19)
motor3=Motor(13,14)
'''Reclaim memory'''
gc.collect()
"""
RM E1 -Onboard resources
MicroPython library for the RM E1 -Onboard resources
=======================================================
#Preliminary composition 20220703
dahanzimin From the Mixly Team
"""
import time,gc
#import ble_handle
from machine import Pin,SoftI2C,ADC,PWM,RTC
'''Bluetooth-handle'''
#handle=ble_handle.Handle()
'''i2c-onboard'''
onboard_i2c=SoftI2C(scl = Pin(22), sda = Pin(21), freq = 400000)
'''RTC'''
rtc_clock=RTC()
'''ACC-Sensor'''
class ACC:
def __init__(self,i2c_bus):
self._device = i2c_bus
self._address = 0x09
def _rreg(self,nbytes):
'''Read memory address'''
return self._device.readfrom(self._address, nbytes)
def acceleration(self):
data_reg=self._rreg(3)
return data_reg[0],data_reg[1],data_reg[2] #返回x y轴数值(0~180)及晃动值
try :
gyro=ACC(onboard_i2c)
except Exception as e:
print("Warning: Failed to communicate with ACC or",e)
'''2RGB_WS2812''' #color_chase(),rainbow_cycle()方法移至类里
from ws2812 import NeoPixel
onboard_rgb = NeoPixel(Pin(12), 2, default=1, timing=(450, 900, 850, 500))
'''3-Button'''
class Button:
def __init__(self, pin):
self._pin = Pin(pin, Pin.IN)
self._flag = True
def get_presses(self, delay = 1):
last_time,presses = time.time(), 0
while time.time() < last_time + delay:
time.sleep(0.05)
if self.was_pressed():
presses += 1
return presses
def is_pressed(self):
return self._pin.value() == False
def was_pressed(self):
if self._pin.value() != self._flag:
time.sleep(0.01)
self._flag = self._pin.value()
if self._flag:
return False
else:
return True
def irq(self, handler, trigger):
self._pin.irq(handler = handler, trigger = trigger)
button_p = Button(35)
button_cw = Button(39)
button_ccw = Button(36)
'''3-ADCSensor'''
class ADCSensor:
def __init__(self, pin):
self._adc=ADC(Pin(pin))
self._adc.atten(ADC.ATTN_11DB)
def read(self):
return self._adc.read_u16()
def voltage(self):
return round(self._adc.read_uv()*4.6/1000000,2)
adc1=ADCSensor(32)
adc2=ADCSensor(33)
'''ADC conflicts with WiFi'''
try:
battery=ADCSensor(26)
except:
class Clash:
def voltage(self):
print("Warning: battery power collection conflicts with WiFi")
return None
battery=Clash()
'''2-LED''' #Repair brightness adjustment range 0-100%
class LED:
def __init__(self, pin):
self._pin =PWM(Pin(pin),freq=5000,duty_u16=0)
self.setbrightness(0)
def value(self, val):
self.setonoff(val)
def setbrightness(self,val):
if not 0 <= val <= 100:
raise ValueError("Brightness must be in the range: 0-100%")
self._brightness=val
self._pin.duty_u16(val*65535//100)
def getbrightness(self):
return self._brightness
def setonoff(self,val):
if(val == -1):
self.setbrightness(100) if self._brightness<50 else self.setbrightness(0)
elif(val == 1):
self.setbrightness(100)
elif(val == 0):
self.setbrightness(0)
def getonoff(self):
return True if self._brightness>0 else False
rled = LED(2)
gled = LED(4)
'''3-Motor'''
class Motor:
def __init__(self, apin,bpin):
self._apin =PWM(Pin(apin),freq=5000,duty_u16=65535)
self._bpin =PWM(Pin(bpin),freq=5000,duty_u16=65535)
self.motion("P")
def motion(self,action,speed=0):
if action=="N":
self._apin.duty_u16(0)
self._bpin.duty_u16(0)
elif action=="P":
self._apin.duty_u16(65535)
self._bpin.duty_u16(65535)
elif action=="CW":
if speed >=0:
self._apin.duty_u16(speed*65535//100)
self._bpin.duty_u16(0)
else:
self._apin.duty_u16(0)
self._bpin.duty_u16(-speed*65535//100)
elif action=="CCW":
if speed >=0:
self._apin.duty_u16(0)
self._bpin.duty_u16(speed*65535//100)
else:
self._apin.duty_u16(-speed*65535//100)
self._bpin.duty_u16(0)
else:
raise ValueError('Invalid input, valid are "N","P","CW","CCW"')
motor1=Motor(23,27)
motor2=Motor(18,19)
motor3=Motor(13,14)
'''Reclaim memory'''
gc.collect()