build(boards): 所有板卡执行 npm run build:prod
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,110 +0,0 @@
|
||||
"""
|
||||
AI-Camera (Inherit C module)
|
||||
|
||||
MicroPython library for the AI-Camera(Inherit C module)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import esp_ai
|
||||
from micropython import const
|
||||
|
||||
CODE_DETECTION = const(0)
|
||||
COLOR_DETECTION = const(1)
|
||||
MOTION_DEECTION = const(2)
|
||||
CAT_FACE_DETECTION = const(3)
|
||||
FACE_DETECTION = const(4)
|
||||
FACE_RECOGNITION = const(5)
|
||||
|
||||
class AI:
|
||||
def __init__(self, function):
|
||||
self._func = function
|
||||
self._ai = None
|
||||
self._once = True
|
||||
|
||||
def _init(self, *args):
|
||||
if self._func == CODE_DETECTION:
|
||||
self._ai = esp_ai.code_recognition()
|
||||
elif self._func == COLOR_DETECTION:
|
||||
self._ai = esp_ai.color_detection(color=args[0])
|
||||
elif self._func == MOTION_DEECTION:
|
||||
self._ai = esp_ai.motion_recognition(threshold=args[0])
|
||||
elif self._func == CAT_FACE_DETECTION:
|
||||
self._ai = esp_ai.cat_detection()
|
||||
elif self._func == FACE_DETECTION:
|
||||
self._ai = esp_ai.face_detection()
|
||||
elif self._func == FACE_RECOGNITION:
|
||||
self._ai = esp_ai.face_recognition()
|
||||
else:
|
||||
raise AttributeError('AI model is not supported')
|
||||
self._ai.start() #启动检测,可以通过LCD观察结果
|
||||
self._once = False
|
||||
|
||||
def _result(self, res, _t, _s=0, _n=0): #_s:第几个, _n:细分第几个
|
||||
if not res: return None
|
||||
if _t == 'len':
|
||||
return res[0]
|
||||
elif _t == 'pos':
|
||||
if len(res) >= (5 + _s * 4):
|
||||
return res[(1 + _s * 4):(5 + _s * 4)]
|
||||
elif _t == 'keypoint':
|
||||
if len(res) >= (7 + _s * 14 + _n * 2):
|
||||
return res[(5 + _s * 14 + _n * 2):(7 + _s * 14 + _n * 2)]
|
||||
|
||||
def code_recognition(self):
|
||||
if self._func == CODE_DETECTION:
|
||||
if self._once: self._init()
|
||||
return self._ai.read()
|
||||
else:
|
||||
raise AttributeError('This model can only run QR code detection')
|
||||
|
||||
def color_detection(self, color=0, event='pos', num=0):
|
||||
if self._func == COLOR_DETECTION:
|
||||
if self._once: self._init(color)
|
||||
return self._result(self._ai.read(), event, num)
|
||||
else:
|
||||
raise AttributeError('This model can only run color detection')
|
||||
|
||||
def motion_recognition(self, threshold=50):
|
||||
if self._func == MOTION_DEECTION:
|
||||
if self._once: self._init(threshold)
|
||||
return bool(self._ai.read() >= threshold)
|
||||
else:
|
||||
raise AttributeError('This model can only run motion recognition')
|
||||
|
||||
def cat_detection(self, event='pos', num=0):
|
||||
if self._func == CAT_FACE_DETECTION:
|
||||
if self._once: self._init()
|
||||
return self._result(self._ai.read(), event, num)
|
||||
else:
|
||||
raise AttributeError('This model can only run cat face detection')
|
||||
|
||||
def face_detection(self, event='pos', num=0, point=0):
|
||||
if self._func == FACE_DETECTION:
|
||||
if self._once: self._init()
|
||||
return self._result(self._ai.read(), event, num, point)
|
||||
else:
|
||||
raise AttributeError('This model can only run face detection')
|
||||
|
||||
def face_recognition(self, event='pos', num=0, point=0):
|
||||
if self._func == FACE_RECOGNITION:
|
||||
if self._once: self._init()
|
||||
return self._result(self._ai.recognize(), event, num, point)
|
||||
else:
|
||||
raise AttributeError('This model can only run face recognition')
|
||||
|
||||
def face_enroll(self):
|
||||
if self._func == FACE_RECOGNITION:
|
||||
return self._ai.enroll()
|
||||
else:
|
||||
raise AttributeError('This model can only run face recognition')
|
||||
|
||||
def face_delete(self, _id):
|
||||
if self._func == FACE_RECOGNITION:
|
||||
self._ai.delete(_id)
|
||||
else:
|
||||
raise AttributeError('This model can only run face recognition')
|
||||
|
||||
def stop(self):
|
||||
if self._ai is not None:
|
||||
self._ai.stop()
|
||||
@@ -1,69 +1,47 @@
|
||||
"""
|
||||
Camera GC032A/FrameBuffer(Inherit C module)
|
||||
Camera
|
||||
|
||||
MicroPython library for the GC032A(Inherit C module)
|
||||
MicroPython library for the Camera(Inherit C module)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
import base64
|
||||
from sensor import *
|
||||
import jpeg
|
||||
from _camera import *
|
||||
from jpeg import Encoder
|
||||
from machine import SoftI2C, Pin
|
||||
from mixgo_sant import onboard_bot
|
||||
from esp_usb import CAM
|
||||
|
||||
class GC032A(Camera):
|
||||
def __init__(self, framesize=LCD, hmirror=None, frame=1):
|
||||
onboard_bot.cam_en(1, 500)
|
||||
super().__init__(frame)
|
||||
super().set_framesize(framesize)
|
||||
time.sleep_ms(100)
|
||||
if hmirror is not None:
|
||||
super().set_hmirror(hmirror)
|
||||
time.sleep_ms(100)
|
||||
SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000)
|
||||
SoftI2C(scl=Pin(47), sda=Pin(38), freq=400000)
|
||||
|
||||
class Camera(Camera):
|
||||
def __init__(self, frame_size=FrameSize.R240X240, pixel_format=PixelFormat.RGB565, hmirror=False, vflip=False, **kwargs):
|
||||
onboard_bot.cam_en(1, 150)
|
||||
super().__init__(frame_size=frame_size, pixel_format=pixel_format, **kwargs)
|
||||
self.set_hmirror(not hmirror)
|
||||
time.sleep_ms(50)
|
||||
self.set_vflip(not vflip)
|
||||
time.sleep_ms(50)
|
||||
SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000) # 恢复I2C
|
||||
|
||||
def deinit(self):
|
||||
super().deinit()
|
||||
onboard_bot.cam_en(0, 100)
|
||||
|
||||
def display(self, show=True):
|
||||
if show:
|
||||
super().display()
|
||||
def snapshot(self, path=None, formats=0, quality=90, rotation=0):
|
||||
if formats == 0 and path is None:
|
||||
return self.capture()
|
||||
else:
|
||||
super().display_stop()
|
||||
|
||||
def snapshot(self, path=None, formats=0, quality=50):
|
||||
if path is None:
|
||||
_data = super().snapshot(formats=formats, quality=quality)
|
||||
if formats >= 2:
|
||||
return b'data:image/jpg;base64,' + base64.b64encode(_data)
|
||||
_encoder = Encoder(pixel_format="RGB565_BE", quality=quality, rotation=rotation, width=self.get_pixel_width(), height=self.get_pixel_height())
|
||||
_jpeg = _encoder.encode(self.capture())
|
||||
del _encoder
|
||||
if path is None:
|
||||
if formats == 1:
|
||||
return _jpeg
|
||||
else:
|
||||
return b'data:image/jpg;base64,' + base64.b64encode(_jpeg)
|
||||
else:
|
||||
return _data
|
||||
else:
|
||||
return super().snapshot(path, quality=50)
|
||||
|
||||
class UVC(CAM):
|
||||
def __init__(self, framesize=QVGA):
|
||||
super().__init__(framesize)
|
||||
|
||||
def deinit(self):
|
||||
super().deinit()
|
||||
|
||||
def display(self, show=True):
|
||||
if show:
|
||||
super().display()
|
||||
else:
|
||||
super().display_stop()
|
||||
|
||||
def snapshot(self, path=None, formats=0, quality=50):
|
||||
if path is None:
|
||||
_data = super().snapshot(formats=formats, quality=quality)
|
||||
if formats >= 2:
|
||||
return b'data:image/jpg;base64,' + base64.b64encode(_data)
|
||||
else:
|
||||
return _data
|
||||
else:
|
||||
return super().snapshot(path, quality=50)
|
||||
with open(path, 'wb') as f:
|
||||
f.write(_jpeg)
|
||||
return True
|
||||
|
||||
@@ -7,25 +7,26 @@ MicroPython library for the CI130Xx (ASR-I2C)
|
||||
"""
|
||||
from ci130x import CI130X
|
||||
|
||||
|
||||
class CI1302(CI130X):
|
||||
def __init__(self, i2c_bus, func, addr=0x64):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._cmd_id = None
|
||||
self._func = func
|
||||
def __init__(self, i2c_bus, func, addr=0x64):
|
||||
self._device = i2c_bus
|
||||
self._address = addr
|
||||
self._cmd_id = None
|
||||
self._func = func
|
||||
|
||||
def _wreg(self, reg):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._device.writeto(self._address, reg)
|
||||
except:
|
||||
self._func(1, 700) #Power on
|
||||
self._device.writeto(self._address, reg)
|
||||
def _wreg(self, reg):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._device.writeto(self._address, reg)
|
||||
except:
|
||||
self._func(1, 700) # Power on
|
||||
self._device.writeto(self._address, reg)
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
except:
|
||||
self._func(1, 700) #Power on
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
except:
|
||||
self._func(1, 700) # Power on
|
||||
return self._device.readfrom_mem(self._address, reg, nbytes)
|
||||
|
||||
@@ -25,65 +25,70 @@ class ES8374:
|
||||
self.configI2SFormat(_ES_MODULE_ADC_DAC, _FMT_I2S_NORMAL)
|
||||
|
||||
def _readReg(self, regAddr):
|
||||
return self.i2c_bus.readfrom_mem(self.i2c_addr, regAddr, 1)[0]
|
||||
return self.i2c_bus.readfrom_mem(self.i2c_addr, regAddr, 1)[0]
|
||||
|
||||
def _writeReg(self, regAddr, data):
|
||||
self.i2c_bus.writeto_mem(self.i2c_addr, regAddr, data.to_bytes(1, 'little'))
|
||||
self.i2c_bus.writeto_mem(
|
||||
self.i2c_addr, regAddr, data.to_bytes(1, 'little'))
|
||||
|
||||
def init_reg(self, ms_mode, fmt, out_channel, in_channel):
|
||||
self._writeReg(0x00, 0x3F)# IC Rst start
|
||||
self._writeReg(0x00, 0x03)# IC Rst stop
|
||||
self._writeReg(0x01, 0x7F)# IC clk on # M ORG 7F
|
||||
self._writeReg(0x0f, (self._readReg(0x0F) & 0x7f) | (ms_mode << 7))# CODEC IN I2S SLAVE MODE
|
||||
self._writeReg(0x00, 0x3F) # IC Rst start
|
||||
self._writeReg(0x00, 0x03) # IC Rst stop
|
||||
self._writeReg(0x01, 0x7F) # IC clk on # M ORG 7F
|
||||
self._writeReg(0x0f, (self._readReg(0x0F) & 0x7f) | (ms_mode << 7)) # CODEC IN I2S SLAVE MODE
|
||||
|
||||
self._writeReg(0x6F, 0xA0)# pll set:mode enable
|
||||
self._writeReg(0x72, 0x41)# pll set:mode set
|
||||
self._writeReg(0x09, 0x01)# pll set:reset on ,set start
|
||||
self._writeReg(0x0C, 0x22)# pll set:k
|
||||
self._writeReg(0x0D, 0x2E)# pll set:k
|
||||
self._writeReg(0x0E, 0xC6)# pll set:k
|
||||
self._writeReg(0x0A, 0x3A)# pll set:
|
||||
self._writeReg(0x0B, 0x07)# pll set:n
|
||||
self._writeReg(0x09, 0x41)# pll set:reset off ,set stop
|
||||
self._writeReg(0x6F, 0xA0) # pll set:mode enable
|
||||
self._writeReg(0x72, 0x41) # pll set:mode set
|
||||
self._writeReg(0x09, 0x01) # pll set:reset on ,set start
|
||||
self._writeReg(0x0C, 0x22) # pll set:k
|
||||
self._writeReg(0x0D, 0x2E) # pll set:k
|
||||
self._writeReg(0x0E, 0xC6) # pll set:k
|
||||
self._writeReg(0x0A, 0x3A) # pll set:
|
||||
self._writeReg(0x0B, 0x07) # pll set:n
|
||||
self._writeReg(0x09, 0x41) # pll set:reset off ,set stop
|
||||
self.i2sConfigClock()
|
||||
self._writeReg(0x24, 0x08)# adc set
|
||||
self._writeReg(0x36, 0x00)# dac set
|
||||
self._writeReg(0x12, 0x30)# timming set
|
||||
self._writeReg(0x13, 0x20)# timming set
|
||||
self._writeReg(0x24, 0x08) # adc set
|
||||
self._writeReg(0x36, 0x00) # dac set
|
||||
self._writeReg(0x12, 0x30) # timming set
|
||||
self._writeReg(0x13, 0x20) # timming set
|
||||
self.configI2SFormat(_ES_MODULE_ADC, fmt)
|
||||
self.configI2SFormat(_ES_MODULE_DAC, fmt)
|
||||
self._writeReg(0x21, 0x50)# adc set: SEL LIN1 CH+PGAGAIN=0DB
|
||||
self._writeReg(0x22, 0xFF)# adc set: PGA GAIN=0DB
|
||||
self._writeReg(0x21, 0x14)# adc set: SEL LIN1 CH+PGAGAIN=18DB
|
||||
self._writeReg(0x22, 0x55)# pga = +15db
|
||||
self._writeReg(0x08, 0x21)# set class d divider = 33, to avoid the high frequency tone on laudspeaker
|
||||
self._writeReg(0x00, 0x80)# IC START
|
||||
self._writeReg(0x21, 0x50) # adc set: SEL LIN1 CH+PGAGAIN=0DB
|
||||
self._writeReg(0x22, 0xFF) # adc set: PGA GAIN=0DB
|
||||
self._writeReg(0x21, 0x14) # adc set: SEL LIN1 CH+PGAGAIN=18DB
|
||||
self._writeReg(0x22, 0x55) # pga = +15db
|
||||
# set class d divider = 33, to avoid the high frequency tone on laudspeaker
|
||||
self._writeReg(0x08, 0x21)
|
||||
self._writeReg(0x00, 0x80) # IC START
|
||||
time.sleep(0.05)
|
||||
self._writeReg(0x25, 0x00)# ADCVOLUME on
|
||||
self._writeReg(0x38, 0x00)# DACVOLUME on
|
||||
self._writeReg(0x14, 0x8A)# IC START
|
||||
self._writeReg(0x15, 0x40)# IC START
|
||||
self._writeReg(0x1A, 0xA0)# monoout set
|
||||
self._writeReg(0x1B, 0x19)# monoout set
|
||||
self._writeReg(0x1C, 0x90)# spk set
|
||||
self._writeReg(0x1D, 0x01)# spk set
|
||||
self._writeReg(0x1F, 0x00)# spk set
|
||||
self._writeReg(0x1E, 0x20)# spk on
|
||||
self._writeReg(0x28, 0x70)# alc set 0x70
|
||||
#self._writeReg(0x26, 0x4E)# alc set
|
||||
#self._writeReg(0x27, 0x10)# alc set
|
||||
#self._writeReg(0x29, 0x00)# alc set
|
||||
#self._writeReg(0x2B, 0x00)# alc set
|
||||
self._writeReg(0x25, 0x00)# ADCVOLUME on
|
||||
self._writeReg(0x38, 0x00)# DACVOLUME on
|
||||
self._writeReg(0x37, 0x30)# dac set
|
||||
self._writeReg(0x6D, 0x60)# SEL:GPIO1=DMIC CLK OUT+SEL:GPIO2=PLL CLK OUT
|
||||
self._writeReg(0x71, 0x05)# for automute setting
|
||||
self._writeReg(0x25, 0x00) # ADCVOLUME on
|
||||
self._writeReg(0x38, 0x00) # DACVOLUME on
|
||||
self._writeReg(0x14, 0x8A) # IC START
|
||||
self._writeReg(0x15, 0x40) # IC START
|
||||
self._writeReg(0x1A, 0xA0) # monoout set
|
||||
self._writeReg(0x1B, 0x19) # monoout set
|
||||
self._writeReg(0x1C, 0x90) # spk set
|
||||
self._writeReg(0x1D, 0x01) # spk set
|
||||
self._writeReg(0x1F, 0x00) # spk set
|
||||
self._writeReg(0x1E, 0x20) # spk on
|
||||
self._writeReg(0x28, 0x70) # alc set 0x70
|
||||
# self._writeReg(0x26, 0x4E)# alc set
|
||||
# self._writeReg(0x27, 0x10)# alc set
|
||||
# self._writeReg(0x29, 0x00)# alc set
|
||||
# self._writeReg(0x2B, 0x00)# alc set
|
||||
self._writeReg(0x25, 0x00) # ADCVOLUME on
|
||||
self._writeReg(0x38, 0x00) # DACVOLUME on
|
||||
self._writeReg(0x37, 0x30) # dac set
|
||||
# SEL:GPIO1=DMIC CLK OUT+SEL:GPIO2=PLL CLK OUT
|
||||
self._writeReg(0x6D, 0x60)
|
||||
self._writeReg(0x71, 0x05) # for automute setting
|
||||
self._writeReg(0x73, 0x70)
|
||||
self.configDACOutput(out_channel)# 0x3c Enable DAC and Enable Lout/Rout/1/2
|
||||
self.configADCInput(in_channel)# 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input DSSEL,use one DS Reg11 DSR, LINPUT1-RINPUT1
|
||||
# 0x3c Enable DAC and Enable Lout/Rout/1/2
|
||||
self.configDACOutput(out_channel)
|
||||
# 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input DSSEL,use one DS Reg11 DSR, LINPUT1-RINPUT1
|
||||
self.configADCInput(in_channel)
|
||||
self.voice_volume(95)
|
||||
self._writeReg(0x37, 0x00)# dac set
|
||||
self._writeReg(0x37, 0x00) # dac set
|
||||
'''
|
||||
reg = self._readReg(0x1a) # disable lout
|
||||
reg |= 0x08
|
||||
@@ -104,34 +109,37 @@ class ES8374:
|
||||
self._writeReg(0x1E, 0xa0) # disable class d
|
||||
self.voice_mute(0)
|
||||
'''
|
||||
|
||||
def stop(self):
|
||||
self.voice_mute(1)
|
||||
self._writeReg(0x1a, self._readReg(0x1a)| 0x08)
|
||||
self._writeReg(0x1a, self._readReg(0x1a)& 0xdf)
|
||||
self._writeReg(0x1D, 0x12)# mute speaker
|
||||
self._writeReg(0x1E, 0x20)# disable class d
|
||||
self._writeReg(0x15, self._readReg(0x15)| 0x20)
|
||||
self._writeReg(0x10, self._readReg(0x10)| 0xc0)
|
||||
self._writeReg(0x21, self._readReg(0x21)| 0xc0)
|
||||
self._writeReg(0x1a, self._readReg(0x1a) | 0x08)
|
||||
self._writeReg(0x1a, self._readReg(0x1a) & 0xdf)
|
||||
self._writeReg(0x1D, 0x12) # mute speaker
|
||||
self._writeReg(0x1E, 0x20) # disable class d
|
||||
self._writeReg(0x15, self._readReg(0x15) | 0x20)
|
||||
self._writeReg(0x10, self._readReg(0x10) | 0xc0)
|
||||
self._writeReg(0x21, self._readReg(0x21) | 0xc0)
|
||||
|
||||
def i2sConfigClock(self):
|
||||
self._writeReg(0x0f, (self._readReg(0x0F) & 0xe0) | _MCLK_DIV)
|
||||
self._writeReg(0x06, _LCLK_DIV >> 8)# ADCFsMode,singel SPEED,RATIO=256
|
||||
self._writeReg(0x07, _LCLK_DIV & 0xFF)# ADCFsMode,singel SPEED,RATIO=256
|
||||
# ADCFsMode,singel SPEED,RATIO=256
|
||||
self._writeReg(0x06, _LCLK_DIV >> 8)
|
||||
# ADCFsMode,singel SPEED,RATIO=256
|
||||
self._writeReg(0x07, _LCLK_DIV & 0xFF)
|
||||
|
||||
def configI2SFormat(self, mode, fmt):
|
||||
fmt_tmp = ((fmt & 0xf0) >> 4)
|
||||
fmt_i2s = fmt & 0x0f
|
||||
fmt_i2s = fmt & 0x0f
|
||||
if (mode == _ES_MODULE_ADC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x10)
|
||||
reg &= 0xfc
|
||||
self._writeReg(0x10, (reg|fmt_i2s))
|
||||
self._writeReg(0x10, (reg | fmt_i2s))
|
||||
self.setBitsPerSample(mode, 3)
|
||||
|
||||
if (mode == _ES_MODULE_DAC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x11)
|
||||
reg &= 0xfc
|
||||
self._writeReg(0x11, (reg|fmt_i2s))
|
||||
self._writeReg(0x11, (reg | fmt_i2s))
|
||||
self.setBitsPerSample(mode, 3)
|
||||
|
||||
# set Bits Per Sample
|
||||
@@ -140,26 +148,26 @@ class ES8374:
|
||||
if (mode == _ES_MODULE_ADC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x10)
|
||||
reg &= 0xe3
|
||||
self._writeReg(0x10, (reg| (bits << 2)))
|
||||
self._writeReg(0x10, (reg | (bits << 2)))
|
||||
|
||||
if (mode == _ES_MODULE_DAC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x11)
|
||||
reg &= 0xe3
|
||||
self._writeReg(0x11, (reg| (bits << 2)))
|
||||
self._writeReg(0x11, (reg | (bits << 2)))
|
||||
|
||||
def configDACOutput(self, output):
|
||||
self._writeReg(0x1d, 0x02)
|
||||
reg = self._readReg(0x1c) # set spk mixer
|
||||
reg = self._readReg(0x1c) # set spk mixer
|
||||
reg |= 0x80
|
||||
self._writeReg(0x1c, reg)
|
||||
self._writeReg(0x1D, 0x02) # spk set
|
||||
self._writeReg(0x1F, 0x00) # spk set
|
||||
self._writeReg(0x1E, 0xA0) # spk on
|
||||
self._writeReg(0x1D, 0x02) # spk set
|
||||
self._writeReg(0x1F, 0x00) # spk set
|
||||
self._writeReg(0x1E, 0xA0) # spk on
|
||||
|
||||
def configADCInput(self, input):
|
||||
reg = self._readReg(0x21)
|
||||
reg = (reg & 0xcf) | 0x24
|
||||
self._writeReg( 0x21, reg)
|
||||
self._writeReg(0x21, reg)
|
||||
|
||||
def mic_volume(self, volume=None):
|
||||
if volume is None:
|
||||
@@ -171,17 +179,17 @@ class ES8374:
|
||||
if volume is None:
|
||||
return round(100 - self._readReg(0x38) * 100 / 192)
|
||||
else:
|
||||
self._writeReg(0x38, (100 - volume) * 192 // 100)
|
||||
self._writeReg(0x38, (100 - volume) * 192 // 100)
|
||||
|
||||
def voice_mute(self, enable=None):
|
||||
if enable is None:
|
||||
return True if self._readReg(0x36) & 0x40 else False
|
||||
else:
|
||||
self._writeReg(0x36, (self._readReg(0x36)& 0xdf) | (enable << 5))
|
||||
self._writeReg(0x36, (self._readReg(0x36) & 0xdf) | (enable << 5))
|
||||
|
||||
def mic_gain(self, gain):
|
||||
gain_n = max(min(gain, 15), 0)
|
||||
self._writeReg(0x22, (gain_n | (gain_n<<4))) # MIC PGA -3.5db ~ 24db
|
||||
self._writeReg(0x22, (gain_n | (gain_n << 4))) # MIC PGA -3.5db ~ 24db
|
||||
|
||||
def pga_enable(self, enable):
|
||||
self._writeReg(0x21, (self._readReg(0x21) & 0xfb) | (enable << 2)) # MIC PGA 0db or 15db
|
||||
def pga_enable(self, enable):
|
||||
self._writeReg(0x21, (self._readReg(0x21) & 0xfb) | (enable << 2)) # MIC PGA 0db or 15db
|
||||
|
||||
17
boards/default/micropython_esp32s3/build/lib/esp_dl.py
Normal file
17
boards/default/micropython_esp32s3/build/lib/esp_dl.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
ESP-DL
|
||||
|
||||
MicroPython library for the ESP-DL(Inherit C module)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from espdl import *
|
||||
|
||||
def analyze(results, keys=None, num=0):
|
||||
if keys is None:
|
||||
return results is not None
|
||||
if results:
|
||||
if keys == "len":
|
||||
return len(results)
|
||||
else:
|
||||
return results[num][keys]
|
||||
220
boards/default/micropython_esp32s3/build/lib/map.json
Normal file
220
boards/default/micropython_esp32s3/build/lib/map.json
Normal file
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"camera": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"base64",
|
||||
"jpeg",
|
||||
"_camera",
|
||||
"jpeg",
|
||||
"machine",
|
||||
"mixgo_sant"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 1617,
|
||||
"__name__": "camera.py"
|
||||
},
|
||||
"ci1302x": {
|
||||
"__require__": [
|
||||
"ci130x"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 939,
|
||||
"__name__": "ci1302x.py"
|
||||
},
|
||||
"es8374": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 8066,
|
||||
"__name__": "es8374.py"
|
||||
},
|
||||
"esp_dl": {
|
||||
"__require__": [
|
||||
"espdl"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 417,
|
||||
"__name__": "esp_dl.py"
|
||||
},
|
||||
"mixgo_nova": {
|
||||
"__require__": [
|
||||
"ws2812",
|
||||
"machine",
|
||||
"time",
|
||||
"gc",
|
||||
"st7735",
|
||||
"math",
|
||||
"_boot",
|
||||
"mxc6655xa",
|
||||
"ltr553als",
|
||||
"ltr553als",
|
||||
"rc522",
|
||||
"mmc5603",
|
||||
"hp203x",
|
||||
"ahtx0",
|
||||
"shtc3",
|
||||
"machine"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 10416,
|
||||
"__name__": "mixgo_nova.py"
|
||||
},
|
||||
"mixgo_nova_voice": {
|
||||
"__require__": [
|
||||
"ustruct",
|
||||
"time",
|
||||
"music_spk",
|
||||
"es8374",
|
||||
"machine",
|
||||
"mixgo_nova",
|
||||
"urequests"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3444,
|
||||
"__name__": "mixgo_nova_voice.py"
|
||||
},
|
||||
"mixgo_sant": {
|
||||
"__require__": [
|
||||
"music",
|
||||
"ws2812x",
|
||||
"machine",
|
||||
"time",
|
||||
"gc",
|
||||
"st7789_cf",
|
||||
"math",
|
||||
"sant_bot",
|
||||
"sc7a20",
|
||||
"ltr553als",
|
||||
"shtc3",
|
||||
"mmc5603",
|
||||
"ci1302x"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 7403,
|
||||
"__name__": "mixgo_sant.py"
|
||||
},
|
||||
"mixgo_soar": {
|
||||
"__require__": [
|
||||
"ws2812",
|
||||
"machine",
|
||||
"time",
|
||||
"gc",
|
||||
"math",
|
||||
"st7789_bf",
|
||||
"soar_bot",
|
||||
"spl06_001",
|
||||
"qmi8658",
|
||||
"ltr553als",
|
||||
"mmc5603"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 6805,
|
||||
"__name__": "mixgo_soar.py"
|
||||
},
|
||||
"mixgo_soar_voice": {
|
||||
"__require__": [
|
||||
"ustruct",
|
||||
"time",
|
||||
"music_spk",
|
||||
"es8374",
|
||||
"machine",
|
||||
"mixgo_soar",
|
||||
"urequests"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3361,
|
||||
"__name__": "mixgo_soar_voice.py"
|
||||
},
|
||||
"music_spk": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"math",
|
||||
"struct"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 7981,
|
||||
"__name__": "music_spk.py"
|
||||
},
|
||||
"nova_g1": {
|
||||
"__require__": [
|
||||
"micropython",
|
||||
"mixgo_nova"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3860,
|
||||
"__name__": "nova_g1.py"
|
||||
},
|
||||
"sant_bot": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 5064,
|
||||
"__name__": "sant_bot.py"
|
||||
},
|
||||
"sant_g2": {
|
||||
"__require__": [
|
||||
"gc",
|
||||
"machine",
|
||||
"rc522",
|
||||
"cbr817"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 729,
|
||||
"__name__": "sant_g2.py"
|
||||
},
|
||||
"sant_gx": {
|
||||
"__require__": [
|
||||
"gc",
|
||||
"machine",
|
||||
"rc522",
|
||||
"cbr817"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 731,
|
||||
"__name__": "sant_gx.py"
|
||||
},
|
||||
"soar_bot": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 4048,
|
||||
"__name__": "soar_bot.py"
|
||||
},
|
||||
"st7789_bf": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"uframebuf",
|
||||
"machine",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 4455,
|
||||
"__name__": "st7789_bf.py"
|
||||
},
|
||||
"st7789_cf": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"uframebuf",
|
||||
"machine",
|
||||
"jpeg",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3953,
|
||||
"__name__": "st7789_cf.py"
|
||||
},
|
||||
"ws2812x": {
|
||||
"__require__": [
|
||||
"time"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 1957,
|
||||
"__name__": "ws2812x.py"
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,12 @@ Micropython library for the mixgo_zero Zi Onboard resources
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from ws2812 import NeoPixel
|
||||
from machine import *
|
||||
import time, gc, st7735, math
|
||||
import time
|
||||
import gc
|
||||
import st7735
|
||||
import math
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
@@ -24,210 +28,228 @@ onboard_i2c_scan = onboard_i2c.scan()
|
||||
|
||||
'''SPI-onboard'''
|
||||
try:
|
||||
import _boot
|
||||
onboard_spi = _boot.onboard_spi
|
||||
onboard_spi.init(baudrate=50000000)
|
||||
import _boot
|
||||
onboard_spi = _boot.onboard_spi
|
||||
onboard_spi.init(baudrate=50000000)
|
||||
except:
|
||||
onboard_spi = SPI(1, baudrate=50000000, polarity=0, phase=0)
|
||||
onboard_spi = SPI(1, baudrate=50000000, polarity=0, phase=0)
|
||||
|
||||
'''TFT/128*160'''
|
||||
onboard_tft = st7735.ST7735(onboard_spi, 160, 128, dc_pin=18, cs_pin=45, bl_pin=14, font_address=0x700000)
|
||||
onboard_tft = st7735.ST7735(
|
||||
onboard_spi, 160, 128, dc_pin=18, cs_pin=45, bl_pin=14, font_address=0x700000)
|
||||
|
||||
'''ACC-Sensor'''
|
||||
try :
|
||||
import mxc6655xa
|
||||
onboard_acc = mxc6655xa.MXC6655XA(onboard_i2c, front=True)
|
||||
try:
|
||||
import mxc6655xa
|
||||
onboard_acc = mxc6655xa.MXC6655XA(onboard_i2c, front=True)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MXC6655XA (ACC) or",e)
|
||||
print("Warning: Failed to communicate with MXC6655XA (ACC) or", e)
|
||||
|
||||
'''ALS_PS-Sensor *2'''
|
||||
try :
|
||||
import ltr553als
|
||||
onboard_als_l = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
try:
|
||||
import ltr553als
|
||||
onboard_als_l = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or",e)
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or", e)
|
||||
|
||||
try :
|
||||
import ltr553als
|
||||
onboard_als_r = ltr553als.LTR_553ALS(onboard_i2c_soft)
|
||||
try:
|
||||
import ltr553als
|
||||
onboard_als_r = ltr553als.LTR_553ALS(onboard_i2c_soft)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or",e)
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or", e)
|
||||
|
||||
'''BPS-Sensor'''
|
||||
if 0x76 in onboard_i2c_scan:
|
||||
try :
|
||||
import hp203x
|
||||
onboard_bps = hp203x.HP203X(onboard_i2c_soft)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with HP203X (BPS) or",e)
|
||||
try:
|
||||
import hp203x
|
||||
onboard_bps = hp203x.HP203X(onboard_i2c_soft)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with HP203X (BPS) or", e)
|
||||
|
||||
'''THS-Sensor'''
|
||||
if 0x38 in onboard_i2c_scan:
|
||||
try :
|
||||
import ahtx0
|
||||
onboard_ths = ahtx0.AHTx0(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with AHTx0 (THS) or",e)
|
||||
try:
|
||||
import ahtx0
|
||||
onboard_ths = ahtx0.AHTx0(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with AHTx0 (THS) or", e)
|
||||
if 0x70 in onboard_i2c_scan:
|
||||
try :
|
||||
import shtc3
|
||||
onboard_ths = shtc3.SHTC3(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or",e)
|
||||
try:
|
||||
import shtc3
|
||||
onboard_ths = shtc3.SHTC3(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or", e)
|
||||
|
||||
'''RFID-Sensor'''
|
||||
try :
|
||||
import rc522
|
||||
onboard_rfid = rc522.RC522(onboard_i2c)
|
||||
try:
|
||||
import rc522
|
||||
onboard_rfid = rc522.RC522(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with RC522 (RFID) or",e)
|
||||
print("Warning: Failed to communicate with RC522 (RFID) or", e)
|
||||
|
||||
'''MGS-Sensor'''
|
||||
try :
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(onboard_i2c)
|
||||
try:
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or",e)
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or", e)
|
||||
|
||||
'''2RGB_WS2812'''
|
||||
from ws2812 import NeoPixel
|
||||
'''2RGB_WS2812'''
|
||||
onboard_rgb = NeoPixel(Pin(38), 4)
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
|
||||
|
||||
class KEYSensor:
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(50):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(2)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
|
||||
def get_presses(self, delay = 1):
|
||||
last_time,presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(50):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(2)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
def get_presses(self, delay=1):
|
||||
last_time, presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def was_pressed(self):
|
||||
if(self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag :
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
|
||||
def was_pressed(self):
|
||||
if (self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler=handler, trigger=trigger)
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
'''1KEY_Button'''
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
|
||||
B1key = Button(0)
|
||||
B2key = KEYSensor(17,0)
|
||||
A1key = KEYSensor(17,2900)
|
||||
A2key = KEYSensor(17,2300)
|
||||
A3key = KEYSensor(17,1650)
|
||||
A4key = KEYSensor(17,850)
|
||||
B2key = KEYSensor(17, 0)
|
||||
A1key = KEYSensor(17, 2900)
|
||||
A2key = KEYSensor(17, 2300)
|
||||
A3key = KEYSensor(17, 1650)
|
||||
A4key = KEYSensor(17, 850)
|
||||
|
||||
'''2-TouchPad'''
|
||||
|
||||
|
||||
class Touch_Pad:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin]=object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
__species = {}
|
||||
__first_init = True
|
||||
|
||||
def __init__(self, pin, default=30000):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
from machine import TouchPad
|
||||
self._pin = TouchPad(Pin(pin))
|
||||
self.raw = self._pin.read()
|
||||
if self.raw >= default * 1.5:
|
||||
self.raw = default
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin] = object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
|
||||
def touch(self,value=None ):
|
||||
return self._pin.read() > value if value else self._pin.read()
|
||||
def __init__(self, pin, default=30000):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
from machine import TouchPad
|
||||
self._pin = TouchPad(Pin(pin))
|
||||
self.raw = self._pin.read()
|
||||
if self.raw >= default * 1.5:
|
||||
self.raw = default
|
||||
|
||||
def touch(self, value=None):
|
||||
return self._pin.read() > value if value else self._pin.read()
|
||||
|
||||
# Touch with function call
|
||||
|
||||
|
||||
def touched(pin, value=60000):
|
||||
return Touch_Pad(pin).touch(value)
|
||||
|
||||
#Touch with function call
|
||||
def touched(pin,value=60000):
|
||||
return Touch_Pad(pin).touch(value)
|
||||
|
||||
def touch_slide(pina, pinb):
|
||||
return ((Touch_Pad(pina).touch() - Touch_Pad(pina).raw) - (Touch_Pad(pinb).touch() - Touch_Pad(pinb).raw)) // 10
|
||||
return ((Touch_Pad(pina).touch() - Touch_Pad(pina).raw) - (Touch_Pad(pinb).touch() - Touch_Pad(pinb).raw)) // 10
|
||||
|
||||
|
||||
'''2LED-Tristate'''
|
||||
|
||||
|
||||
class LED_T:
|
||||
def __init__(self, pin, timer_id=3):
|
||||
self._pin = pin
|
||||
self._pwm = 0
|
||||
self._index_pwm = [0,0]
|
||||
Timer(timer_id, freq=2500, mode=Timer.PERIODIC, callback=self.tim_callback)
|
||||
def __init__(self, pin, timer_id=3):
|
||||
self._pin = pin
|
||||
self._pwm = 0
|
||||
self._index_pwm = [0, 0]
|
||||
Timer(timer_id, freq=2500, mode=Timer.PERIODIC, callback=self.tim_callback)
|
||||
|
||||
def _cutonoff(self,val):
|
||||
if val == 0:
|
||||
Pin(self._pin, Pin.IN)
|
||||
elif val == 1:
|
||||
Pin(self._pin, Pin.OUT).value(1)
|
||||
elif val == -1:
|
||||
Pin(self._pin, Pin.OUT).value(0)
|
||||
def _cutonoff(self, val):
|
||||
if val == 0:
|
||||
Pin(self._pin, Pin.IN)
|
||||
elif val == 1:
|
||||
Pin(self._pin, Pin.OUT).value(1)
|
||||
elif val == -1:
|
||||
Pin(self._pin, Pin.OUT).value(0)
|
||||
|
||||
def tim_callback(self,tim):
|
||||
if self._pwm <= 25:
|
||||
if self._pwm * 4 < self._index_pwm[0]:
|
||||
self._cutonoff(1)
|
||||
else:
|
||||
self._cutonoff(0)
|
||||
else:
|
||||
if (self._pwm - 26) * 4 < self._index_pwm[1]:
|
||||
self._cutonoff(-1)
|
||||
else:
|
||||
self._cutonoff(0)
|
||||
self._pwm = self._pwm + 1 if self._pwm <= 51 else 0
|
||||
def tim_callback(self, tim):
|
||||
if self._pwm <= 25:
|
||||
if self._pwm * 4 < self._index_pwm[0]:
|
||||
self._cutonoff(1)
|
||||
else:
|
||||
self._cutonoff(0)
|
||||
else:
|
||||
if (self._pwm - 26) * 4 < self._index_pwm[1]:
|
||||
self._cutonoff(-1)
|
||||
else:
|
||||
self._cutonoff(0)
|
||||
self._pwm = self._pwm + 1 if self._pwm <= 51 else 0
|
||||
|
||||
def setbrightness(self,index,val):
|
||||
if not 0 <= val <= 100:
|
||||
raise ValueError("Brightness must be in the range: 0~100%")
|
||||
self._index_pwm[index-1] = val
|
||||
|
||||
def getbrightness(self,index):
|
||||
return self._index_pwm[index-1]
|
||||
def setbrightness(self, index, val):
|
||||
if not 0 <= val <= 100:
|
||||
raise ValueError("Brightness must be in the range: 0~100%")
|
||||
self._index_pwm[index-1] = val
|
||||
|
||||
def setonoff(self,index,val):
|
||||
if(val == -1):
|
||||
if self._index_pwm[index-1] < 50:
|
||||
self._index_pwm[index-1] = 100
|
||||
else:
|
||||
self._index_pwm[index-1] = 0
|
||||
elif(val == 1):
|
||||
self._index_pwm[index-1] = 100
|
||||
elif(val == 0):
|
||||
self._index_pwm[index-1] = 0
|
||||
def getbrightness(self, index):
|
||||
return self._index_pwm[index-1]
|
||||
|
||||
def setonoff(self, index, val):
|
||||
if (val == -1):
|
||||
if self._index_pwm[index-1] < 50:
|
||||
self._index_pwm[index-1] = 100
|
||||
else:
|
||||
self._index_pwm[index-1] = 0
|
||||
elif (val == 1):
|
||||
self._index_pwm[index-1] = 100
|
||||
elif (val == 0):
|
||||
self._index_pwm[index-1] = 0
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self._index_pwm[index-1] > 0 else False
|
||||
|
||||
|
||||
'''2LED-Independent'''
|
||||
|
||||
def getonoff(self,index):
|
||||
return True if self._index_pwm[index-1] > 0 else False
|
||||
|
||||
'''2LED-Independent'''
|
||||
class LED_I:
|
||||
def __init__(self, pins=[]):
|
||||
self._pins = [PWM(Pin(pin), duty_u16=0) for pin in pins]
|
||||
@@ -244,44 +266,47 @@ class LED_I:
|
||||
|
||||
def setonoff(self, index, val):
|
||||
if val == -1:
|
||||
self.setbrightness(index, 100) if self.getbrightness(index) < 50 else self.setbrightness(index, 0)
|
||||
self.setbrightness(index, 100) if self.getbrightness(
|
||||
index) < 50 else self.setbrightness(index, 0)
|
||||
elif val == 1:
|
||||
self.setbrightness(index, 100)
|
||||
self.setbrightness(index, 100)
|
||||
elif val == 0:
|
||||
self.setbrightness(index, 0)
|
||||
self.setbrightness(index, 0)
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self.getbrightness(index) > 50 else False
|
||||
|
||||
onboard_led=LED_I(pins=[42, 13]) if version else LED_T(42, timer_id=3)
|
||||
|
||||
onboard_led = LED_I(pins=[42, 13]) if version else LED_T(42, timer_id=3)
|
||||
|
||||
|
||||
class Clock:
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): #定义时钟中心点和半径
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): # 定义时钟中心点和半径
|
||||
self.display = oled
|
||||
self.xc = x
|
||||
self.yc = y
|
||||
self.r = radius
|
||||
self.color= color
|
||||
self.color = color
|
||||
self.hour = 0
|
||||
self.min = 0
|
||||
self.sec = 0
|
||||
|
||||
def set_time(self, h, m, s): #设定时间
|
||||
def set_time(self, h, m, s): # 设定时间
|
||||
self.hour = h
|
||||
self.min = m
|
||||
self.sec = s
|
||||
|
||||
def set_rtctime(self): #设定时间
|
||||
def set_rtctime(self): # 设定时间
|
||||
t = rtc_clock.datetime()
|
||||
self.hour = t[4]
|
||||
self.min = t[5]
|
||||
self.sec = t[6]
|
||||
|
||||
def drawDial(self,color): #画钟表刻度
|
||||
def drawDial(self, color): # 画钟表刻度
|
||||
r_tic1 = self.r - 1
|
||||
r_tic2 = self.r - 2
|
||||
self.display.ellipse(self.xc, self.yc, self.r,self.r, self.color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, self.color,True)
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, self.color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, self.color, True)
|
||||
|
||||
for h in range(12):
|
||||
at = math.pi * 2.0 * h / 12.0
|
||||
@@ -291,28 +316,28 @@ class Clock:
|
||||
y2 = round(self.yc - r_tic2 * math.cos(at))
|
||||
self.display.line(x1, y1, x2, y2, color)
|
||||
|
||||
def drawHour(self,color): #画时针
|
||||
def drawHour(self, color): # 画时针
|
||||
r_hour = int(self.r / 10.0 * 5)
|
||||
ah = math.pi * 2.0 * ((self.hour % 12) + self.min / 60.0) / 12.0
|
||||
xh = int(self.xc + r_hour * math.sin(ah))
|
||||
yh = int(self.yc - r_hour * math.cos(ah))
|
||||
self.display.line(self.xc, self.yc, xh, yh, color)
|
||||
|
||||
def drawMin(self,color): #画分针
|
||||
def drawMin(self, color): # 画分针
|
||||
r_min = int(self.r / 10.0 * 7)
|
||||
am = math.pi * 2.0 * self.min / 60.0
|
||||
xm = round(self.xc + r_min * math.sin(am))
|
||||
ym = round(self.yc - r_min * math.cos(am))
|
||||
self.display.line(self.xc, self.yc, xm, ym, color)
|
||||
|
||||
def drawSec(self,color): #画秒针
|
||||
def drawSec(self, color): # 画秒针
|
||||
r_sec = int(self.r / 10.0 * 9)
|
||||
asec = math.pi * 2.0 * self.sec / 60.0
|
||||
xs = round(self.xc + r_sec * math.sin(asec))
|
||||
ys = round(self.yc - r_sec * math.cos(asec))
|
||||
self.display.line(self.xc, self.yc, xs, ys, color)
|
||||
|
||||
def draw_clock(self): #画完整钟表
|
||||
def draw_clock(self): # 画完整钟表
|
||||
self.drawDial(self.color)
|
||||
self.drawHour(self.color)
|
||||
self.drawMin(self.color)
|
||||
@@ -320,10 +345,11 @@ class Clock:
|
||||
self.display.show()
|
||||
self.clear(0)
|
||||
|
||||
def clear(self,color=0): #清除
|
||||
def clear(self, color=0): # 清除
|
||||
self.drawHour(color)
|
||||
self.drawMin(color)
|
||||
self.drawSec(color)
|
||||
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
|
||||
@@ -20,70 +20,81 @@ sample_rate = 22050
|
||||
ob_code = es8374.ES8374(onboard_i2c)
|
||||
time.sleep(0.2)
|
||||
|
||||
#ps 特殊改双全工i2s支持
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
# ps 特殊改双全工i2s支持
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
|
||||
spk_midi = music_spk.MIDI(ob_audio, sample_rate)
|
||||
|
||||
|
||||
def u2s(n):
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
|
||||
|
||||
def sound_level():
|
||||
buf = bytearray(100)
|
||||
values = []
|
||||
ob_audio.readinto(buf)
|
||||
for i in range(len(buf)//2):
|
||||
values.append(u2s(buf[i * 2] | buf[i * 2 + 1]<<8))
|
||||
return max(values) - min(values)
|
||||
buf = bytearray(100)
|
||||
values = []
|
||||
ob_audio.readinto(buf)
|
||||
for i in range(len(buf)//2):
|
||||
values.append(u2s(buf[i * 2] | buf[i * 2 + 1] << 8))
|
||||
return max(values) - min(values)
|
||||
|
||||
|
||||
def play_audio(path):
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
print("sample_rate", _rate)
|
||||
file.seek(44)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = file.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
print("sample_rate", _rate)
|
||||
file.seek(44)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = file.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
|
||||
def record_audio(path, seconds=5):
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate*4, ibuf=20000)
|
||||
file_size = sample_rate * 16 * 1 * seconds // 8
|
||||
wav_header = bytearray(44)
|
||||
wav_header[0:4] = b'RIFF'
|
||||
ustruct.pack_into('<I', wav_header, 4, file_size + 36)
|
||||
wav_header[8:40] = b'WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00"V\x00\x00D\xac\x00\x00\x02\x00\x10\x00data'
|
||||
ustruct.pack_into('<I', wav_header, 40, file_size)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate*4, ibuf=20000)
|
||||
file_size = sample_rate * 16 * 1 * seconds // 8
|
||||
wav_header = bytearray(44)
|
||||
wav_header[0:4] = b'RIFF'
|
||||
ustruct.pack_into('<I', wav_header, 4, file_size + 36)
|
||||
wav_header[8:40] = b'WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00"V\x00\x00D\xac\x00\x00\x02\x00\x10\x00data'
|
||||
ustruct.pack_into('<I', wav_header, 40, file_size)
|
||||
|
||||
buf = bytearray(512)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // 512):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
buf = bytearray(512)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // 512):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
def play_audio_url(url):
|
||||
import urequests
|
||||
response = urequests.get(url, stream=True)
|
||||
header = response.raw.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
#print("sample_rate", _rate)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = response.raw.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
response.close()
|
||||
import urequests
|
||||
response = urequests.get(url, stream=True)
|
||||
header = response.raw.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
# print("sample_rate", _rate)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = response.raw.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), dout=Pin(48), din=Pin(33), mck=Pin(
|
||||
35), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
response.close()
|
||||
|
||||
@@ -6,123 +6,135 @@ Micropython library for the mixgo_sant Onboard resources
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from music import MIDI
|
||||
from ws2812x import NeoPixel
|
||||
from machine import *
|
||||
import time, gc, st7789_cf, math
|
||||
import time
|
||||
import gc
|
||||
import st7789_cf
|
||||
import math
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
|
||||
'''I2C-onboard'''
|
||||
#inboard_i2c = I2C(0)
|
||||
# inboard_i2c = I2C(0)
|
||||
inboard_i2c = SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000)
|
||||
onboard_i2c = SoftI2C(scl=Pin(47), sda=Pin(38), freq=400000)
|
||||
|
||||
'''SPI-onboard'''
|
||||
onboard_spi = SPI(1, baudrate=80000000, polarity=1, phase=1)
|
||||
|
||||
'''BOT035-Sensor'''
|
||||
try :
|
||||
import sant_bot
|
||||
onboard_bot = sant_bot.BOT035(inboard_i2c)
|
||||
try:
|
||||
import sant_bot
|
||||
onboard_bot = sant_bot.BOT035(inboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with BOT035 (Coprocessor) or",e)
|
||||
print("Warning: Failed to communicate with BOT035 (Coprocessor) or", e)
|
||||
|
||||
'''TFT/240*240'''
|
||||
onboard_tft = st7789_cf.ST7789(reset=onboard_bot.tft_reset, backlight=onboard_bot.tft_brightness, font_address=0xE00000)
|
||||
onboard_tft = st7789_cf.ST7789(onboard_spi, 240, 240, dc_pin=45, reset=onboard_bot.tft_reset, backlight=onboard_bot.tft_brightness, font_address=0xF00000)
|
||||
|
||||
'''ACC-Sensor'''
|
||||
try :
|
||||
import sc7a20
|
||||
onboard_acc = sc7a20.SC7A20(inboard_i2c)
|
||||
try:
|
||||
import sc7a20
|
||||
onboard_acc = sc7a20.SC7A20(inboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with SC7A20H (ACC) or",e)
|
||||
print("Warning: Failed to communicate with SC7A20H (ACC) or", e)
|
||||
|
||||
'''ALS_PS-Sensor *2'''
|
||||
try :
|
||||
import ltr553als
|
||||
onboard_als_l = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
try:
|
||||
import ltr553als
|
||||
onboard_als_l = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS-L (ALS&PS) or",e)
|
||||
print("Warning: Failed to communicate with TR_553ALS-L (ALS&PS) or", e)
|
||||
|
||||
try :
|
||||
#import ltr553als
|
||||
onboard_als_r = ltr553als.LTR_553ALS(inboard_i2c)
|
||||
try:
|
||||
# import ltr553als
|
||||
onboard_als_r = ltr553als.LTR_553ALS(inboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS-R (ALS&PS) or",e)
|
||||
print("Warning: Failed to communicate with TR_553ALS-R (ALS&PS) or", e)
|
||||
|
||||
'''THS-Sensor'''
|
||||
try :
|
||||
import shtc3
|
||||
onboard_ths = shtc3.SHTC3(inboard_i2c)
|
||||
try:
|
||||
import shtc3
|
||||
onboard_ths = shtc3.SHTC3(inboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or",e)
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or", e)
|
||||
|
||||
'''MGS-Sensor'''
|
||||
try :
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(inboard_i2c)
|
||||
try:
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(inboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or",e)
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or", e)
|
||||
|
||||
'''ASR-Sensor'''
|
||||
try :
|
||||
from ci1302x import CI1302
|
||||
onboard_asr = CI1302(inboard_i2c, onboard_bot.asr_en)
|
||||
try:
|
||||
from ci1302x import CI1302
|
||||
onboard_asr = CI1302(inboard_i2c, onboard_bot.asr_en)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with CI130X (ASR) or",e)
|
||||
print("Warning: Failed to communicate with CI130X (ASR) or", e)
|
||||
|
||||
'''2RGB_WS2812'''
|
||||
from ws2812x import NeoPixel
|
||||
'''2RGB_WS2812'''
|
||||
onboard_rgb = NeoPixel(onboard_bot.rgb_sync, 4)
|
||||
|
||||
'''1Buzzer-Music'''
|
||||
from musicx import MIDI
|
||||
onboard_music = MIDI(46, pa_ctrl=onboard_bot.spk_en)
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
|
||||
|
||||
class KEYSensor:
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin))
|
||||
self.adc.atten(ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin))
|
||||
self.adc.atten(ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(25):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(5)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(25):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(5)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
|
||||
def get_presses(self, delay = 1):
|
||||
last_time,presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
def get_presses(self, delay=1):
|
||||
last_time, presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
|
||||
def was_pressed(self):
|
||||
if(self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag :
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def was_pressed(self):
|
||||
if (self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler=handler, trigger=trigger)
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
'''1KEY_Button'''
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
|
||||
B1key = Button(0)
|
||||
B2key = KEYSensor(17, 0)
|
||||
@@ -131,108 +143,117 @@ A2key = KEYSensor(17, 1100)
|
||||
A3key = KEYSensor(17, 550)
|
||||
A4key = KEYSensor(17, 2100)
|
||||
|
||||
'''2-LED'''
|
||||
'''2-LED'''
|
||||
|
||||
|
||||
class LED:
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
|
||||
def setbrightness(self, index, val):
|
||||
self._func(index, val)
|
||||
def setbrightness(self, index, val):
|
||||
self._func(index, val)
|
||||
|
||||
def getbrightness(self, index):
|
||||
return self._func(index)
|
||||
def getbrightness(self, index):
|
||||
return self._func(index)
|
||||
|
||||
def setonoff(self, index, val):
|
||||
if val == -1:
|
||||
self.setbrightness(index, 100) if self.getbrightness(index) < 50 else self.setbrightness(index, 0)
|
||||
elif val == 1:
|
||||
self.setbrightness(index, 100)
|
||||
elif val == 0:
|
||||
self.setbrightness(index, 0)
|
||||
def setonoff(self, index, val):
|
||||
if val == -1:
|
||||
self.setbrightness(index, 100) if self.getbrightness(
|
||||
index) < 50 else self.setbrightness(index, 0)
|
||||
elif val == 1:
|
||||
self.setbrightness(index, 100)
|
||||
elif val == 0:
|
||||
self.setbrightness(index, 0)
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self.getbrightness(index) > 50 else False
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self.getbrightness(index) > 50 else False
|
||||
|
||||
onboard_led = LED(onboard_bot.led_pwm)
|
||||
|
||||
|
||||
class Voice_Energy:
|
||||
def read(self, samples=10):
|
||||
values = []
|
||||
for _ in range(samples):
|
||||
values.append(int.from_bytes(onboard_asr._rreg(0x08, 3)[:2], 'little')) #在语音识别里获取
|
||||
return sorted(values)[samples // 2]
|
||||
def read(self, samples=10):
|
||||
values = []
|
||||
for _ in range(samples):
|
||||
values.append(int.from_bytes(onboard_asr._rreg(
|
||||
0x08, 3)[:2], 'little')) # 在语音识别里获取
|
||||
return sorted(values)[samples // 2]
|
||||
|
||||
|
||||
onboard_sound = Voice_Energy()
|
||||
|
||||
|
||||
class Clock:
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): #定义时钟中心点和半径
|
||||
self.display = oled
|
||||
self.xc = x
|
||||
self.yc = y
|
||||
self.r = radius
|
||||
self.color= color
|
||||
self.hour = 0
|
||||
self.min = 0
|
||||
self.sec = 0
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): # 定义时钟中心点和半径
|
||||
self.display = oled
|
||||
self.xc = x
|
||||
self.yc = y
|
||||
self.r = radius
|
||||
self.color = color
|
||||
self.hour = 0
|
||||
self.min = 0
|
||||
self.sec = 0
|
||||
|
||||
def set_time(self, h, m, s): #设定时间
|
||||
self.hour = h
|
||||
self.min = m
|
||||
self.sec = s
|
||||
def set_time(self, h, m, s): # 设定时间
|
||||
self.hour = h
|
||||
self.min = m
|
||||
self.sec = s
|
||||
|
||||
def set_rtctime(self): #设定时间
|
||||
t = rtc_clock.datetime()
|
||||
self.hour = t[4]
|
||||
self.min = t[5]
|
||||
self.sec = t[6]
|
||||
def set_rtctime(self): # 设定时间
|
||||
t = rtc_clock.datetime()
|
||||
self.hour = t[4]
|
||||
self.min = t[5]
|
||||
self.sec = t[6]
|
||||
|
||||
def drawDial(self,color): #画钟表刻度
|
||||
r_tic1 = self.r - 1
|
||||
r_tic2 = self.r - 2
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, color,True)
|
||||
def drawDial(self, color): # 画钟表刻度
|
||||
r_tic1 = self.r - 1
|
||||
r_tic2 = self.r - 2
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, color, True)
|
||||
|
||||
for h in range(12):
|
||||
at = math.pi * 2.0 * h / 12.0
|
||||
x1 = round(self.xc + r_tic1 * math.sin(at))
|
||||
x2 = round(self.xc + r_tic2 * math.sin(at))
|
||||
y1 = round(self.yc - r_tic1 * math.cos(at))
|
||||
y2 = round(self.yc - r_tic2 * math.cos(at))
|
||||
self.display.line(x1, y1, x2, y2, color)
|
||||
for h in range(12):
|
||||
at = math.pi * 2.0 * h / 12.0
|
||||
x1 = round(self.xc + r_tic1 * math.sin(at))
|
||||
x2 = round(self.xc + r_tic2 * math.sin(at))
|
||||
y1 = round(self.yc - r_tic1 * math.cos(at))
|
||||
y2 = round(self.yc - r_tic2 * math.cos(at))
|
||||
self.display.line(x1, y1, x2, y2, color)
|
||||
|
||||
def drawHour(self,color): #画时针
|
||||
r_hour = int(self.r / 10.0 * 5)
|
||||
ah = math.pi * 2.0 * ((self.hour % 12) + self.min / 60.0) / 12.0
|
||||
xh = int(self.xc + r_hour * math.sin(ah))
|
||||
yh = int(self.yc - r_hour * math.cos(ah))
|
||||
self.display.line(self.xc, self.yc, xh, yh, color)
|
||||
def drawHour(self, color): # 画时针
|
||||
r_hour = int(self.r / 10.0 * 5)
|
||||
ah = math.pi * 2.0 * ((self.hour % 12) + self.min / 60.0) / 12.0
|
||||
xh = int(self.xc + r_hour * math.sin(ah))
|
||||
yh = int(self.yc - r_hour * math.cos(ah))
|
||||
self.display.line(self.xc, self.yc, xh, yh, color)
|
||||
|
||||
def drawMin(self,color): #画分针
|
||||
r_min = int(self.r / 10.0 * 7)
|
||||
am = math.pi * 2.0 * self.min / 60.0
|
||||
xm = round(self.xc + r_min * math.sin(am))
|
||||
ym = round(self.yc - r_min * math.cos(am))
|
||||
self.display.line(self.xc, self.yc, xm, ym, color)
|
||||
def drawMin(self, color): # 画分针
|
||||
r_min = int(self.r / 10.0 * 7)
|
||||
am = math.pi * 2.0 * self.min / 60.0
|
||||
xm = round(self.xc + r_min * math.sin(am))
|
||||
ym = round(self.yc - r_min * math.cos(am))
|
||||
self.display.line(self.xc, self.yc, xm, ym, color)
|
||||
|
||||
def drawSec(self,color): #画秒针
|
||||
r_sec = int(self.r / 10.0 * 9)
|
||||
asec = math.pi * 2.0 * self.sec / 60.0
|
||||
xs = round(self.xc + r_sec * math.sin(asec))
|
||||
ys = round(self.yc - r_sec * math.cos(asec))
|
||||
self.display.line(self.xc, self.yc, xs, ys, color)
|
||||
def drawSec(self, color): # 画秒针
|
||||
r_sec = int(self.r / 10.0 * 9)
|
||||
asec = math.pi * 2.0 * self.sec / 60.0
|
||||
xs = round(self.xc + r_sec * math.sin(asec))
|
||||
ys = round(self.yc - r_sec * math.cos(asec))
|
||||
self.display.line(self.xc, self.yc, xs, ys, color)
|
||||
|
||||
def draw_clock(self, bg_color=0): #画完整钟表
|
||||
self.drawDial(self.color)
|
||||
self.drawHour(self.color)
|
||||
self.drawMin(self.color)
|
||||
self.drawSec(self.color)
|
||||
self.display.show()
|
||||
self.drawHour(bg_color)
|
||||
self.drawMin(bg_color)
|
||||
self.drawSec(bg_color)
|
||||
def draw_clock(self, bg_color=0): # 画完整钟表
|
||||
self.drawDial(self.color)
|
||||
self.drawHour(self.color)
|
||||
self.drawMin(self.color)
|
||||
self.drawSec(self.color)
|
||||
self.display.show()
|
||||
self.drawHour(bg_color)
|
||||
self.drawMin(bg_color)
|
||||
self.drawSec(bg_color)
|
||||
|
||||
def clear(self, color=0): # 清除
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color, True)
|
||||
|
||||
def clear(self, color=0): #清除
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color, True)
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
|
||||
233
boards/default/micropython_esp32s3/build/lib/mixgo_soar.py
Normal file
233
boards/default/micropython_esp32s3/build/lib/mixgo_soar.py
Normal file
@@ -0,0 +1,233 @@
|
||||
"""
|
||||
mixgo_soar onboard resources
|
||||
|
||||
Micropython library for the mixgo_soar onboard resources
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from ws2812 import NeoPixel
|
||||
from machine import *
|
||||
import time
|
||||
import gc
|
||||
import math
|
||||
import st7789_bf
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
|
||||
'''I2C-onboard'''
|
||||
# onboard_i2c = I2C(0)
|
||||
onboard_i2c = SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000)
|
||||
|
||||
'''SPI-onboard'''
|
||||
onboard_spi = SPI(1, baudrate=80000000, polarity=0, phase=0)
|
||||
|
||||
'''BOT035-Sensor'''
|
||||
try:
|
||||
import soar_bot
|
||||
onboard_bot = soar_bot.BOT035(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with BOT035 (Coprocessor) or", e)
|
||||
|
||||
'''BPS-Sensor'''
|
||||
try:
|
||||
import spl06_001
|
||||
onboard_bps = spl06_001.SPL06(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with SPL06-001 (BPS) or", e)
|
||||
|
||||
'''IMU-Sensor'''
|
||||
try:
|
||||
import qmi8658
|
||||
onboard_imu = qmi8658.QMI8658(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with QMI8658 (IMU) or", e)
|
||||
|
||||
'''ALS_PS-Sensor'''
|
||||
try:
|
||||
import ltr553als
|
||||
onboard_als = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or", e)
|
||||
|
||||
'''MGS-Sensor'''
|
||||
try:
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or", e)
|
||||
|
||||
'''TFT/240*240'''
|
||||
onboard_tft = st7789_bf.ST7789(onboard_spi, 240, 240, dc_pin=46, cs_pin=45, bl_pin=onboard_bot.tft_brightness, brightness=0, font_address=0x700000)
|
||||
|
||||
'''2RGB_WS2812'''
|
||||
onboard_rgb = NeoPixel(Pin(40), 4)
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
|
||||
|
||||
class KEYSensor:
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(50):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(2)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
|
||||
def get_presses(self, delay=1):
|
||||
last_time, presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
|
||||
def was_pressed(self):
|
||||
if (self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler=handler, trigger=trigger)
|
||||
|
||||
|
||||
'''1KEY_Button'''
|
||||
|
||||
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
|
||||
B1key = Button(0)
|
||||
B2key = KEYSensor(17, 0)
|
||||
A1key = KEYSensor(17, 2300)
|
||||
A2key = KEYSensor(17, 1600)
|
||||
A3key = KEYSensor(17, 800)
|
||||
A4key = KEYSensor(17, 2900)
|
||||
|
||||
'''2LED-Independent'''
|
||||
|
||||
|
||||
class LED:
|
||||
def __init__(self, pins=[]):
|
||||
self._pins = [PWM(Pin(pin), duty_u16=0) for pin in pins]
|
||||
self._brightness = [0 for _ in range(len(self._pins))]
|
||||
|
||||
def setbrightness(self, index, val):
|
||||
if not 0 <= val <= 100:
|
||||
raise ValueError("Brightness must be in the range: 0-100%")
|
||||
self._brightness[index - 1] = val
|
||||
self._pins[index - 1].duty_u16(val * 65535 // 100)
|
||||
|
||||
def getbrightness(self, index):
|
||||
return self._brightness[index - 1]
|
||||
|
||||
def setonoff(self, index, val):
|
||||
if val == -1:
|
||||
self.setbrightness(index, 100) if self.getbrightness(
|
||||
index) < 50 else self.setbrightness(index, 0)
|
||||
elif val == 1:
|
||||
self.setbrightness(index, 100)
|
||||
elif val == 0:
|
||||
self.setbrightness(index, 0)
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self.getbrightness(index) > 50 else False
|
||||
|
||||
|
||||
onboard_led = LED([38, 39])
|
||||
|
||||
|
||||
class Clock:
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): # 定义时钟中心点和半径
|
||||
self.display = oled
|
||||
self.xc = x
|
||||
self.yc = y
|
||||
self.r = radius
|
||||
self.color = color
|
||||
self.hour = 0
|
||||
self.min = 0
|
||||
self.sec = 0
|
||||
|
||||
def set_time(self, h, m, s): # 设定时间
|
||||
self.hour = h
|
||||
self.min = m
|
||||
self.sec = s
|
||||
|
||||
def set_rtctime(self): # 设定时间
|
||||
t = rtc_clock.datetime()
|
||||
self.hour = t[4]
|
||||
self.min = t[5]
|
||||
self.sec = t[6]
|
||||
|
||||
def drawDial(self, color): # 画钟表刻度
|
||||
r_tic1 = self.r - 1
|
||||
r_tic2 = self.r - 2
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, color, True)
|
||||
|
||||
for h in range(12):
|
||||
at = math.pi * 2.0 * h / 12.0
|
||||
x1 = round(self.xc + r_tic1 * math.sin(at))
|
||||
x2 = round(self.xc + r_tic2 * math.sin(at))
|
||||
y1 = round(self.yc - r_tic1 * math.cos(at))
|
||||
y2 = round(self.yc - r_tic2 * math.cos(at))
|
||||
self.display.line(x1, y1, x2, y2, color)
|
||||
|
||||
def drawHour(self, color): # 画时针
|
||||
r_hour = int(self.r / 10.0 * 5)
|
||||
ah = math.pi * 2.0 * ((self.hour % 12) + self.min / 60.0) / 12.0
|
||||
xh = int(self.xc + r_hour * math.sin(ah))
|
||||
yh = int(self.yc - r_hour * math.cos(ah))
|
||||
self.display.line(self.xc, self.yc, xh, yh, color)
|
||||
|
||||
def drawMin(self, color): # 画分针
|
||||
r_min = int(self.r / 10.0 * 7)
|
||||
am = math.pi * 2.0 * self.min / 60.0
|
||||
xm = round(self.xc + r_min * math.sin(am))
|
||||
ym = round(self.yc - r_min * math.cos(am))
|
||||
self.display.line(self.xc, self.yc, xm, ym, color)
|
||||
|
||||
def drawSec(self, color): # 画秒针
|
||||
r_sec = int(self.r / 10.0 * 9)
|
||||
asec = math.pi * 2.0 * self.sec / 60.0
|
||||
xs = round(self.xc + r_sec * math.sin(asec))
|
||||
ys = round(self.yc - r_sec * math.cos(asec))
|
||||
self.display.line(self.xc, self.yc, xs, ys, color)
|
||||
|
||||
def draw_clock(self, bg_color=0): # 画完整钟表
|
||||
self.drawDial(self.color)
|
||||
self.drawHour(self.color)
|
||||
self.drawMin(self.color)
|
||||
self.drawSec(self.color)
|
||||
self.display.show()
|
||||
self.drawHour(bg_color)
|
||||
self.drawMin(bg_color)
|
||||
self.drawSec(bg_color)
|
||||
|
||||
def clear(self, color=0): # 清除
|
||||
self.display.ellipse(self.xc, self.yc, self.r, self.r, color, True)
|
||||
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
onboard_tft.set_brightness(0.6)
|
||||
@@ -0,0 +1,97 @@
|
||||
"""
|
||||
Soar Voice Onboard resources
|
||||
|
||||
Micropython library for the Soar Onboard resources
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import ustruct
|
||||
import time
|
||||
import music_spk
|
||||
import es8374
|
||||
|
||||
from machine import Pin, I2S
|
||||
from mixgo_soar import onboard_i2c
|
||||
|
||||
sample_rate = 22050
|
||||
ob_code = es8374.ES8374(onboard_i2c)
|
||||
time.sleep(0.2)
|
||||
|
||||
# ps 特殊改双全工i2s支持
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
|
||||
spk_midi = music_spk.MIDI(ob_audio, sample_rate)
|
||||
|
||||
|
||||
def u2s(n):
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
|
||||
|
||||
def sound_level():
|
||||
buf = bytearray(100)
|
||||
values = []
|
||||
ob_audio.readinto(buf)
|
||||
for i in range(len(buf)//2):
|
||||
values.append(u2s(buf[i * 2] | buf[i * 2 + 1] << 8))
|
||||
return max(values) - min(values)
|
||||
|
||||
|
||||
def play_audio(path):
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
print("sample_rate", _rate)
|
||||
file.seek(44)
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = file.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
|
||||
def record_audio(path, seconds=5):
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate*4, ibuf=20000)
|
||||
file_size = sample_rate * 16 * 1 * seconds // 8
|
||||
wav_header = bytearray(44)
|
||||
wav_header[0:4] = b'RIFF'
|
||||
ustruct.pack_into('<I', wav_header, 4, file_size + 36)
|
||||
wav_header[8:40] = b'WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00"V\x00\x00D\xac\x00\x00\x02\x00\x10\x00data'
|
||||
ustruct.pack_into('<I', wav_header, 40, file_size)
|
||||
|
||||
buf = bytearray(512)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // 512):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
|
||||
def play_audio_url(url):
|
||||
import urequests
|
||||
response = urequests.get(url, stream=True)
|
||||
header = response.raw.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
# print("sample_rate", _rate)
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = response.raw.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(37), din=Pin(36), ws=Pin(35), dout=Pin(34), mck=Pin(
|
||||
33), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
response.close()
|
||||
@@ -1,283 +0,0 @@
|
||||
"""
|
||||
mixgo_zero Onboard resources
|
||||
|
||||
Micropython library for the mixgo_zero Onboard resources
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20240110
|
||||
#S3定时器ID(-1,0,1,2,3)
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from machine import *
|
||||
import time, gc, st7789_bf, math
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
|
||||
'''I2C-onboard'''
|
||||
#onboard_i2c = I2C(0)
|
||||
onboard_i2c = SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000)
|
||||
onboard_i2c_1 = SoftI2C(scl=Pin(47), sda=Pin(21), freq=400000)
|
||||
|
||||
'''SPI-onboard'''
|
||||
try:
|
||||
import _boot
|
||||
onboard_spi = _boot.onboard_spi
|
||||
onboard_spi.init(baudrate=50000000)
|
||||
except:
|
||||
onboard_spi = SPI(1, baudrate=50000000, polarity=0, phase=0)
|
||||
|
||||
'''TFT/320*240'''
|
||||
onboard_tft = st7789_bf.ST7789(onboard_spi, 320, 240, dc_pin=18, cs_pin=45, bl_pin=46, font_address=0xE00000)
|
||||
|
||||
'''ACC-Sensor'''
|
||||
try :
|
||||
import mxc6655xa
|
||||
onboard_acc = mxc6655xa.MXC6655XA(onboard_i2c, front=True)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MXC6655XA (ACC) or",e)
|
||||
|
||||
'''ALS_PS-Sensor *2'''
|
||||
try :
|
||||
import ltr553als
|
||||
onboard_als_l = ltr553als.LTR_553ALS(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or",e)
|
||||
|
||||
try :
|
||||
import ltr553als
|
||||
onboard_als_r = ltr553als.LTR_553ALS(onboard_i2c_1)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with TR_553ALS (ALS&PS) or",e)
|
||||
|
||||
'''THS-Sensor'''
|
||||
try :
|
||||
import shtc3
|
||||
onboard_ths = shtc3.SHTC3(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or",e)
|
||||
|
||||
'''RFID-Sensor'''
|
||||
try :
|
||||
import rc522
|
||||
onboard_rfid = rc522.RC522(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with RC522 (RFID) or",e)
|
||||
|
||||
'''MGS-Sensor'''
|
||||
try :
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with MMC5603 (MGS) or",e)
|
||||
|
||||
'''BPS-Sensor'''
|
||||
try :
|
||||
import spl06_001
|
||||
onboard_bps = spl06_001.SPL06(onboard_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with SPL06-001 (BPS) or",e)
|
||||
|
||||
'''2RGB_WS2812'''
|
||||
from ws2812 import NeoPixel
|
||||
onboard_rgb = NeoPixel(Pin(0), 6, multiplex=True, leds=2)
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
class KEYSensor:
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_0DB)
|
||||
self.range = range
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
values = []
|
||||
for _ in range(50):
|
||||
values.append(self.adc.read())
|
||||
time.sleep_us(2)
|
||||
return (self.range-200) < min(values) < (self.range+200)
|
||||
|
||||
def get_presses(self, delay = 1):
|
||||
last_time,presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep_ms(50)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def is_pressed(self):
|
||||
return self._value()
|
||||
|
||||
def was_pressed(self):
|
||||
if(self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag :
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
'''1KEY_Button'''
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
B1key = Button(0)
|
||||
B2key = KEYSensor(13,0)
|
||||
A1key = KEYSensor(13,2900)
|
||||
A2key = KEYSensor(13,2300)
|
||||
A3key = KEYSensor(13,1650)
|
||||
A4key = KEYSensor(13,850)
|
||||
|
||||
'''2-TouchPad'''
|
||||
class Touch_Pad:
|
||||
__species = {}
|
||||
__first_init = True
|
||||
def __new__(cls, pin, *args, **kwargs):
|
||||
if pin not in cls.__species.keys():
|
||||
cls.__first_init = True
|
||||
cls.__species[pin]=object.__new__(cls)
|
||||
return cls.__species[pin]
|
||||
|
||||
def __init__(self, pin, default=30000):
|
||||
if self.__first_init:
|
||||
self.__first_init = False
|
||||
from machine import TouchPad
|
||||
self._pin = TouchPad(Pin(pin))
|
||||
self.raw = self._pin.read()
|
||||
if self.raw >= default * 1.5:
|
||||
self.raw = default
|
||||
|
||||
def touch(self,value=None ):
|
||||
return self._pin.read() > value if value else self._pin.read()
|
||||
|
||||
#Touch with function call
|
||||
def touched(pin,value=60000):
|
||||
return Touch_Pad(pin).touch(value)
|
||||
|
||||
def touch_slide(pina, pinb):
|
||||
return ((Touch_Pad(pina).touch() - Touch_Pad(pina).raw) - (Touch_Pad(pinb).touch() - Touch_Pad(pinb).raw)) // 10
|
||||
|
||||
'''2LED-WS2812'''
|
||||
class LED:
|
||||
def __init__(self, rgb, num=2, color=3):
|
||||
self._rgb = rgb
|
||||
self._col = [color] * num
|
||||
self._color = ((0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 1))
|
||||
|
||||
def setbrightness(self, index, value):
|
||||
self._rgb.led_set(index - 1, (value if self._color[self._col[index-1]][0] else 0,
|
||||
value if self._color[self._col[index-1]][1] else 0,
|
||||
value if self._color[self._col[index-1]][2] else 0))
|
||||
self._rgb.write()
|
||||
|
||||
def getbrightness(self, index):
|
||||
color = self._rgb.led_get(index - 1)
|
||||
return color[0] | color[1] | color[2]
|
||||
|
||||
def setonoff(self, index, value):
|
||||
if value == -1:
|
||||
if self.getbrightness(index) < 50:
|
||||
self.setbrightness(index, 100)
|
||||
else:
|
||||
self.setbrightness(index, 0)
|
||||
elif value == 1:
|
||||
self.setbrightness(index, 100)
|
||||
elif value == 0:
|
||||
self.setbrightness(index, 0)
|
||||
|
||||
def getonoff(self, index):
|
||||
return True if self.getbrightness(index) > 50 else False
|
||||
|
||||
def setcolor(self, index, color):
|
||||
self._col[index-1] = color
|
||||
|
||||
def getcolor(self, index):
|
||||
return self._col[index-1]
|
||||
|
||||
onboard_led = LED(onboard_rgb)
|
||||
|
||||
class Clock:
|
||||
def __init__(self, x, y, radius, color, oled=onboard_tft): #定义时钟中心点和半径
|
||||
self.display = oled
|
||||
self.xc = x
|
||||
self.yc = y
|
||||
self.r = radius
|
||||
self.color= color
|
||||
self.hour = 0
|
||||
self.min = 0
|
||||
self.sec = 0
|
||||
|
||||
def set_time(self, h, m, s): #设定时间
|
||||
self.hour = h
|
||||
self.min = m
|
||||
self.sec = s
|
||||
|
||||
def set_rtctime(self): #设定时间
|
||||
t = rtc_clock.datetime()
|
||||
self.hour = t[4]
|
||||
self.min = t[5]
|
||||
self.sec = t[6]
|
||||
|
||||
def drawDial(self,color): #画钟表刻度
|
||||
r_tic1 = self.r - 1
|
||||
r_tic2 = self.r - 2
|
||||
|
||||
self.display.ellipse(self.xc, self.yc, self.r,self.r, self.color)
|
||||
self.display.ellipse(self.xc, self.yc, 2, 2, self.color,True)
|
||||
|
||||
for h in range(12):
|
||||
at = math.pi * 2.0 * h / 12.0
|
||||
x1 = round(self.xc + r_tic1 * math.sin(at))
|
||||
x2 = round(self.xc + r_tic2 * math.sin(at))
|
||||
y1 = round(self.yc - r_tic1 * math.cos(at))
|
||||
y2 = round(self.yc - r_tic2 * math.cos(at))
|
||||
self.display.line(x1, y1, x2, y2, color)
|
||||
|
||||
def drawHour(self,color): #画时针
|
||||
|
||||
r_hour = int(self.r / 10.0 * 5)
|
||||
ah = math.pi * 2.0 * ((self.hour % 12) + self.min / 60.0) / 12.0
|
||||
xh = int(self.xc + r_hour * math.sin(ah))
|
||||
yh = int(self.yc - r_hour * math.cos(ah))
|
||||
self.display.line(self.xc, self.yc, xh, yh, color)
|
||||
|
||||
def drawMin(self,color): #画分针
|
||||
|
||||
r_min = int(self.r / 10.0 * 7)
|
||||
am = math.pi * 2.0 * self.min / 60.0
|
||||
|
||||
xm = round(self.xc + r_min * math.sin(am))
|
||||
ym = round(self.yc - r_min * math.cos(am))
|
||||
self.display.line(self.xc, self.yc, xm, ym, color)
|
||||
|
||||
def drawSec(self,color): #画秒针
|
||||
|
||||
r_sec = int(self.r / 10.0 * 9)
|
||||
asec = math.pi * 2.0 * self.sec / 60.0
|
||||
xs = round(self.xc + r_sec * math.sin(asec))
|
||||
ys = round(self.yc - r_sec * math.cos(asec))
|
||||
self.display.line(self.xc, self.yc, xs, ys, color)
|
||||
|
||||
def draw_clock(self): #画完整钟表
|
||||
self.drawDial(self.color)
|
||||
self.drawHour(self.color)
|
||||
self.drawMin(self.color)
|
||||
self.drawSec(self.color)
|
||||
self.display.show()
|
||||
|
||||
def clear(self,color=0): #清除
|
||||
self.drawHour(color)
|
||||
self.drawMin(color)
|
||||
self.drawSec(color)
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
@@ -1,88 +0,0 @@
|
||||
"""
|
||||
mixgo_zero Zi Voice Onboard resources
|
||||
|
||||
Micropython library for the mixgo_zero Zi Onboard resources
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20230818
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
import ustruct
|
||||
import time
|
||||
import music_spk
|
||||
import es8374
|
||||
from machine import Pin, I2S
|
||||
from mixgo_zero import onboard_i2c
|
||||
|
||||
sample_rate = 22050
|
||||
ob_code = es8374.ES8374(onboard_i2c)
|
||||
time.sleep(0.2)
|
||||
|
||||
#ps 特殊改双全工i2s支持
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
|
||||
spk_midi = music_spk.MIDI(ob_audio, sample_rate)
|
||||
|
||||
def u2s(n):
|
||||
return n if n < (1 << 15) else n - (1 << 16)
|
||||
|
||||
def sound_level():
|
||||
buf = bytearray(100)
|
||||
values = []
|
||||
ob_audio.readinto(buf)
|
||||
for i in range(len(buf)//2):
|
||||
values.append(u2s(buf[i * 2] | buf[i * 2 + 1]<<8))
|
||||
return max(values) - min(values)
|
||||
|
||||
def play_audio(path):
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
print("sample_rate", _rate)
|
||||
file.seek(44)
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = file.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
def record_audio(path, seconds=5):
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate*4, ibuf=20000)
|
||||
file_size = sample_rate * 16 * 1 * seconds // 8
|
||||
wav_header = bytearray(44)
|
||||
wav_header[0:4] = b'RIFF'
|
||||
ustruct.pack_into('<I', wav_header, 4, file_size + 36)
|
||||
wav_header[8:40] = b'WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00"V\x00\x00D\xac\x00\x00\x02\x00\x10\x00data'
|
||||
ustruct.pack_into('<I', wav_header, 40, file_size)
|
||||
|
||||
buf = bytearray(512)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // 512):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
file.close()
|
||||
|
||||
def play_audio_url(url):
|
||||
import urequests
|
||||
response = urequests.get(url, stream=True)
|
||||
header = response.raw.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
#print("sample_rate", _rate)
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=_rate, ibuf=20000)
|
||||
while True:
|
||||
block = response.raw.read(1024)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
ob_audio = I2S(0, sck=Pin(39), ws=Pin(41), dout=Pin(42), din=Pin(40), mck=Pin(38), mode=I2S.RTX, bits=16, format=I2S.MONO, rate=sample_rate, ibuf=20000)
|
||||
response.close()
|
||||
@@ -16,142 +16,155 @@ import math
|
||||
import struct
|
||||
|
||||
normal_tone = {
|
||||
'A1': 55, 'B1': 62, 'C1': 33, 'D1': 37, 'E1': 41, 'F1': 44, 'G1': 49,
|
||||
'A2': 110, 'B2': 123, 'C2': 65, 'D2': 73, 'E2': 82, 'F2': 87, 'G2': 98,
|
||||
'A3': 220, 'B3': 247, 'C3': 131, 'D3': 147, 'E3': 165, 'F3': 175, 'G3': 196,
|
||||
'A4': 440, 'B4': 494, 'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392,
|
||||
'A5': 880, 'B5': 988, 'C5': 523, 'D5': 587, 'E5': 659, 'F5': 698, 'G5': 784,
|
||||
'A6': 1760, 'B6': 1976, 'C6': 1047, 'D6': 1175, 'E6': 1319, 'F6': 1397, 'G6': 1568,
|
||||
'A7': 3520, 'B7': 3951, 'C7': 2093, 'D7': 2349, 'E7': 2637, 'F7': 2794, 'G7': 3135,
|
||||
'A8': 7040, 'B8': 7902, 'C8': 4186, 'D8': 4699, 'E8': 5274, 'F8': 5588, 'G8': 6271,
|
||||
'A9': 14080, 'B9': 15804 }
|
||||
'A1': 55, 'B1': 62, 'C1': 33, 'D1': 37, 'E1': 41, 'F1': 44, 'G1': 49,
|
||||
'A2': 110, 'B2': 123, 'C2': 65, 'D2': 73, 'E2': 82, 'F2': 87, 'G2': 98,
|
||||
'A3': 220, 'B3': 247, 'C3': 131, 'D3': 147, 'E3': 165, 'F3': 175, 'G3': 196,
|
||||
'A4': 440, 'B4': 494, 'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392,
|
||||
'A5': 880, 'B5': 988, 'C5': 523, 'D5': 587, 'E5': 659, 'F5': 698, 'G5': 784,
|
||||
'A6': 1760, 'B6': 1976, 'C6': 1047, 'D6': 1175, 'E6': 1319, 'F6': 1397, 'G6': 1568,
|
||||
'A7': 3520, 'B7': 3951, 'C7': 2093, 'D7': 2349, 'E7': 2637, 'F7': 2794, 'G7': 3135,
|
||||
'A8': 7040, 'B8': 7902, 'C8': 4186, 'D8': 4699, 'E8': 5274, 'F8': 5588, 'G8': 6271,
|
||||
'A9': 14080, 'B9': 15804}
|
||||
|
||||
Letter = 'ABCDEFG#R'
|
||||
|
||||
|
||||
class MIDI():
|
||||
def __init__(self, i2s_bus, rate=22050):
|
||||
self.reset()
|
||||
self._rate = rate
|
||||
self.i2s_bus = i2s_bus
|
||||
def __init__(self, i2s_bus, rate=22050):
|
||||
self.reset()
|
||||
self._rate = rate
|
||||
self.i2s_bus = i2s_bus
|
||||
|
||||
def _wave(self, frequency):
|
||||
_period = self._rate // frequency
|
||||
_samples = bytearray()
|
||||
for i in range(_period):
|
||||
sample = 32768 + int((32767) * math.sin(2 * math.pi * i / _period))
|
||||
_samples.extend(struct.pack("<h", sample))
|
||||
return bytes(_samples)
|
||||
def _wave(self, frequency):
|
||||
_period = self._rate // frequency
|
||||
_samples = bytearray()
|
||||
for i in range(_period):
|
||||
sample = 32768 + int((32767) * math.sin(2 * math.pi * i / _period))
|
||||
_samples.extend(struct.pack("<h", sample))
|
||||
return bytes(_samples)
|
||||
|
||||
def _tone(self, frequency, duration_ms=1000):
|
||||
_wave = self._wave(frequency)
|
||||
_samples = self._rate * duration_ms // 1000
|
||||
_data = _wave * (_samples // (len(_wave) // 2) + 1)
|
||||
_data = _data[:_samples * 2]
|
||||
def _tone(self, frequency, duration_ms=1000):
|
||||
_wave = self._wave(frequency)
|
||||
_samples = self._rate * duration_ms // 1000
|
||||
_data = _wave * (_samples // (len(_wave) // 2) + 1)
|
||||
_data = _data[:_samples * 2]
|
||||
|
||||
_wbytes = 0
|
||||
while _wbytes < len(_data):
|
||||
send_size = min(512, len(_data) - _wbytes)
|
||||
self.i2s_bus.write(_data[_wbytes : _wbytes + send_size])
|
||||
_wbytes += send_size
|
||||
_wbytes = 0
|
||||
while _wbytes < len(_data):
|
||||
send_size = min(512, len(_data) - _wbytes)
|
||||
self.i2s_bus.write(_data[_wbytes: _wbytes + send_size])
|
||||
_wbytes += send_size
|
||||
|
||||
def set_tempo(self, ticks=4, bpm=120):
|
||||
self.ticks = ticks
|
||||
self.bpm = bpm
|
||||
self.beat = 60000 / self.bpm / self.ticks
|
||||
def set_tempo(self, ticks=4, bpm=120):
|
||||
self.ticks = ticks
|
||||
self.bpm = bpm
|
||||
self.beat = 60000 / self.bpm / self.ticks
|
||||
|
||||
def set_octave(self, octave=4):
|
||||
self.octave = octave
|
||||
def set_octave(self, octave=4):
|
||||
self.octave = octave
|
||||
|
||||
def set_duration(self, duration=4):
|
||||
self.duration = duration
|
||||
def set_duration(self, duration=4):
|
||||
self.duration = duration
|
||||
|
||||
def get_tempo(self):
|
||||
return (self.ticks, self.bpm)
|
||||
def get_tempo(self):
|
||||
return (self.ticks, self.bpm)
|
||||
|
||||
def get_octave(self):
|
||||
return self.octave
|
||||
def get_octave(self):
|
||||
return self.octave
|
||||
|
||||
def get_duration(self):
|
||||
return self.duration
|
||||
def get_duration(self):
|
||||
return self.duration
|
||||
|
||||
def reset(self):
|
||||
self.set_duration()
|
||||
self.set_octave()
|
||||
self.set_tempo()
|
||||
def reset(self):
|
||||
self.set_duration()
|
||||
self.set_octave()
|
||||
self.set_tempo()
|
||||
|
||||
def parse(self, tone, dict):
|
||||
time = self.beat * self.duration
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
time = self.beat * int(tone[(pos + 1):])
|
||||
tone = tone[:pos]
|
||||
freq, tone_size = 1, len(tone)
|
||||
if 'R' in tone:
|
||||
freq = 20000
|
||||
elif tone_size == 1:
|
||||
freq = dict[tone[0] + str(self.octave)]
|
||||
elif tone_size == 2:
|
||||
freq = dict[tone]
|
||||
self.set_octave(tone[1:])
|
||||
return int(freq), int(time)
|
||||
def parse(self, tone, dict):
|
||||
time = self.beat * self.duration
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
time = self.beat * int(tone[(pos + 1):])
|
||||
tone = tone[:pos]
|
||||
freq, tone_size = 1, len(tone)
|
||||
if 'R' in tone:
|
||||
freq = 20000
|
||||
elif tone_size == 1:
|
||||
freq = dict[tone[0] + str(self.octave)]
|
||||
elif tone_size == 2:
|
||||
freq = dict[tone]
|
||||
self.set_octave(tone[1:])
|
||||
return int(freq), int(time)
|
||||
|
||||
def midi(self, tone):
|
||||
pos = tone.find('#')
|
||||
if pos != -1:
|
||||
return self.parse(tone.replace('#', ''), normal_tone)
|
||||
pos = tone.find('B')
|
||||
if pos != -1 and pos != 0:
|
||||
return self.parse(tone.replace('B', ''), normal_tone)
|
||||
return self.parse(tone, normal_tone)
|
||||
def midi(self, tone):
|
||||
pos = tone.find('#')
|
||||
if pos != -1:
|
||||
return self.parse(tone.replace('#', ''), normal_tone)
|
||||
pos = tone.find('B')
|
||||
if pos != -1 and pos != 0:
|
||||
return self.parse(tone.replace('B', ''), normal_tone)
|
||||
return self.parse(tone, normal_tone)
|
||||
|
||||
def set_default(self, tone):
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
self.set_duration(int(tone[(pos + 1):]))
|
||||
tone = tone[:pos]
|
||||
def set_default(self, tone):
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
self.set_duration(int(tone[(pos + 1):]))
|
||||
tone = tone[:pos]
|
||||
|
||||
def play(self, tune, duration=None):
|
||||
if duration is None:
|
||||
self.set_default(tune[0])
|
||||
else:
|
||||
self.set_duration(duration)
|
||||
for tone in tune:
|
||||
tone = tone.upper()
|
||||
if tone[0] not in Letter:
|
||||
continue
|
||||
midi = self.midi(tone)
|
||||
self._tone(midi[0], midi[1])
|
||||
self._tone(20000, 1)
|
||||
time.sleep_ms(10)
|
||||
def play(self, tune, duration=None):
|
||||
if duration is None:
|
||||
self.set_default(tune[0])
|
||||
else:
|
||||
self.set_duration(duration)
|
||||
for tone in tune:
|
||||
tone = tone.upper()
|
||||
if tone[0] not in Letter:
|
||||
continue
|
||||
midi = self.midi(tone)
|
||||
self._tone(midi[0], midi[1])
|
||||
self._tone(20000, 1)
|
||||
time.sleep_ms(10)
|
||||
|
||||
def pitch(self, freq):
|
||||
pass
|
||||
def pitch(self, freq):
|
||||
pass
|
||||
|
||||
def pitch_time(self, freq, delay):
|
||||
self._tone(freq, delay)
|
||||
time.sleep_ms(10)
|
||||
def pitch_time(self, freq, delay):
|
||||
self._tone(freq, delay)
|
||||
time.sleep_ms(10)
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
DADADADUM=['r4:2','g','g','g','eb:8','r:2','f','f','f','d:8']
|
||||
ENTERTAINER=['d4:1','d#','e','c5:2','e4:1','c5:2','e4:1','c5:3','c:1','d','d#','e','c','d','e:2','b4:1','d5:2','c:4']
|
||||
PRELUDE=['c4:1','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e','c4','d','g','d5','f','g4','d5','f','c4','d','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','c4','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e']
|
||||
ODE=['e4','e','f','g','g','f','e','d','c','c','d','e','e:6','d:2','d:8','e:4','e','f','g','g','f','e','d','c','c','d','e','d:6','c:2','c:8']
|
||||
NYAN=['f#5:1','g#','c#:1','d#:2','b4:1','d5:1','c#','b4:2','b','c#5','d','d:1','c#','b4:1','c#5:1','d#','f#','g#','d#','f#','c#','d','b4','c#5','b4','d#5:2','f#','g#:1','d#','f#','c#','d#','b4','d5','d#','d','c#','b4','c#5','d:2','b4:1','c#5','d#','f#','c#','d','c#','b4','c#5:2','b4','c#5','b4','f#:1','g#','b:2','f#:1','g#','b','c#5','d#','b4','e5','d#','e','f#','b4:2','b','f#:1','g#','b','f#','e5','d#','c#','b4','f#','d#','e','f#','b:2','f#:1','g#','b:2','f#:1','g#','b','b','c#5','d#','b4','f#','g#','f#','b:2','b:1','a#','b','f#','g#','b','e5','d#','e','f#','b4:2','c#5']
|
||||
RINGTONE=['c4:1','d','e:2','g','d:1','e','f:2','a','e:1','f','g:2','b','c5:4']
|
||||
FUNK=['c2:2','c','d#','c:1','f:2','c:1','f:2','f#','g','c','c','g','c:1','f#:2','c:1','f#:2','f','d#']
|
||||
BLUES=['c2:2','e','g','a','a#','a','g','e','c2:2','e','g','a','a#','a','g','e','f','a','c3','d','d#','d','c','a2','c2:2','e','g','a','a#','a','g','e','g','b','d3','f','f2','a','c3','d#','c2:2','e','g','e','g','f','e','d']
|
||||
BIRTHDAY=['c4:4','c:1','d:4','c:4','f','e:8','c:3','c:1','d:4','c:4','g','f:8','c:3','c:1','c5:4','a4','f','e','d','a#:3','a#:1','a:4','f','g','f:8']
|
||||
WEDDING=['c4:4','f:3','f:1','f:8','c:4','g:3','e:1','f:8','c:4','f:3','a:1','c5:4','a4:3','f:1','f:4','e:3','f:1','g:8']
|
||||
FUNERAL=['c3:4','c:3','c:1','c:4','d#:3','d:1','d:3','c:1','c:3','b2:1','c3:4']
|
||||
PUNCHLINE=['c4:3','g3:1','f#','g','g#:3','g','r','b','c4']
|
||||
PYTHON=['d5:1','b4','r','b','b','a#','b','g5','r','d','d','r','b4','c5','r','c','c','r','d','e:5','c:1','a4','r','a','a','g#','a','f#5','r','e','e','r','c','b4','r','b','b','r','c5','d:5','d:1','b4','r','b','b','a#','b','b5','r','g','g','r','d','c#','r','a','a','r','a','a:5','g:1','f#:2','a:1','a','g#','a','e:2','a:1','a','g#','a','d','r','c#','d','r','c#','d:2','r:3']
|
||||
BADDY=['c3:3','r','d:2','d#','r','c','r','f#:8']
|
||||
CHASE=['a4:1','b','c5','b4','a:2','r','a:1','b','c5','b4','a:2','r','a:2','e5','d#','e','f','e','d#','e','b4:1','c5','d','c','b4:2','r','b:1','c5','d','c','b4:2','r','b:2','e5','d#','e','f','e','d#','e']
|
||||
BA_DING=['b5:1','e6:3']
|
||||
WAWAWAWAA=['e3:3','r:1','d#:3','r:1','d:4','r:1','c#:8']
|
||||
JUMP_UP=['c5:1','d','e','f','g']
|
||||
JUMP_DOWN=['g5:1','f','e','d','c']
|
||||
POWER_UP=['g4:1','c5','e4','g5:2','e5:1','g5:3']
|
||||
POWER_DOWN=['g5:1','d#','c','g4:2','b:1','c5:3']
|
||||
DADADADUM = ['r4:2', 'g', 'g', 'g', 'eb:8', 'r:2', 'f', 'f', 'f', 'd:8']
|
||||
ENTERTAINER = ['d4:1', 'd#', 'e', 'c5:2', 'e4:1', 'c5:2', 'e4:1',
|
||||
'c5:3', 'c:1', 'd', 'd#', 'e', 'c', 'd', 'e:2', 'b4:1', 'd5:2', 'c:4']
|
||||
PRELUDE = ['c4:1', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'd', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'c4', 'd', 'g', 'd5', 'f', 'g4', 'd5',
|
||||
'f', 'b3', 'd4', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'b3', 'd4', 'g', 'd5', 'f', 'g4', 'd5', 'f', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e', 'c4', 'e', 'g', 'c5', 'e', 'g4', 'c5', 'e']
|
||||
ODE = ['e4', 'e', 'f', 'g', 'g', 'f', 'e', 'd', 'c', 'c', 'd', 'e', 'e:6', 'd:2', 'd:8',
|
||||
'e:4', 'e', 'f', 'g', 'g', 'f', 'e', 'd', 'c', 'c', 'd', 'e', 'd:6', 'c:2', 'c:8']
|
||||
NYAN = ['f#5:1', 'g#', 'c#:1', 'd#:2', 'b4:1', 'd5:1', 'c#', 'b4:2', 'b', 'c#5', 'd', 'd:1', 'c#', 'b4:1', 'c#5:1', 'd#', 'f#', 'g#', 'd#', 'f#', 'c#', 'd', 'b4', 'c#5', 'b4', 'd#5:2', 'f#', 'g#:1', 'd#', 'f#', 'c#', 'd#', 'b4', 'd5', 'd#', 'd', 'c#', 'b4', 'c#5', 'd:2', 'b4:1', 'c#5', 'd#', 'f#', 'c#', 'd', 'c#', 'b4', 'c#5:2', 'b4', 'c#5',
|
||||
'b4', 'f#:1', 'g#', 'b:2', 'f#:1', 'g#', 'b', 'c#5', 'd#', 'b4', 'e5', 'd#', 'e', 'f#', 'b4:2', 'b', 'f#:1', 'g#', 'b', 'f#', 'e5', 'd#', 'c#', 'b4', 'f#', 'd#', 'e', 'f#', 'b:2', 'f#:1', 'g#', 'b:2', 'f#:1', 'g#', 'b', 'b', 'c#5', 'd#', 'b4', 'f#', 'g#', 'f#', 'b:2', 'b:1', 'a#', 'b', 'f#', 'g#', 'b', 'e5', 'd#', 'e', 'f#', 'b4:2', 'c#5']
|
||||
RINGTONE = ['c4:1', 'd', 'e:2', 'g', 'd:1', 'e',
|
||||
'f:2', 'a', 'e:1', 'f', 'g:2', 'b', 'c5:4']
|
||||
FUNK = ['c2:2', 'c', 'd#', 'c:1', 'f:2', 'c:1', 'f:2', 'f#',
|
||||
'g', 'c', 'c', 'g', 'c:1', 'f#:2', 'c:1', 'f#:2', 'f', 'd#']
|
||||
BLUES = ['c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'f', 'a', 'c3', 'd', 'd#', 'd', 'c',
|
||||
'a2', 'c2:2', 'e', 'g', 'a', 'a#', 'a', 'g', 'e', 'g', 'b', 'd3', 'f', 'f2', 'a', 'c3', 'd#', 'c2:2', 'e', 'g', 'e', 'g', 'f', 'e', 'd']
|
||||
BIRTHDAY = ['c4:4', 'c:1', 'd:4', 'c:4', 'f', 'e:8', 'c:3', 'c:1', 'd:4', 'c:4', 'g',
|
||||
'f:8', 'c:3', 'c:1', 'c5:4', 'a4', 'f', 'e', 'd', 'a#:3', 'a#:1', 'a:4', 'f', 'g', 'f:8']
|
||||
WEDDING = ['c4:4', 'f:3', 'f:1', 'f:8', 'c:4', 'g:3', 'e:1', 'f:8',
|
||||
'c:4', 'f:3', 'a:1', 'c5:4', 'a4:3', 'f:1', 'f:4', 'e:3', 'f:1', 'g:8']
|
||||
FUNERAL = ['c3:4', 'c:3', 'c:1', 'c:4', 'd#:3',
|
||||
'd:1', 'd:3', 'c:1', 'c:3', 'b2:1', 'c3:4']
|
||||
PUNCHLINE = ['c4:3', 'g3:1', 'f#', 'g', 'g#:3', 'g', 'r', 'b', 'c4']
|
||||
PYTHON = ['d5:1', 'b4', 'r', 'b', 'b', 'a#', 'b', 'g5', 'r', 'd', 'd', 'r', 'b4', 'c5', 'r', 'c', 'c', 'r', 'd', 'e:5', 'c:1', 'a4', 'r', 'a', 'a', 'g#', 'a', 'f#5', 'r', 'e', 'e', 'r', 'c', 'b4', 'r', 'b', 'b', 'r', 'c5', 'd:5',
|
||||
'd:1', 'b4', 'r', 'b', 'b', 'a#', 'b', 'b5', 'r', 'g', 'g', 'r', 'd', 'c#', 'r', 'a', 'a', 'r', 'a', 'a:5', 'g:1', 'f#:2', 'a:1', 'a', 'g#', 'a', 'e:2', 'a:1', 'a', 'g#', 'a', 'd', 'r', 'c#', 'd', 'r', 'c#', 'd:2', 'r:3']
|
||||
BADDY = ['c3:3', 'r', 'd:2', 'd#', 'r', 'c', 'r', 'f#:8']
|
||||
CHASE = ['a4:1', 'b', 'c5', 'b4', 'a:2', 'r', 'a:1', 'b', 'c5', 'b4', 'a:2', 'r', 'a:2', 'e5', 'd#', 'e', 'f', 'e', 'd#',
|
||||
'e', 'b4:1', 'c5', 'd', 'c', 'b4:2', 'r', 'b:1', 'c5', 'd', 'c', 'b4:2', 'r', 'b:2', 'e5', 'd#', 'e', 'f', 'e', 'd#', 'e']
|
||||
BA_DING = ['b5:1', 'e6:3']
|
||||
WAWAWAWAA = ['e3:3', 'r:1', 'd#:3', 'r:1', 'd:4', 'r:1', 'c#:8']
|
||||
JUMP_UP = ['c5:1', 'd', 'e', 'f', 'g']
|
||||
JUMP_DOWN = ['g5:1', 'f', 'e', 'd', 'c']
|
||||
POWER_UP = ['g4:1', 'c5', 'e4', 'g5:2', 'e5:1', 'g5:3']
|
||||
POWER_DOWN = ['g5:1', 'd#', 'c', 'g4:2', 'b:1', 'c5:3']
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
"""
|
||||
Music buzzer
|
||||
|
||||
Micropython library for the Music buzzer
|
||||
=======================================================
|
||||
|
||||
#Based on Author: qiren123(MIDI Music)
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from time import sleep_ms
|
||||
from machine import Pin, PWM
|
||||
|
||||
normal_tone = {
|
||||
'A1': 55, 'B1': 62, 'C1': 33, 'D1': 37, 'E1': 41, 'F1': 44, 'G1': 49,
|
||||
'A2': 110, 'B2': 123, 'C2': 65, 'D2': 73, 'E2': 82, 'F2': 87, 'G2': 98,
|
||||
'A3': 220, 'B3': 247, 'C3': 131, 'D3': 147, 'E3': 165, 'F3': 175, 'G3': 196,
|
||||
'A4': 440, 'B4': 494, 'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392,
|
||||
'A5': 880, 'B5': 988, 'C5': 523, 'D5': 587, 'E5': 659, 'F5': 698, 'G5': 784,
|
||||
'A6': 1760, 'B6': 1976, 'C6': 1047, 'D6': 1175, 'E6': 1319, 'F6': 1397, 'G6': 1568,
|
||||
'A7': 3520, 'B7': 3951, 'C7': 2093, 'D7': 2349, 'E7': 2637, 'F7': 2794, 'G7': 3135,
|
||||
'A8': 7040, 'B8': 7902, 'C8': 4186, 'D8': 4699, 'E8': 5274, 'F8': 5588, 'G8': 6271,
|
||||
'A9': 14080, 'B9': 15804 }
|
||||
|
||||
Letter = 'ABCDEFG#R'
|
||||
|
||||
class MIDI():
|
||||
def __init__(self, pin, volume=100, invert=0, pa_ctrl=None):
|
||||
self.reset()
|
||||
self._invert=invert
|
||||
self._pin = pin
|
||||
self._volume = volume
|
||||
self._pwm = None
|
||||
self._pa_ctrl = pa_ctrl
|
||||
|
||||
def set_volume(self,volume):
|
||||
if not 0 <= volume <= 100:
|
||||
raise ValueError("Volume value is in the range: 0-100")
|
||||
self._volume=volume
|
||||
|
||||
def set_tempo(self, ticks=4, bpm=120):
|
||||
self.ticks = ticks
|
||||
self.bpm = bpm
|
||||
self.beat = 60000 / self.bpm / self.ticks
|
||||
|
||||
def set_octave(self, octave=4):
|
||||
self.octave = octave
|
||||
|
||||
def set_duration(self, duration=4):
|
||||
self.duration = duration
|
||||
|
||||
def get_tempo(self):
|
||||
return (self.ticks, self.bpm)
|
||||
|
||||
def get_octave(self):
|
||||
return self.octave
|
||||
|
||||
def get_duration(self):
|
||||
return self.duration
|
||||
|
||||
def reset(self):
|
||||
self.set_duration()
|
||||
self.set_octave()
|
||||
self.set_tempo()
|
||||
|
||||
def parse(self, tone, dict):
|
||||
time = self.beat * self.duration
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
time = self.beat * int(tone[(pos + 1):])
|
||||
tone = tone[:pos]
|
||||
freq, tone_size = 1, len(tone)
|
||||
if 'R' in tone:
|
||||
freq = 40000
|
||||
elif tone_size == 1:
|
||||
freq = dict[tone[0] + str(self.octave)]
|
||||
elif tone_size == 2:
|
||||
freq = dict[tone]
|
||||
self.set_octave(tone[1:])
|
||||
return int(freq), int(time)
|
||||
|
||||
def midi(self, tone):
|
||||
pos = tone.find('#')
|
||||
if pos != -1:
|
||||
return self.parse(tone.replace('#', ''), normal_tone)
|
||||
pos = tone.find('B')
|
||||
if pos != -1 and pos != 0:
|
||||
return self.parse(tone.replace('B', ''), normal_tone)
|
||||
return self.parse(tone, normal_tone)
|
||||
|
||||
def set_default(self, tone):
|
||||
pos = tone.find(':')
|
||||
if pos != -1:
|
||||
self.set_duration(int(tone[(pos + 1):]))
|
||||
tone = tone[:pos]
|
||||
|
||||
def play(self, tune, duration=None, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin), duty=1023 if self._invert else 0)
|
||||
if duration is None:
|
||||
self.set_default(tune[0])
|
||||
else:
|
||||
self.set_duration(duration)
|
||||
for tone in tune:
|
||||
tone = tone.upper()
|
||||
if tone[0] not in Letter:
|
||||
continue
|
||||
midi = self.midi(tone)
|
||||
self._pwm.duty(1023-self._volume) if self._invert else self._pwm.duty(self._volume)
|
||||
self._pwm.freq(midi[0])
|
||||
sleep_ms(midi[1])
|
||||
self._pwm.freq(40000)
|
||||
sleep_ms(1)
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
def pitch(self, freq, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin))
|
||||
self._pwm.duty(1023-self._volume) if self._invert else self._pwm.duty(self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
|
||||
def pitch_time(self, freq, delay, pa_delay=100):
|
||||
if self._pa_ctrl: self._pa_ctrl(1, pa_delay)
|
||||
self._pwm = PWM(Pin(self._pin))
|
||||
self._pwm.duty(1023-self._volume) if self._invert else self._pwm.duty(self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
sleep_ms(delay)
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
def stop(self):
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
if self._pwm: self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
DADADADUM=['r4:2','g','g','g','eb:8','r:2','f','f','f','d:8']
|
||||
ENTERTAINER=['d4:1','d#','e','c5:2','e4:1','c5:2','e4:1','c5:3','c:1','d','d#','e','c','d','e:2','b4:1','d5:2','c:4']
|
||||
PRELUDE=['c4:1','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e','c4','d','g','d5','f','g4','d5','f','c4','d','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','b3','d4','g','d5','f','g4','d5','f','c4','e','g','c5','e','g4','c5','e','c4','e','g','c5','e','g4','c5','e']
|
||||
ODE=['e4','e','f','g','g','f','e','d','c','c','d','e','e:6','d:2','d:8','e:4','e','f','g','g','f','e','d','c','c','d','e','d:6','c:2','c:8']
|
||||
NYAN=['f#5:1','g#','c#:1','d#:2','b4:1','d5:1','c#','b4:2','b','c#5','d','d:1','c#','b4:1','c#5:1','d#','f#','g#','d#','f#','c#','d','b4','c#5','b4','d#5:2','f#','g#:1','d#','f#','c#','d#','b4','d5','d#','d','c#','b4','c#5','d:2','b4:1','c#5','d#','f#','c#','d','c#','b4','c#5:2','b4','c#5','b4','f#:1','g#','b:2','f#:1','g#','b','c#5','d#','b4','e5','d#','e','f#','b4:2','b','f#:1','g#','b','f#','e5','d#','c#','b4','f#','d#','e','f#','b:2','f#:1','g#','b:2','f#:1','g#','b','b','c#5','d#','b4','f#','g#','f#','b:2','b:1','a#','b','f#','g#','b','e5','d#','e','f#','b4:2','c#5']
|
||||
RINGTONE=['c4:1','d','e:2','g','d:1','e','f:2','a','e:1','f','g:2','b','c5:4']
|
||||
FUNK=['c2:2','c','d#','c:1','f:2','c:1','f:2','f#','g','c','c','g','c:1','f#:2','c:1','f#:2','f','d#']
|
||||
BLUES=['c2:2','e','g','a','a#','a','g','e','c2:2','e','g','a','a#','a','g','e','f','a','c3','d','d#','d','c','a2','c2:2','e','g','a','a#','a','g','e','g','b','d3','f','f2','a','c3','d#','c2:2','e','g','e','g','f','e','d']
|
||||
BIRTHDAY=['c4:4','c:1','d:4','c:4','f','e:8','c:3','c:1','d:4','c:4','g','f:8','c:3','c:1','c5:4','a4','f','e','d','a#:3','a#:1','a:4','f','g','f:8']
|
||||
WEDDING=['c4:4','f:3','f:1','f:8','c:4','g:3','e:1','f:8','c:4','f:3','a:1','c5:4','a4:3','f:1','f:4','e:3','f:1','g:8']
|
||||
FUNERAL=['c3:4','c:3','c:1','c:4','d#:3','d:1','d:3','c:1','c:3','b2:1','c3:4']
|
||||
PUNCHLINE=['c4:3','g3:1','f#','g','g#:3','g','r','b','c4']
|
||||
PYTHON=['d5:1','b4','r','b','b','a#','b','g5','r','d','d','r','b4','c5','r','c','c','r','d','e:5','c:1','a4','r','a','a','g#','a','f#5','r','e','e','r','c','b4','r','b','b','r','c5','d:5','d:1','b4','r','b','b','a#','b','b5','r','g','g','r','d','c#','r','a','a','r','a','a:5','g:1','f#:2','a:1','a','g#','a','e:2','a:1','a','g#','a','d','r','c#','d','r','c#','d:2','r:3']
|
||||
BADDY=['c3:3','r','d:2','d#','r','c','r','f#:8']
|
||||
CHASE=['a4:1','b','c5','b4','a:2','r','a:1','b','c5','b4','a:2','r','a:2','e5','d#','e','f','e','d#','e','b4:1','c5','d','c','b4:2','r','b:1','c5','d','c','b4:2','r','b:2','e5','d#','e','f','e','d#','e']
|
||||
BA_DING=['b5:1','e6:3']
|
||||
WAWAWAWAA=['e3:3','r:1','d#:3','r:1','d:4','r:1','c#:8']
|
||||
JUMP_UP=['c5:1','d','e','f','g']
|
||||
JUMP_DOWN=['g5:1','f','e','d','c']
|
||||
POWER_UP=['g4:1','c5','e4','g5:2','e5:1','g5:3']
|
||||
POWER_DOWN=['g5:1','d#','c','g4:2','b:1','c5:3']
|
||||
@@ -18,94 +18,95 @@ _NOVA_G1_IO = const(0x03)
|
||||
_NOVA_G1_PWM = const(0x04)
|
||||
|
||||
class NOVA_G1:
|
||||
def __init__(self, i2c_bus, addr=_NOVA_G1_ADDRESS):
|
||||
self._i2c=i2c_bus
|
||||
self._addr = addr
|
||||
if self._rreg(_NOVA_G1_ID)!= 0x25:
|
||||
raise AttributeError("Cannot find a NOVA_G1")
|
||||
self.reset()
|
||||
def __init__(self, i2c_bus, addr=_NOVA_G1_ADDRESS):
|
||||
self._i2c = i2c_bus
|
||||
self._addr = addr
|
||||
if self._rreg(_NOVA_G1_ID) != 0x25:
|
||||
raise AttributeError("Cannot find a NOVA_G1")
|
||||
self.reset()
|
||||
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._i2c.writeto_mem(self._addr, reg, val.to_bytes(1, 'little'))
|
||||
except:
|
||||
return 0
|
||||
def _wreg(self, reg, val):
|
||||
'''Write memory address'''
|
||||
try:
|
||||
self._i2c.writeto_mem(self._addr, reg, val.to_bytes(1, 'little'))
|
||||
except:
|
||||
return 0
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
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]
|
||||
except:
|
||||
return 0
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
try:
|
||||
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]
|
||||
except:
|
||||
return 0
|
||||
|
||||
def reset(self):
|
||||
"""Reset all registers to default state"""
|
||||
for reg in range(_NOVA_G1_PWM,_NOVA_G1_PWM + 6):
|
||||
self._wreg(reg,0x00)
|
||||
def reset(self):
|
||||
"""Reset all registers to default state"""
|
||||
for reg in range(_NOVA_G1_PWM, _NOVA_G1_PWM + 6):
|
||||
self._wreg(reg, 0x00)
|
||||
|
||||
def varistor(self, ratio=100/1023):
|
||||
'''Read battery power'''
|
||||
_adc= self._rreg(_NOVA_G1_ADC) << 2 | self._rreg(_NOVA_G1_ADC+1) >> 6
|
||||
return round(_adc * ratio)
|
||||
|
||||
def pwm(self, index, duty=None):
|
||||
"""Motor*2*2 & USB*2 PWM duty cycle data register"""
|
||||
if duty is None:
|
||||
return self._rreg(_NOVA_G1_PWM + index)
|
||||
else:
|
||||
duty = min(255, max(0, duty))
|
||||
self._wreg(_NOVA_G1_PWM + index, duty)
|
||||
def varistor(self, ratio=100/1023):
|
||||
'''Read battery power'''
|
||||
_adc = self._rreg(_NOVA_G1_ADC) << 2 | self._rreg(_NOVA_G1_ADC+1) >> 6
|
||||
return round(_adc * ratio)
|
||||
|
||||
def motor(self, index, action, speed=0):
|
||||
if not 0 <= index <= 1:
|
||||
raise ValueError("Motor port must be a number in the range: 0~1")
|
||||
speed = min(100, max(speed, -100))
|
||||
if action=="N":
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
elif action=="P":
|
||||
self.pwm(index * 2, 255)
|
||||
self.pwm(index * 2 + 1, 255)
|
||||
elif action=="CW":
|
||||
if speed >= 0:
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, speed * 255 // 100)
|
||||
else:
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, - speed * 255 // 100)
|
||||
elif action=="CCW":
|
||||
if speed >= 0:
|
||||
self.pwm(index * 2, speed * 255 // 100)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
else:
|
||||
self.pwm(index * 2, - speed * 255 // 100)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
elif action=="NC":
|
||||
return round(self.pwm(index * 2) * 100 / 255), round(self.pwm(index * 2 + 1) * 100 / 255)
|
||||
else:
|
||||
raise ValueError('Invalid input, valid are "N","P","CW","CCW"')
|
||||
def pwm(self, index, duty=None):
|
||||
"""Motor*2*2 & USB*2 PWM duty cycle data register"""
|
||||
if duty is None:
|
||||
return self._rreg(_NOVA_G1_PWM + index)
|
||||
else:
|
||||
duty = min(255, max(0, duty))
|
||||
self._wreg(_NOVA_G1_PWM + index, duty)
|
||||
|
||||
def usb_pwm(self, index, duty=None):
|
||||
if not 0 <= index <= 1:
|
||||
raise ValueError("USB-2.0 port must be a number in the range: 0~1")
|
||||
if duty is None:
|
||||
return round((self.pwm(index + 4) * 100 / 255))
|
||||
else:
|
||||
self.pwm(index + 4, duty * 255 // 100)
|
||||
def motor(self, index, action, speed=0):
|
||||
if not 0 <= index <= 1:
|
||||
raise ValueError("Motor port must be a number in the range: 0~1")
|
||||
speed = min(100, max(speed, -100))
|
||||
if action == "N":
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
elif action == "P":
|
||||
self.pwm(index * 2, 255)
|
||||
self.pwm(index * 2 + 1, 255)
|
||||
elif action == "CW":
|
||||
if speed >= 0:
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, speed * 255 // 100)
|
||||
else:
|
||||
self.pwm(index * 2, 0)
|
||||
self.pwm(index * 2 + 1, - speed * 255 // 100)
|
||||
elif action == "CCW":
|
||||
if speed >= 0:
|
||||
self.pwm(index * 2, speed * 255 // 100)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
else:
|
||||
self.pwm(index * 2, - speed * 255 // 100)
|
||||
self.pwm(index * 2 + 1, 0)
|
||||
elif action == "NC":
|
||||
return round(self.pwm(index * 2) * 100 / 255), round(self.pwm(index * 2 + 1) * 100 / 255)
|
||||
else:
|
||||
raise ValueError('Invalid input, valid are "N","P","CW","CCW"')
|
||||
|
||||
def spk_en(self, onoff=True):
|
||||
if onoff:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) | 0x02)
|
||||
else:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) & 0xFD)
|
||||
def usb_pwm(self, index, duty=None):
|
||||
if not 0 <= index <= 1:
|
||||
raise ValueError("USB-2.0 port must be a number in the range: 0~1")
|
||||
if duty is None:
|
||||
return round((self.pwm(index + 4) * 100 / 255))
|
||||
else:
|
||||
self.pwm(index + 4, duty * 255 // 100)
|
||||
|
||||
def ldo_en(self, onoff=True):
|
||||
if onoff:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) | 0x01)
|
||||
else:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) & 0xFE)
|
||||
def spk_en(self, onoff=True):
|
||||
if onoff:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) | 0x02)
|
||||
else:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) & 0xFD)
|
||||
|
||||
#Constructor
|
||||
def ldo_en(self, onoff=True):
|
||||
if onoff:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) | 0x01)
|
||||
else:
|
||||
self._wreg(_NOVA_G1_IO, (self._rreg(_NOVA_G1_IO)) & 0xFE)
|
||||
|
||||
|
||||
# Constructor
|
||||
ext_g1 = NOVA_G1(onboard_i2c)
|
||||
|
||||
@@ -43,7 +43,7 @@ class BOT035:
|
||||
time.sleep_ms(delay)
|
||||
|
||||
def reset(self):
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_PWM, b' Ndddd\x00\x00\x00\x8c\xb0')
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_PWM, b' Ndddd\x00\x00\x00\x8c\x20')
|
||||
|
||||
def key_adc(self):
|
||||
return self._rreg(_BOT035_ADC, 2)
|
||||
@@ -94,7 +94,7 @@ class BOT035:
|
||||
"""Convert to high level effective"""
|
||||
value = value if value is None else ~ value & 0x01
|
||||
return self._bits(5, 0x20, value, delay)
|
||||
|
||||
|
||||
def cam_reset(self, value=None, delay=50):
|
||||
return self._bits(4, 0x10, value, delay)
|
||||
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
"""
|
||||
MicroPython driver for SD cards using SPI bus.
|
||||
"""
|
||||
import time
|
||||
from machine import Pin
|
||||
from micropython import const
|
||||
|
||||
_CMD_TIMEOUT = const(100)
|
||||
_R1_IDLE_STATE = const(1 << 0)
|
||||
_R1_ILLEGAL_COMMAND = const(1 << 2)
|
||||
_TOKEN_CMD25 = const(0xFC)
|
||||
_TOKEN_STOP_TRAN = const(0xFD)
|
||||
_TOKEN_DATA = const(0xFE)
|
||||
|
||||
class SDCard:
|
||||
def __init__(self, spi, cs_pin, baudrate=50000000):
|
||||
self.spi = spi
|
||||
self.cs = Pin(cs_pin, Pin.OUT, value=1)
|
||||
self.cmdbuf = bytearray(6)
|
||||
self.dummybuf = bytearray(512)
|
||||
self.tokenbuf = bytearray(1)
|
||||
for i in range(512):
|
||||
self.dummybuf[i] = 0xFF
|
||||
self.dummybuf_memoryview = memoryview(self.dummybuf)
|
||||
# initialise the card
|
||||
self.init_card(baudrate)
|
||||
|
||||
def init_spi(self, baudrate):
|
||||
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
|
||||
|
||||
def init_card(self, baudrate):
|
||||
# init SPI bus; use low data rate for initialisation
|
||||
self.init_spi(100000)
|
||||
# clock card at least 100 cycles with cs high
|
||||
for i in range(16):
|
||||
self.spi.write(b"\xff")
|
||||
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
|
||||
for _ in range(5):
|
||||
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
|
||||
break
|
||||
else:
|
||||
raise OSError("no SD card")
|
||||
# CMD8: determine card version
|
||||
r = self.cmd(8, 0x01AA, 0x87, 4)
|
||||
if r == _R1_IDLE_STATE:
|
||||
self.init_card_v2()
|
||||
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
|
||||
self.init_card_v1()
|
||||
else:
|
||||
raise OSError("couldn't determine SD card version")
|
||||
# CMD9: response R2 (R1 byte + 16-byte block read)
|
||||
if self.cmd(9, 0, 0, 0, False) != 0:
|
||||
raise OSError("no response from SD card")
|
||||
csd = bytearray(16)
|
||||
self.readinto(csd)
|
||||
if csd[0] & 0xC0 == 0x40: # CSD version 2.0
|
||||
self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024
|
||||
elif csd[0] & 0xC0 == 0x00: # CSD version 1.0 (old, <=2GB)
|
||||
c_size = (csd[6] & 0b11) << 10 | csd[7] << 2 | csd[8] >> 6
|
||||
c_size_mult = (csd[9] & 0b11) << 1 | csd[10] >> 7
|
||||
read_bl_len = csd[5] & 0b1111
|
||||
capacity = (c_size + 1) * (2 ** (c_size_mult + 2)) * (2**read_bl_len)
|
||||
self.sectors = capacity // 512
|
||||
else:
|
||||
raise OSError("SD card CSD format not supported")
|
||||
# CMD16: set block length to 512 bytes
|
||||
if self.cmd(16, 512, 0) != 0:
|
||||
raise OSError("can't set 512 block size")
|
||||
# set to high data rate now that it's initialised
|
||||
self.init_spi(baudrate)
|
||||
|
||||
def init_card_v1(self):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0, 0) == 0:
|
||||
# SDSC card, uses byte addressing in read/write/erase commands
|
||||
self.cdv = 512
|
||||
# print("[SDCard] v1 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v1 card")
|
||||
|
||||
def init_card_v2(self):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0x40000000, 0) == 0:
|
||||
self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte
|
||||
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
|
||||
if not ocr & 0x40:
|
||||
# SDSC card, uses byte addressing in read/write/erase commands
|
||||
self.cdv = 512
|
||||
else:
|
||||
# SDHC/SDXC card, uses block addressing in read/write/erase commands
|
||||
self.cdv = 1
|
||||
# print("[SDCard] v2 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v2 card")
|
||||
|
||||
def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False):
|
||||
self.cs(0)
|
||||
|
||||
# create and send the command
|
||||
buf = self.cmdbuf
|
||||
buf[0] = 0x40 | cmd
|
||||
buf[1] = arg >> 24
|
||||
buf[2] = arg >> 16
|
||||
buf[3] = arg >> 8
|
||||
buf[4] = arg
|
||||
buf[5] = crc
|
||||
self.spi.write(buf)
|
||||
|
||||
if skip1:
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
# wait for the response (response[7] == 0)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
response = self.tokenbuf[0]
|
||||
if not (response & 0x80):
|
||||
if final < 0:
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
final = -1 - final
|
||||
for j in range(final):
|
||||
self.spi.write(b"\xff")
|
||||
if release:
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return response
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return -1
|
||||
|
||||
def readinto(self, buf):
|
||||
self.cs(0)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.spi.readinto(self.tokenbuf, 0xFF)
|
||||
if self.tokenbuf[0] == _TOKEN_DATA:
|
||||
break
|
||||
time.sleep_ms(1)
|
||||
else:
|
||||
self.cs(1)
|
||||
raise OSError("timeout waiting for response")
|
||||
mv = self.dummybuf_memoryview
|
||||
if len(buf) != len(mv):
|
||||
mv = mv[: len(buf)]
|
||||
self.spi.write_readinto(mv, buf)
|
||||
self.spi.write(b"\xff")
|
||||
self.spi.write(b"\xff")
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def write(self, token, buf):
|
||||
self.cs(0)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(buf)
|
||||
self.spi.write(b"\xff")
|
||||
self.spi.write(b"\xff")
|
||||
if (self.spi.read(1, 0xFF)[0] & 0x1F) != 0x05:
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
return
|
||||
while self.spi.read(1, 0xFF)[0] == 0:
|
||||
pass
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def write_token(self, token):
|
||||
self.cs(0)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(b"\xff")
|
||||
while self.spi.read(1, 0xFF)[0] == 0x00:
|
||||
pass
|
||||
self.cs(1)
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
def readblocks(self, block_num, buf):
|
||||
# workaround for shared bus, required for (at least) some Kingston
|
||||
self.spi.write(b"\xff")
|
||||
|
||||
nblocks = len(buf) // 512
|
||||
assert nblocks and not len(buf) % 512, "Buffer length is invalid"
|
||||
if nblocks == 1:
|
||||
# CMD17: set read address for single block
|
||||
if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
|
||||
# release the card
|
||||
self.cs(1)
|
||||
raise OSError(5) # EIO
|
||||
# receive the data and release card
|
||||
self.readinto(buf)
|
||||
else:
|
||||
# CMD18: set read address for multiple blocks
|
||||
if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
|
||||
self.cs(1)
|
||||
raise OSError(5) # EIO
|
||||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.readinto(mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
if self.cmd(12, 0, 0xFF, skip1=True):
|
||||
raise OSError(5) # EIO
|
||||
|
||||
def writeblocks(self, block_num, buf):
|
||||
# workaround for shared bus, required for (at least) some Kingston
|
||||
self.spi.write(b"\xff")
|
||||
nblocks, err = divmod(len(buf), 512)
|
||||
assert nblocks and not err, "Buffer length is invalid"
|
||||
if nblocks == 1:
|
||||
# CMD24: set write address for single block
|
||||
if self.cmd(24, block_num * self.cdv, 0) != 0:
|
||||
raise OSError(5) # EIO
|
||||
self.write(_TOKEN_DATA, buf)
|
||||
else:
|
||||
# CMD25: set write address for first block
|
||||
if self.cmd(25, block_num * self.cdv, 0) != 0:
|
||||
raise OSError(5) # EIO
|
||||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
self.write_token(_TOKEN_STOP_TRAN)
|
||||
|
||||
def ioctl(self, op, arg):
|
||||
if op == 4: # get number of blocks
|
||||
return self.sectors
|
||||
if op == 5: # get block size in bytes
|
||||
return 512
|
||||
106
boards/default/micropython_esp32s3/build/lib/soar_bot.py
Normal file
106
boards/default/micropython_esp32s3/build/lib/soar_bot.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
SOAR_WCH
|
||||
|
||||
Micropython library for the SOAR_WCH
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_BOT035_ADDRESS = const(0x13)
|
||||
_BOT5_TOUCH = const(0x01)
|
||||
_BOT035_ADC = const(0x05)
|
||||
_BOT035_OPA = const(0x09)
|
||||
_BOT035_PWM = const(0x0B)
|
||||
_BOT035_CMD = const(0x11)
|
||||
_BOT035_STA = const(0x12)
|
||||
_BOT035_KB = const(0x13)
|
||||
_BOT035_MS = const(0x17)
|
||||
_BOT035_STR = const(0x1B)
|
||||
|
||||
class BOT035:
|
||||
def __init__(self, i2c_bus):
|
||||
self._i2c = i2c_bus
|
||||
self._touchs = [self.touch(0), self.touch(1)]
|
||||
self.reset()
|
||||
|
||||
def _wreg(self, reg, val, digit=1):
|
||||
'''Write memory address'''
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, reg, val.to_bytes(digit, 'little'))
|
||||
|
||||
def _rreg(self, reg, nbytes=1):
|
||||
'''Read memory address'''
|
||||
self._i2c.writeto(_BOT035_ADDRESS, reg.to_bytes(1, 'little'))
|
||||
return int.from_bytes(self._i2c.readfrom(_BOT035_ADDRESS, nbytes), 'little')
|
||||
|
||||
def reset(self):
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_PWM, b' Ndddd\xc0')
|
||||
|
||||
def touch(self, index, value=None):
|
||||
index = max(min(index, 1), 0)
|
||||
touch = 4095 - self._rreg(_BOT5_TOUCH + index * 2, 2)
|
||||
return touch > value if value else touch
|
||||
|
||||
def touched(self, index, value=600):
|
||||
return self.touch(index, value)
|
||||
|
||||
def touch_slide(self):
|
||||
values = []
|
||||
for i in range(20):
|
||||
values.append((self.touch(1) - self._touchs[1]) - (self.touch(0) - self._touchs[0]))
|
||||
return round(sorted(values)[10] / 10)
|
||||
|
||||
def brightness(self, index):
|
||||
index = max(min(index, 1), 0)
|
||||
return 4095 - self._rreg(_BOT035_ADC + index * 2, 2)
|
||||
|
||||
def amp_pga(self, k=1, b=155, pga=3, dp=0):
|
||||
"""0:4x,1:8x,2:16x,3:32x"""
|
||||
self._wreg(_BOT035_CMD, (self._rreg(_BOT035_CMD) & 0x3F) | (pga & 0x03) << 6)
|
||||
return round((self._rreg(_BOT035_OPA, 2) * k - b) / (2 ** (pga + 2)), dp)
|
||||
|
||||
def usben(self, index=1, duty=None, freq=None):
|
||||
index = max(min(index, 4), 1)
|
||||
if duty is not None:
|
||||
self._wreg(_BOT035_PWM + index + 1, int(max(min(duty, 100), 0)))
|
||||
if freq is not None:
|
||||
self._wreg(_BOT035_PWM, max(min(freq, 65535), 10), 2)
|
||||
if freq is None and duty is None:
|
||||
return self._rreg(_BOT035_PWM + index + 1), self._rreg(_BOT035_PWM ,2)
|
||||
|
||||
def tft_brightness(self, brightness=None):
|
||||
if brightness is None:
|
||||
return round((self._rreg(_BOT035_CMD) & 0x3F) * 1.587)
|
||||
else:
|
||||
brightness = round(brightness* 0.63)
|
||||
self._wreg(_BOT035_CMD, (self._rreg(_BOT035_CMD) & 0xC0) | max(min(brightness, 63), 0))
|
||||
|
||||
def hid_keyboard(self, special=0, general=0, release=True):
|
||||
self._buf = bytearray(4)
|
||||
self._buf[0] = special
|
||||
if type(general) in (tuple, list):
|
||||
for i in range(len(general)):
|
||||
if i > 2: break
|
||||
self._buf[i + 1] = general[i]
|
||||
else:
|
||||
self._buf[1] = general
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_KB, self._buf)
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_KB, bytes(4))
|
||||
|
||||
def hid_keyboard_str(self, string, delay=0):
|
||||
for char in str(string):
|
||||
self._wreg(_BOT035_STR, ord(char) & 0xFF)
|
||||
time.sleep_ms(20 + delay)
|
||||
|
||||
def hid_keyboard_state(self):
|
||||
state = self._rreg(_BOT035_STA)
|
||||
return bool(state & 0x10), bool(state & 0x20), bool(state & 0x40)
|
||||
|
||||
def hid_mouse(self, keys=0, move=(0, 0), wheel=0, release=True):
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_MS, bytes([keys & 0x0F, move[0] & 0xFF, move[1] & 0xFF, wheel & 0xFF]))
|
||||
if release:
|
||||
time.sleep_ms(10)
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_MS, bytes(4))
|
||||
@@ -7,7 +7,8 @@ MicroPython library for the ST7789(TFT-SPI)
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time, uframebuf
|
||||
import time
|
||||
import uframebuf
|
||||
from machine import Pin, PWM
|
||||
from micropython import const
|
||||
|
||||
@@ -30,78 +31,98 @@ _CMD_COLMOD = const(0x3A)
|
||||
_CMD_MADCTL = const(0x36)
|
||||
|
||||
class ST7789(uframebuf.FrameBuffer_Uincode):
|
||||
def __init__(self, spi, width, height, dc_pin=None, cs_pin=None, bl_pin=None, font_address=0x700000):
|
||||
if height != 240 or width not in [320, 240, 135]:
|
||||
raise ValueError("Unsupported display. 320x240, 240x240 and 135x240 are supported.")
|
||||
self.spi = spi
|
||||
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
||||
self.cs = Pin(cs_pin, Pin.OUT, value=1)
|
||||
self._buffer = bytearray(width * height * 2)
|
||||
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
||||
self.font(font_address)
|
||||
self._init()
|
||||
self.show()
|
||||
time.sleep_ms(100)
|
||||
self._brightness = 0.6
|
||||
self.bl_led = PWM(Pin(bl_pin), duty_u16=int(self._brightness * 60000)) if bl_pin else None
|
||||
def __init__(self, spi, width, height, dc_pin=None, cs_pin=None, bl_pin=None, brightness=0.6, font_address=0x700000):
|
||||
self.spi = spi
|
||||
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
||||
self.cs = Pin(cs_pin, Pin.OUT, value=1)
|
||||
self._buffer = bytearray(width * height * 2)
|
||||
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
||||
self.font(font_address)
|
||||
self._init()
|
||||
self.show()
|
||||
if brightness > 0:
|
||||
time.sleep_ms(100)
|
||||
self._brightness = brightness
|
||||
if callable(bl_pin):
|
||||
self.bl_led = bl_pin
|
||||
else:
|
||||
self.bl_led = PWM(Pin(bl_pin), duty_u16=int(
|
||||
self._brightness * 60000)) if bl_pin else None
|
||||
|
||||
def _write(self, cmd, dat = None):
|
||||
self.cs.off()
|
||||
self.dc.off()
|
||||
self.spi.write(bytearray([cmd]))
|
||||
self.cs.on()
|
||||
if dat is not None:
|
||||
self.cs.off()
|
||||
self.dc.on()
|
||||
self.spi.write(dat)
|
||||
self.cs.on()
|
||||
def _write(self, cmd, dat=None):
|
||||
self.cs.off()
|
||||
self.dc.off()
|
||||
self.spi.write(bytearray([cmd]))
|
||||
self.cs.on()
|
||||
if dat is not None:
|
||||
self.cs.off()
|
||||
self.dc.on()
|
||||
self.spi.write(dat)
|
||||
self.cs.on()
|
||||
|
||||
def _init(self):
|
||||
"""Display initialization configuration"""
|
||||
for cmd, data, delay in [
|
||||
(_CMD_SWRESET, None, 150),
|
||||
(_CMD_SLPOUT, None, None),
|
||||
(_CMD_COLMOD, b'\x55', 50),
|
||||
(_CMD_MADCTL, b'\x60', 50),
|
||||
(_CMD_INVOFF, None, 10),
|
||||
(_CMD_NORON, None, 10),
|
||||
(_CMD_DISPON, None, 200),
|
||||
]:
|
||||
self._write(cmd, data)
|
||||
if delay:
|
||||
time.sleep_us(delay)
|
||||
def _init(self):
|
||||
"""Display initialization configuration"""
|
||||
for cmd, data, delay in [
|
||||
# (_CMD_SWRESET, None, 20000),
|
||||
(_CMD_SLPOUT, None, 120000),
|
||||
(_CMD_MADCTL, b'\x00', 50),
|
||||
(_CMD_COLMOD, b'\x05', 50),
|
||||
(0xB2, b'\x0c\x0c\x00\x33\x33', 10),
|
||||
(0xB7, b'\x35', 10),
|
||||
(0xBB, b'\x19', 10),
|
||||
(0xC0, b'\x2C', 10),
|
||||
(0xC2, b'\x01', 10),
|
||||
(0xC3, b'\x12', 10),
|
||||
(0xC4, b'\x20', 10),
|
||||
(0xC6, b'\x0F', 10),
|
||||
(0xD0, b'\xA4\xA1', 10),
|
||||
(0xE0, b'\xD0\x04\x0D\x11\x13\x2B\x3F\x54\x4C\x18\x0D\x0B\x1F\x23', 10),
|
||||
(0xE1, b'\xD0\x04\x0C\x11\x13\x2C\x3F\x44\x51\x2F\x1F\x1F\x20\x23', 10),
|
||||
(0x21, None, 10),
|
||||
(0x29, None, 10),
|
||||
# (_CMD_INVOFF, None, 10),
|
||||
# (_CMD_NORON, None, 10),
|
||||
# (_CMD_DISPON, None, 200),
|
||||
]:
|
||||
self._write(cmd, data)
|
||||
if delay:
|
||||
time.sleep_us(delay)
|
||||
|
||||
def _write(self, command=None, data=None):
|
||||
"""SPI write to the device: commands and data."""
|
||||
if command is not None:
|
||||
self.cs.off()
|
||||
self.dc.off()
|
||||
self.spi.write(bytes([command]))
|
||||
self.cs.on()
|
||||
if data is not None:
|
||||
self.cs.off()
|
||||
self.dc.on()
|
||||
self.spi.write(data)
|
||||
self.cs.on()
|
||||
def _write(self, command=None, data=None):
|
||||
"""SPI write to the device: commands and data."""
|
||||
if command is not None:
|
||||
self.cs.off()
|
||||
self.dc.off()
|
||||
self.spi.write(bytes([command]))
|
||||
self.cs.on()
|
||||
if data is not None:
|
||||
self.cs.off()
|
||||
self.dc.on()
|
||||
self.spi.write(data)
|
||||
self.cs.on()
|
||||
|
||||
def get_brightness(self):
|
||||
return self._brightness
|
||||
def get_brightness(self):
|
||||
return self._brightness
|
||||
|
||||
def set_brightness(self, brightness):
|
||||
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.bl_led.duty_u16(int(brightness*60000))
|
||||
def set_brightness(self, brightness):
|
||||
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
|
||||
if callable(self.bl_led):
|
||||
self.bl_led(brightness * 100)
|
||||
elif isinstance(self.bl_led, PWM):
|
||||
self.bl_led.duty_u16(int(brightness*60000))
|
||||
|
||||
def color(self, red, green=None, blue=None):
|
||||
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
||||
if green is None or blue is None:
|
||||
return red
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
def color(self, red, green=None, blue=None):
|
||||
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
||||
if green is None or blue is None:
|
||||
return red
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self._write(_CMD_CASET, b'\x00\x00\x01\x3f')
|
||||
self._write(_CMD_RASET, b'\x00\x00\x00\xef')
|
||||
self._write(_CMD_RAMWR, self._buffer)
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self._write(_CMD_CASET, b'\x00\x00\x01\x3f')
|
||||
self._write(_CMD_RASET, b'\x00\x00\x00\xef')
|
||||
self._write(_CMD_RAMWR, self._buffer)
|
||||
|
||||
@@ -1,48 +1,113 @@
|
||||
"""
|
||||
ST7789/FrameBuffer(Inherit C module)
|
||||
ST7789/FrameBuffer
|
||||
|
||||
MicroPython library for the ST7789(Inherit C module)
|
||||
MicroPython library for the ST7789(TFT-SPI)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time, uframebuf
|
||||
from tftlcd import LCD15
|
||||
import time
|
||||
import uframebuf
|
||||
from machine import Pin
|
||||
from jpeg import Decoder
|
||||
from micropython import const
|
||||
|
||||
_CMD_SWRESET = const(0x01)
|
||||
_CMD_SLPIN = const(0x10)
|
||||
_CMD_SLPOUT = const(0x11)
|
||||
_CMD_PTLON = const(0x12)
|
||||
_CMD_NORON = const(0x13)
|
||||
_CMD_INVOFF = const(0x20)
|
||||
_CMD_INVON = const(0x21)
|
||||
_CMD_DISPOFF = const(0x28)
|
||||
_CMD_DISPON = const(0x29)
|
||||
_CMD_CASET = const(0x2A)
|
||||
_CMD_RASET = const(0x2B)
|
||||
_CMD_RAMWR = const(0x2C)
|
||||
_CMD_RAMRD = const(0x2E)
|
||||
_CMD_PTLAR = const(0x30)
|
||||
_CMD_VSCRDEF = const(0x33)
|
||||
_CMD_COLMOD = const(0x3A)
|
||||
_CMD_MADCTL = const(0x36)
|
||||
|
||||
class ST7789(uframebuf.FrameBuffer_Uincode):
|
||||
def __init__(self, width=240, height=240, reset=None, backlight=None, direction=1, font_address=0x700000):
|
||||
self.display = LCD15(portrait=direction)
|
||||
self.display.deinit()
|
||||
if reset is not None:
|
||||
reset(0, 50)
|
||||
reset(1, 100)
|
||||
self.display = LCD15(portrait=direction)
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._buffer = bytearray(width * height * 2)
|
||||
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
||||
self.font(font_address)
|
||||
self.show()
|
||||
self._backlight = backlight
|
||||
if backlight: self.set_brightness(0.5)
|
||||
def __init__(self, spi, width, height, dc_pin=None, backlight=None, reset=None, font_address=0x700000):
|
||||
self.spi = spi
|
||||
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
||||
self._buffer = bytearray(width * height * 2)
|
||||
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
||||
reset(1, 100)
|
||||
self.font(font_address)
|
||||
self._init()
|
||||
# self.show()
|
||||
self._oneclight = True
|
||||
self._backlight = backlight
|
||||
|
||||
def get_brightness(self):
|
||||
return self._backlight() / 100
|
||||
def display(self, data=None, rotation=0, sync=True):
|
||||
if type(data) is str:
|
||||
with open(data, "rb") as f:
|
||||
_jpeg = f.read()
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", rotation=rotation)
|
||||
self._buffer[:] = _decoder.decode(_jpeg)
|
||||
del _decoder
|
||||
else:
|
||||
self._buffer[:] = data # 后期做图像大小处理
|
||||
if sync:
|
||||
self.show()
|
||||
return self._buffer
|
||||
|
||||
def set_brightness(self, brightness):
|
||||
if not 0.0 <= brightness <= 1.0:
|
||||
raise ValueError("Brightness must be a decimal number in the range: 0.0~1.0")
|
||||
self._backlight(int(brightness * 100))
|
||||
def _write(self, cmd, dat=None):
|
||||
self.dc.off()
|
||||
self.spi.write(bytearray([cmd]))
|
||||
if dat is not None:
|
||||
self.dc.on()
|
||||
self.spi.write(dat)
|
||||
|
||||
def color(self, red, green=None, blue=None):
|
||||
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
||||
if green is None or blue is None:
|
||||
return red
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
def _init(self):
|
||||
"""Display initialization configuration"""
|
||||
for cmd, data, delay in [
|
||||
# (_CMD_SWRESET, None, 20000),
|
||||
(_CMD_SLPOUT, None, 120000),
|
||||
(_CMD_MADCTL, b'\x00', 50),
|
||||
(_CMD_COLMOD, b'\x05', 50),
|
||||
(0xB2, b'\x0c\x0c\x00\x33\x33', 10),
|
||||
(0xB7, b'\x35', 10),
|
||||
(0xBB, b'\x19', 10),
|
||||
(0xC0, b'\x2C', 10),
|
||||
(0xC2, b'\x01', 10),
|
||||
(0xC3, b'\x12', 10),
|
||||
(0xC4, b'\x20', 10),
|
||||
(0xC6, b'\x0F', 10),
|
||||
(0xD0, b'\xA4\xA1', 10),
|
||||
(0xE0, b'\xD0\x04\x0D\x11\x13\x2B\x3F\x54\x4C\x18\x0D\x0B\x1F\x23', 10),
|
||||
(0xE1, b'\xD0\x04\x0C\x11\x13\x2C\x3F\x44\x51\x2F\x1F\x1F\x20\x23', 10),
|
||||
(_CMD_INVON, None, 10),
|
||||
(_CMD_DISPON, None, 10),
|
||||
]:
|
||||
self._write(cmd, data)
|
||||
if delay:
|
||||
time.sleep_us(delay)
|
||||
|
||||
def picture(self, x, y, path):
|
||||
self.display.Picture(x, y, path)
|
||||
def get_brightness(self):
|
||||
return self._backlight() / 100
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self.display.write_buf(self._buffer, 0, 0, self._width, self._height)
|
||||
def set_brightness(self, brightness):
|
||||
if not 0.0 <= brightness <= 1.0:
|
||||
raise ValueError(
|
||||
"Brightness must be a decimal number in the range: 0.0~1.0")
|
||||
self._backlight(int(brightness * 100))
|
||||
|
||||
def color(self, red, green=None, blue=None):
|
||||
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
||||
if green is None or blue is None:
|
||||
return red
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
if self._oneclight:
|
||||
self.set_brightness(0.6)
|
||||
self._oneclight = False
|
||||
self._write(_CMD_CASET, b'\x00\x00\x00\xef')
|
||||
self._write(_CMD_RASET, b'\x00\x00\x00\xef')
|
||||
self._write(_CMD_RAMWR, self._buffer)
|
||||
|
||||
@@ -7,60 +7,61 @@ Micropython library for the WS2812 NeoPixel-RGB(method inheritance)
|
||||
"""
|
||||
from time import sleep
|
||||
|
||||
|
||||
class NeoPixel:
|
||||
def __init__(self, func, n, bpp=3, ORDER=(0, 1, 2, 3)):
|
||||
self.func = func
|
||||
self.bpp = bpp
|
||||
self.rgbs = n
|
||||
self.ORDER = ORDER
|
||||
self.rgb_buf = bytearray(self.rgbs * bpp)
|
||||
self.write()
|
||||
def __init__(self, func, n, bpp=3, ORDER=(0, 1, 2, 3)):
|
||||
self.func = func
|
||||
self.bpp = bpp
|
||||
self.rgbs = n
|
||||
self.ORDER = ORDER
|
||||
self.rgb_buf = bytearray(self.rgbs * bpp)
|
||||
self.write()
|
||||
|
||||
def __len__(self):
|
||||
return self.rgbs
|
||||
def __len__(self):
|
||||
return self.rgbs
|
||||
|
||||
def __setitem__(self, n, v):
|
||||
for i in range(self.bpp):
|
||||
self.rgb_buf[n * self.bpp + self.ORDER[i]] = v[i]
|
||||
def __setitem__(self, n, v):
|
||||
for i in range(self.bpp):
|
||||
self.rgb_buf[n * self.bpp + self.ORDER[i]] = v[i]
|
||||
|
||||
def __getitem__(self, n):
|
||||
return tuple(self.rgb_buf[n * self.bpp + self.ORDER[i]] for i in range(self.bpp))
|
||||
def __getitem__(self, n):
|
||||
return tuple(self.rgb_buf[n * self.bpp + self.ORDER[i]] for i in range(self.bpp))
|
||||
|
||||
def fill(self, v):
|
||||
for i in range(self.bpp):
|
||||
j = self.ORDER[i]
|
||||
while j < self.rgbs * self.bpp:
|
||||
self.rgb_buf[j] = v[i]
|
||||
j += self.bpp
|
||||
def fill(self, v):
|
||||
for i in range(self.bpp):
|
||||
j = self.ORDER[i]
|
||||
while j < self.rgbs * self.bpp:
|
||||
self.rgb_buf[j] = v[i]
|
||||
j += self.bpp
|
||||
|
||||
def write(self):
|
||||
self.func(self.rgb_buf)
|
||||
def write(self):
|
||||
self.func(self.rgb_buf)
|
||||
|
||||
def color_chase(self,R, G, B, wait):
|
||||
for i in range(self.rgbs):
|
||||
self.__setitem__(i,(R, G, B))
|
||||
self.write()
|
||||
sleep(wait/1000)
|
||||
def color_chase(self, R, G, B, wait):
|
||||
for i in range(self.rgbs):
|
||||
self.__setitem__(i, (R, G, B))
|
||||
self.write()
|
||||
sleep(wait/1000)
|
||||
|
||||
def rainbow_cycle(self, wait, clear=True):
|
||||
for j in range(255):
|
||||
for i in range(self.rgbs):
|
||||
rc_index = (i * 256 // self.rgbs) + j
|
||||
self.__setitem__(i,self.wheel(rc_index & 255))
|
||||
self.write()
|
||||
sleep(wait / 1000 / 256)
|
||||
if clear:
|
||||
self.fill((0, 0, 0))
|
||||
self.write()
|
||||
def rainbow_cycle(self, wait, clear=True):
|
||||
for j in range(255):
|
||||
for i in range(self.rgbs):
|
||||
rc_index = (i * 256 // self.rgbs) + j
|
||||
self.__setitem__(i, self.wheel(rc_index & 255))
|
||||
self.write()
|
||||
sleep(wait / 1000 / 256)
|
||||
if clear:
|
||||
self.fill((0, 0, 0))
|
||||
self.write()
|
||||
|
||||
def wheel(self,pos):
|
||||
if pos < 0 or pos > 255:
|
||||
return (0, 0, 0)
|
||||
elif pos < 85:
|
||||
return (pos * 3, 255 - pos * 3, 0)
|
||||
elif pos < 170:
|
||||
pos -= 85
|
||||
return (255 - pos * 3, 0, pos * 3)
|
||||
else:
|
||||
pos -= 170
|
||||
return (0, pos * 3, 255 - pos * 3)
|
||||
def wheel(self, pos):
|
||||
if pos < 0 or pos > 255:
|
||||
return (0, 0, 0)
|
||||
elif pos < 85:
|
||||
return (pos * 3, 255 - pos * 3, 0)
|
||||
elif pos < 170:
|
||||
pos -= 85
|
||||
return (255 - pos * 3, 0, pos * 3)
|
||||
else:
|
||||
pos -= 170
|
||||
return (0, pos * 3, 255 - pos * 3)
|
||||
|
||||
Reference in New Issue
Block a user