feat: sync all micropython board configurations and scripts
This commit is contained in:
117
mixly/boards/default/micropython_esp32s3/build/lib/camera.py
Normal file
117
mixly/boards/default/micropython_esp32s3/build/lib/camera.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
Camera
|
||||
|
||||
MicroPython library for the Camera(Inherit C module)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time, gc
|
||||
import urequests
|
||||
from _camera import *
|
||||
from base64 import b64encode
|
||||
from machine import SoftI2C, Pin
|
||||
from jpeg import Encoder, Decoder
|
||||
|
||||
class IMG:
|
||||
def __init__(self, image, width, height):
|
||||
self.image = image
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.format = "RGB565"
|
||||
|
||||
class Camera(Camera):
|
||||
def __init__(self, frame_size=FrameSize.R240X240, pixel_format=PixelFormat.RGB565, skip_frame=3, hmirror=False, vflip=False, **kwargs):
|
||||
from mixgo_sant import onboard_bot
|
||||
onboard_bot.cam_reset(1, 0)
|
||||
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(150)
|
||||
self.set_vflip(not vflip)
|
||||
SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000) # 恢复I2C
|
||||
for _ in range(skip_frame):
|
||||
super().capture()
|
||||
|
||||
def deinit(self):
|
||||
super().deinit()
|
||||
gc.collect()
|
||||
onboard_bot.cam_reset(0, 0)
|
||||
onboard_bot.cam_en(0, 100)
|
||||
|
||||
def snapshot(self, path=None, quality=90, rotation=0):
|
||||
if path is None:
|
||||
return self.capture()
|
||||
else:
|
||||
Image.save(self.capture(), path, quality=quality, rotation=rotation)
|
||||
|
||||
def capture(self):
|
||||
return IMG(super().capture(), self.get_pixel_width(), self.get_pixel_height())
|
||||
|
||||
class Image:
|
||||
def save(self, img, path="mixly.jpg", **kwargs):
|
||||
'''quality(1-100), rotation (0, 90, 180, 270)'''
|
||||
_encoder = Encoder(pixel_format="RGB565_BE", width=img.width, height=img.height, **kwargs)
|
||||
_jpeg = _encoder.encode(img.image)
|
||||
del _encoder
|
||||
gc.collect()
|
||||
if isinstance(path, str):
|
||||
with open(path, 'wb') as f:
|
||||
f.write(_jpeg)
|
||||
else:
|
||||
return _jpeg
|
||||
|
||||
def open(self, path="mixly.jpg", scale_width=None, scale_height=None, tft_width=240, tft_height=240, **kwargs):
|
||||
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
||||
with open(path, "rb") as f:
|
||||
_jpeg = f.read()
|
||||
return self._jpg_decoder(_jpeg, scale_width, scale_height, tft_width, tft_height, **kwargs)
|
||||
|
||||
def convert(self, img, formats=0, **kwargs):
|
||||
if formats == 0:
|
||||
return self.save(img, None, **kwargs)
|
||||
elif formats == 1:
|
||||
return b'data:image/jpg;base64,' + b64encode(self.save(img, None, **kwargs))
|
||||
|
||||
def download(self, url, path=None, scale_width=None, scale_height=None, tft_width=240, tft_height=240, block=1024, **kwargs):
|
||||
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
||||
response = urequests.get(url, stream=True)
|
||||
if path is None:
|
||||
_image = self._jpg_decoder(response.raw.read(), scale_width, scale_height, tft_width, tft_height, **kwargs)
|
||||
response.close()
|
||||
return _image
|
||||
else:
|
||||
with open(path, 'wb') as f:
|
||||
while True:
|
||||
_data = response.raw.read(block)
|
||||
if not _data:
|
||||
break
|
||||
else:
|
||||
f.write(_data)
|
||||
response.close()
|
||||
|
||||
def _jpg_decoder(self, jpg, scale_width, scale_height, tft_width, tft_height, **kwargs):
|
||||
'''Automatically zoom based on the screen'''
|
||||
if scale_width is None or scale_height is None:
|
||||
_width = tft_width
|
||||
_height = tft_height
|
||||
for i in range(min(len(jpg), 1024)):
|
||||
if jpg[i] == 0xFF and (jpg[i + 1] & 0xF0) == 0xC0:
|
||||
if jpg[i + 1] not in [0xC4, 0xC8, 0xCC]:
|
||||
_width = jpg[i + 7] << 8 | jpg[i + 8]
|
||||
_height = jpg[i + 5] << 8| jpg[i + 6]
|
||||
break
|
||||
if _width > tft_width or _height > tft_height:
|
||||
_scale = max(_width / tft_width, _height / tft_height) * 8
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=round(_width / _scale) * 8, scale_height=round(_height / _scale) * 8, **kwargs)
|
||||
else:
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", **kwargs)
|
||||
else:
|
||||
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=scale_width // 8 * 8, scale_height=scale_height // 8 * 8, **kwargs)
|
||||
_info = _decoder.get_img_info(jpg)
|
||||
_image = IMG(_decoder.decode(jpg), _info[0], _info[1])
|
||||
del _decoder, jpg
|
||||
gc.collect()
|
||||
return _image
|
||||
|
||||
#图像处理
|
||||
Image = Image()
|
||||
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
CI1302(继承ci130x)
|
||||
|
||||
MicroPython library for the CI130Xx (ASR-I2C)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
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 _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)
|
||||
195
mixly/boards/default/micropython_esp32s3/build/lib/es8374.py
Normal file
195
mixly/boards/default/micropython_esp32s3/build/lib/es8374.py
Normal file
@@ -0,0 +1,195 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_ES_MODULE_ADC = const(0x01)
|
||||
_ES_MODULE_DAC = const(0x02)
|
||||
_ES_MODULE_ADC_DAC = const(0x03)
|
||||
_ES_MODULE_LINE = const(0x04)
|
||||
_BIT_LENGTH_16BITS = const(0x03)
|
||||
_FMT_I2S_NORMAL = const(0x00)
|
||||
_I2S_MODE_SLAVE = const(0x00)
|
||||
_ADC_INPUT_LINE = const(0x01)
|
||||
_DAC_OUTPUT_ALL = const(0x02)
|
||||
_LCLK_DIV = const(256)
|
||||
_MCLK_DIV = const(0x04)
|
||||
|
||||
class ES8374:
|
||||
def __init__(self, i2c_bus=None, i2c_addr=0x10, gain=5, pga_en=1):
|
||||
self.i2c_bus = i2c_bus
|
||||
self.i2c_addr = i2c_addr
|
||||
self.stop()
|
||||
self.init_reg(_I2S_MODE_SLAVE, ((_BIT_LENGTH_16BITS << 4) | _FMT_I2S_NORMAL), _DAC_OUTPUT_ALL, _ADC_INPUT_LINE)
|
||||
self.mic_gain(gain)
|
||||
self.pga_enable(pga_en)
|
||||
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]
|
||||
|
||||
def _writeReg(self, regAddr, data):
|
||||
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(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.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
|
||||
# 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
|
||||
# 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)
|
||||
# 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
|
||||
'''
|
||||
reg = self._readReg(0x1a) # disable lout
|
||||
reg |= 0x08
|
||||
self._writeReg(0x1a, reg)
|
||||
reg &= 0xdf
|
||||
self._writeReg(0x1a, reg)
|
||||
self._writeReg(0x1D, 0x12) # mute speaker
|
||||
self._writeReg(0x1E, 0x20) # disable class d
|
||||
reg = self._readReg(0x15) # power up dac
|
||||
reg &= 0xdf
|
||||
self._writeReg(0x15, reg)
|
||||
reg = self._readReg(0x1a) # disable lout
|
||||
reg |= 0x20
|
||||
self._writeReg(0x1a, reg)
|
||||
reg &= 0xf7
|
||||
self._writeReg(0x1a, reg)
|
||||
self._writeReg(0x1D, 0x02) # mute speaker
|
||||
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)
|
||||
|
||||
def i2sConfigClock(self):
|
||||
self._writeReg(0x0f, (self._readReg(0x0F) & 0xe0) | _MCLK_DIV)
|
||||
# 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
|
||||
if (mode == _ES_MODULE_ADC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x10)
|
||||
reg &= 0xfc
|
||||
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.setBitsPerSample(mode, 3)
|
||||
|
||||
# set Bits Per Sample
|
||||
def setBitsPerSample(self, mode, bit_per_smaple):
|
||||
bits = bit_per_smaple & 0x0f
|
||||
if (mode == _ES_MODULE_ADC or mode == _ES_MODULE_ADC_DAC):
|
||||
reg = self._readReg(0x10)
|
||||
reg &= 0xe3
|
||||
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)))
|
||||
|
||||
def configDACOutput(self, output):
|
||||
self._writeReg(0x1d, 0x02)
|
||||
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
|
||||
|
||||
def configADCInput(self, input):
|
||||
reg = self._readReg(0x21)
|
||||
reg = (reg & 0xcf) | 0x24
|
||||
self._writeReg(0x21, reg)
|
||||
|
||||
def mic_volume(self, volume=None):
|
||||
if volume is None:
|
||||
return round(100 - self._readReg(0x25) * 100 / 192)
|
||||
else:
|
||||
self._writeReg(0x25, (100 - volume) * 192 // 100)
|
||||
|
||||
def voice_volume(self, volume=None):
|
||||
if volume is None:
|
||||
return round(100 - self._readReg(0x38) * 100 / 192)
|
||||
else:
|
||||
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))
|
||||
|
||||
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
|
||||
|
||||
def pga_enable(self, enable):
|
||||
self._writeReg(0x21, (self._readReg(0x21) & 0xfb) | (enable << 2)) # MIC PGA 0db or 15db
|
||||
62
mixly/boards/default/micropython_esp32s3/build/lib/esp_dl.py
Normal file
62
mixly/boards/default/micropython_esp32s3/build/lib/esp_dl.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
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 True if results else False
|
||||
if results:
|
||||
if keys == "len":
|
||||
return len(results)
|
||||
else:
|
||||
return results[num][keys]
|
||||
|
||||
#简单处理模型运行结果
|
||||
_onboard_tft = None
|
||||
|
||||
def simple_run(molde, camera, keys="len", keyx=None, num=0, color=0xF800, size=2, sync=True):
|
||||
global _onboard_tft
|
||||
if _onboard_tft is None:
|
||||
from mixgo_sant import onboard_tft
|
||||
_onboard_tft = onboard_tft
|
||||
|
||||
if sync: _onboard_tft.fill(0, sync=False)
|
||||
_img = camera.capture()
|
||||
_onboard_tft.display(_img, sync=False)
|
||||
_result = molde.run(_img.image)
|
||||
_data = None
|
||||
|
||||
if _result:
|
||||
_x_of = (camera.get_pixel_width() - _onboard_tft.width) // 2
|
||||
_y_of = (camera.get_pixel_height() - _onboard_tft.height) // 2
|
||||
|
||||
for r in _result:
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
if r['box']:
|
||||
_onboard_tft.rect(r['box'][0] - _x_of, r['box'][1] - _y_of, r['box'][2], r['box'][3], color, sync=False)
|
||||
x = r['box'][0]
|
||||
y = r['box'][1] + r['box'][3]
|
||||
|
||||
if "person" in r:
|
||||
_onboard_tft.shows(r['person']['name'], x=x - _x_of, y=y - _y_of, size=size, center=0, color=color, sync=False)
|
||||
else:
|
||||
if r['box']:
|
||||
_onboard_tft.shows(r['data'], x=x - _x_of, y=y - _y_of, size=size, center=0, color=color, sync=False)
|
||||
else:
|
||||
_onboard_tft.shows(r['data'], y=0, size=size, center=True, color=color, sync=False)
|
||||
break
|
||||
|
||||
if keys == "len":
|
||||
_data = len(_result)
|
||||
else:
|
||||
_data = _result[num][keys] if keyx is None else _result[num][keys][keyx]
|
||||
|
||||
if sync: _onboard_tft.show()
|
||||
return _data
|
||||
234
mixly/boards/default/micropython_esp32s3/build/lib/map.json
Normal file
234
mixly/boards/default/micropython_esp32s3/build/lib/map.json
Normal file
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"camera": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"gc",
|
||||
"urequests",
|
||||
"_camera",
|
||||
"base64",
|
||||
"machine",
|
||||
"jpeg",
|
||||
"mixgo_sant"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 4782,
|
||||
"__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",
|
||||
"mixgo_sant"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 2060,
|
||||
"__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__": [
|
||||
"es8374",
|
||||
"ustruct",
|
||||
"music_spk",
|
||||
"machine",
|
||||
"esp_i2s",
|
||||
"esp_tts",
|
||||
"mixgo_nova",
|
||||
"urequests"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 2804,
|
||||
"__name__": "mixgo_nova_voice.py"
|
||||
},
|
||||
"mixgo_sant": {
|
||||
"__require__": [
|
||||
"gc",
|
||||
"time",
|
||||
"math",
|
||||
"machine",
|
||||
"music",
|
||||
"ws2812x",
|
||||
"st7789_cf",
|
||||
"sant_bot",
|
||||
"sc7a20",
|
||||
"ltr553als",
|
||||
"shtc3",
|
||||
"mmc5603",
|
||||
"ci1302x"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 7375,
|
||||
"__name__": "mixgo_sant.py"
|
||||
},
|
||||
"mixgo_soar": {
|
||||
"__require__": [
|
||||
"ws2812",
|
||||
"machine",
|
||||
"time",
|
||||
"gc",
|
||||
"math",
|
||||
"st7789_bf",
|
||||
"soar_bot",
|
||||
"spl06_001",
|
||||
"qmi8658",
|
||||
"ltr553als",
|
||||
"mmc5603"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 6752,
|
||||
"__name__": "mixgo_soar.py"
|
||||
},
|
||||
"mixgo_soar_voice": {
|
||||
"__require__": [
|
||||
"es8374",
|
||||
"ustruct",
|
||||
"music_spk",
|
||||
"machine",
|
||||
"esp_i2s",
|
||||
"esp_tts",
|
||||
"mixgo_soar",
|
||||
"urequests"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 2804,
|
||||
"__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"
|
||||
},
|
||||
"sant_tts": {
|
||||
"__require__": [
|
||||
"gc",
|
||||
"esp_tts",
|
||||
"machine",
|
||||
"pwm_audio",
|
||||
"mixgo_sant"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 747,
|
||||
"__name__": "sant_tts.py"
|
||||
},
|
||||
"soar_bot": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"micropython"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 4048,
|
||||
"__name__": "soar_bot.py"
|
||||
},
|
||||
"st7789_bf": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"uframebuf",
|
||||
"machine"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3711,
|
||||
"__name__": "st7789_bf.py"
|
||||
},
|
||||
"st7789_cf": {
|
||||
"__require__": [
|
||||
"time",
|
||||
"uframebuf",
|
||||
"machine",
|
||||
"camera"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 3595,
|
||||
"__name__": "st7789_cf.py"
|
||||
},
|
||||
"ws2812x": {
|
||||
"__require__": [
|
||||
"time"
|
||||
],
|
||||
"__file__": true,
|
||||
"__size__": 1957,
|
||||
"__name__": "ws2812x.py"
|
||||
}
|
||||
}
|
||||
355
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_nova.py
Normal file
355
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_nova.py
Normal file
@@ -0,0 +1,355 @@
|
||||
"""
|
||||
mixgo_zero Zi Onboard resources
|
||||
|
||||
Micropython library for the mixgo_zero Zi Onboard resources
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20231020
|
||||
#S3定时器ID(-1,0,1,2,3(led))
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
from ws2812 import NeoPixel
|
||||
from machine import *
|
||||
import time
|
||||
import gc
|
||||
import st7735
|
||||
import math
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
|
||||
'''I2C-onboard'''
|
||||
version = not Pin(13, Pin.IN, Pin.PULL_DOWN).value()
|
||||
onboard_i2c = SoftI2C(scl=Pin(36), sda=Pin(37), freq=400000)
|
||||
onboard_i2c_soft = SoftI2C(scl=Pin(36) if version else Pin(13), sda=Pin(15), freq=400000)
|
||||
onboard_i2c_scan = onboard_i2c.scan()
|
||||
|
||||
'''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/128*160'''
|
||||
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)
|
||||
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_soft)
|
||||
except Exception as 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)
|
||||
|
||||
'''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)
|
||||
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)
|
||||
|
||||
'''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)
|
||||
|
||||
'''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 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, 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]
|
||||
|
||||
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-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 _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 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 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'''
|
||||
|
||||
|
||||
class LED_I:
|
||||
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_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): # 定义时钟中心点和半径
|
||||
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()
|
||||
self.clear(0)
|
||||
|
||||
def clear(self, color=0): # 清除
|
||||
self.drawHour(color)
|
||||
self.drawMin(color)
|
||||
self.drawSec(color)
|
||||
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
mixgo_nova Voice Onboard resources
|
||||
|
||||
Micropython library for the mixgo_nova Onboard resources
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import es8374
|
||||
import ustruct
|
||||
import music_spk
|
||||
from machine import Pin
|
||||
from esp_i2s import I2S
|
||||
from esp_tts import TTS
|
||||
from mixgo_nova import onboard_i2c
|
||||
|
||||
ob_code = es8374.ES8374(onboard_i2c)
|
||||
ob_tts = TTS()
|
||||
ob_audio = I2S(0, sck=Pin(34), ws=Pin(47), sd_out=Pin(48), sd_in=Pin(33), mck=Pin(35), channels=1)
|
||||
ob_audio.start()
|
||||
spk_midi = music_spk.MIDI(ob_audio)
|
||||
|
||||
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_tts(text, speed=3):
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = 16000
|
||||
ob_audio.start()
|
||||
if ob_tts.parse_chinese(text):
|
||||
while True:
|
||||
data = ob_tts.stream_play(speed)
|
||||
if not data:
|
||||
break
|
||||
else:
|
||||
ob_audio.write(data)
|
||||
|
||||
def play_audio(path, chunk=1024):
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
ob_audio.start()
|
||||
file.seek(44)
|
||||
while True:
|
||||
block = file.read(chunk)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
file.close()
|
||||
|
||||
def record_audio(path, seconds=5, sample_rate=22050, chunk=512):
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = sample_rate
|
||||
ob_audio.start()
|
||||
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(chunk)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // chunk):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
file.close()
|
||||
|
||||
def play_audio_url(url, chunk=1024):
|
||||
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')
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
ob_audio.start()
|
||||
while True:
|
||||
block = response.raw.read(chunk)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
response.close()
|
||||
245
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_sant.py
Normal file
245
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_sant.py
Normal file
@@ -0,0 +1,245 @@
|
||||
"""
|
||||
mixgo_sant Onboard resources(v2.0)
|
||||
|
||||
Micropython library for the mixgo_sant Onboard resources
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import gc
|
||||
import time
|
||||
import math
|
||||
from machine import *
|
||||
from music import MIDI
|
||||
from ws2812x import NeoPixel
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock = RTC()
|
||||
|
||||
'''I2C-onboard'''
|
||||
# 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)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with BOT035 (Coprocessor) or", e)
|
||||
|
||||
'''TFT/240*240'''
|
||||
import st7789_cf
|
||||
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)
|
||||
except Exception as 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)
|
||||
except Exception as 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)
|
||||
except Exception as 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)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with GXHTC3 (THS) or", e)
|
||||
|
||||
'''MGS-Sensor'''
|
||||
try:
|
||||
import mmc5603
|
||||
onboard_mgs = mmc5603.MMC5603(inboard_i2c)
|
||||
except Exception as 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)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with CI130X (ASR) or", e)
|
||||
|
||||
'''2RGB_WS2812'''
|
||||
onboard_rgb = NeoPixel(onboard_bot.rgb_sync, 4)
|
||||
|
||||
'''1Buzzer-Music'''
|
||||
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 _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 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, 1600)
|
||||
A2key = KEYSensor(17, 1100)
|
||||
A3key = KEYSensor(17, 550)
|
||||
A4key = KEYSensor(17, 2100)
|
||||
|
||||
'''2-LED'''
|
||||
class LED:
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
|
||||
def setbrightness(self, index, val):
|
||||
self._func(index, val)
|
||||
|
||||
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 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]
|
||||
|
||||
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 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()
|
||||
221
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_soar.py
Normal file
221
mixly/boards/default/micropython_esp32s3/build/lib/mixgo_soar.py
Normal file
@@ -0,0 +1,221 @@
|
||||
"""
|
||||
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.6, 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()
|
||||
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
mixgo_soar Voice Onboard resources
|
||||
|
||||
Micropython library for the mixgo_soar Onboard resources
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import es8374
|
||||
import ustruct
|
||||
import music_spk
|
||||
from machine import Pin
|
||||
from esp_i2s import I2S
|
||||
from esp_tts import TTS
|
||||
from mixgo_soar import onboard_i2c
|
||||
|
||||
ob_code = es8374.ES8374(onboard_i2c)
|
||||
ob_tts = TTS()
|
||||
ob_audio = I2S(0, sck=Pin(37), ws=Pin(35), sd_out=Pin(34), sd_in=Pin(36), mck=Pin(33), channels=1)
|
||||
ob_audio.start()
|
||||
spk_midi = music_spk.MIDI(ob_audio)
|
||||
|
||||
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_tts(text, speed=3):
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = 16000
|
||||
ob_audio.start()
|
||||
if ob_tts.parse_chinese(text):
|
||||
while True:
|
||||
data = ob_tts.stream_play(speed)
|
||||
if not data:
|
||||
break
|
||||
else:
|
||||
ob_audio.write(data)
|
||||
|
||||
def play_audio(path, chunk=1024):
|
||||
file = open(path, 'rb')
|
||||
header = file.read(44)
|
||||
if header[8:12] != b'WAVE':
|
||||
raise Error('not a WAVE file')
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
ob_audio.start()
|
||||
file.seek(44)
|
||||
while True:
|
||||
block = file.read(chunk)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
file.close()
|
||||
|
||||
def record_audio(path, seconds=5, sample_rate=22050, chunk=512):
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = sample_rate
|
||||
ob_audio.start()
|
||||
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(chunk)
|
||||
file = open(path, 'wb')
|
||||
file.write(wav_header)
|
||||
for _ in range(file_size // chunk):
|
||||
ob_audio.readinto(buf)
|
||||
file.write(buf)
|
||||
file.close()
|
||||
|
||||
def play_audio_url(url, chunk=1024):
|
||||
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')
|
||||
ob_audio.stop()
|
||||
ob_audio.sample_rate = ustruct.unpack('<I', header[24:28])[0]
|
||||
ob_audio.start()
|
||||
while True:
|
||||
block = response.raw.read(chunk)
|
||||
if not block:
|
||||
break
|
||||
ob_audio.write(block)
|
||||
response.close()
|
||||
170
mixly/boards/default/micropython_esp32s3/build/lib/music_spk.py
Normal file
170
mixly/boards/default/micropython_esp32s3/build/lib/music_spk.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
Music buzzer
|
||||
|
||||
Micropython library for the Music buzzer
|
||||
=======================================================
|
||||
|
||||
#Based on Author: qiren123(MIDI Music) 20220618
|
||||
#Make changes to instantiation 20220622
|
||||
#Increase level reversal selection 20220716
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time
|
||||
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}
|
||||
|
||||
Letter = 'ABCDEFG#R'
|
||||
|
||||
|
||||
class MIDI():
|
||||
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 _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
|
||||
|
||||
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 = 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 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 pitch(self, freq):
|
||||
pass
|
||||
|
||||
def pitch_time(self, freq, delay):
|
||||
self._tone(freq, delay)
|
||||
time.sleep_ms(10)
|
||||
|
||||
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']
|
||||
112
mixly/boards/default/micropython_esp32s3/build/lib/nova_g1.py
Normal file
112
mixly/boards/default/micropython_esp32s3/build/lib/nova_g1.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""
|
||||
NOVA_G1
|
||||
|
||||
Micropython library for the NOVA_G1(PWM*6, IO*2, ADC*1)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20240222
|
||||
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
from micropython import const
|
||||
from mixgo_nova import onboard_i2c
|
||||
|
||||
_NOVA_G1_ADDRESS = const(0x25)
|
||||
_NOVA_G1_ID = const(0x00)
|
||||
_NOVA_G1_ADC = const(0x01)
|
||||
_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 _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 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 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 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 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 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)
|
||||
137
mixly/boards/default/micropython_esp32s3/build/lib/sant_bot.py
Normal file
137
mixly/boards/default/micropython_esp32s3/build/lib/sant_bot.py
Normal file
@@ -0,0 +1,137 @@
|
||||
"""
|
||||
SANT_WCH
|
||||
|
||||
Micropython library for the SANT_WCH(--V1.8--)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
_BOT035_ADDRESS = const(0x13)
|
||||
_BOT5_TOUCH = const(0x01)
|
||||
_BOT035_ADC = const(0x05)
|
||||
_BOT035_PWM = const(0x09)
|
||||
_BOT035_LED = const(0x0F)
|
||||
_BOT035_STA = const(0x12)
|
||||
_BOT035_CMD = const(0x13)
|
||||
_BOT035_RGB = const(0x14)
|
||||
_BOT035_KB = const(0x20)
|
||||
_BOT035_MS = const(0x24)
|
||||
_BOT035_STR = const(0x28)
|
||||
|
||||
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 _bits(self, offset, mask, value=None, delay=100, reg=_BOT035_CMD):
|
||||
if value is None:
|
||||
return (self._rreg(reg) & mask) >> offset
|
||||
else:
|
||||
self._wreg(reg, (self._rreg(reg) & (~ mask & 0xFF)) | (value << offset))
|
||||
time.sleep_ms(delay)
|
||||
|
||||
def reset(self):
|
||||
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)
|
||||
|
||||
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 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 self._rreg(_BOT035_LED)
|
||||
else:
|
||||
self._wreg(_BOT035_LED, max(min(brightness, 100), 0))
|
||||
|
||||
def led_pwm(self, index=1, duty=None):
|
||||
index = max(min(index, 2), 1)
|
||||
if duty is None:
|
||||
return self._rreg(_BOT035_LED + index)
|
||||
else:
|
||||
self._wreg(_BOT035_LED + index, max(min(duty, 100), 0))
|
||||
|
||||
def tft_reset(self, value=None, delay=50):
|
||||
return self._bits(7, 0x80, value, delay)
|
||||
|
||||
def spk_en(self, value=None, delay=10):
|
||||
return self._bits(6, 0x40, value, delay)
|
||||
|
||||
def cam_en(self, value=None, delay=500):
|
||||
"""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)
|
||||
|
||||
def asr_en(self, value=None, delay=700):
|
||||
return self._bits(2, 0x0C, value, delay)
|
||||
|
||||
def uart_select(self, value=None, delay=50):
|
||||
return self._bits(0, 0x03, value, delay)
|
||||
|
||||
def rgb_sync(self, buffer, n=12):
|
||||
self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_RGB, buffer if len(buffer) < n else buffer[:n])
|
||||
|
||||
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))
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
SANT G2 -MixGo SANT EXT G2
|
||||
|
||||
MicroPython library for the SANT G2 (Expansion board for MixGo SANT)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import gc
|
||||
from machine import Pin, SoftI2C
|
||||
|
||||
'''i2c-extboard'''
|
||||
ext_i2c = SoftI2C(scl=Pin(5), sda=Pin(6), freq=400000)
|
||||
|
||||
'''RFID_Sensor'''
|
||||
try :
|
||||
import rc522
|
||||
ext_rfid = rc522.RC522(ext_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with SI522A (RFID) or",e)
|
||||
|
||||
'''RADAR_Sensor'''
|
||||
try :
|
||||
import cbr817
|
||||
ext_mmw = cbr817.CBR817(ext_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with CBR817 (RADAR) or",e)
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
SANT GX -MixGo SANT EXT G3
|
||||
|
||||
MicroPython library for the SANT GX (Expansion board for MixGo SANT)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import gc
|
||||
from machine import Pin, SoftI2C
|
||||
|
||||
'''i2c-extboard'''
|
||||
ext_i2c = SoftI2C(scl=Pin(18), sda=Pin(21), freq=400000)
|
||||
|
||||
'''RFID_Sensor'''
|
||||
try :
|
||||
import rc522
|
||||
ext_rfid = rc522.RC522(ext_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with SI522A (RFID) or",e)
|
||||
|
||||
'''RADAR_Sensor'''
|
||||
try :
|
||||
import cbr817
|
||||
ext_mmw = cbr817.CBR817(ext_i2c)
|
||||
except Exception as e:
|
||||
print("Warning: Failed to communicate with CBR817 (RADAR) or",e)
|
||||
|
||||
'''Reclaim memory'''
|
||||
gc.collect()
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
SANT-TTS
|
||||
|
||||
MicroPython library for the SANT-TTS(暂行)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import gc
|
||||
from esp_tts import TTS
|
||||
from machine import Pin
|
||||
from pwm_audio import PWMAudio
|
||||
from mixgo_sant import onboard_bot
|
||||
|
||||
audio = PWMAudio(Pin(46))
|
||||
tts = TTS()
|
||||
|
||||
def play(text, speed=3):
|
||||
try:
|
||||
onboard_bot.spk_en(1, 100)
|
||||
if tts.parse_chinese(text):
|
||||
audio.start()
|
||||
while True:
|
||||
data = tts.stream_play(speed)
|
||||
if not data:
|
||||
break
|
||||
else:
|
||||
audio.write(data)
|
||||
finally:
|
||||
onboard_bot.spk_en(0)
|
||||
audio.stop()
|
||||
gc.collect()
|
||||
106
mixly/boards/default/micropython_esp32s3/build/lib/soar_bot.py
Normal file
106
mixly/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))
|
||||
103
mixly/boards/default/micropython_esp32s3/build/lib/st7789_bf.py
Normal file
103
mixly/boards/default/micropython_esp32s3/build/lib/st7789_bf.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""
|
||||
ST7789/FrameBuffer
|
||||
|
||||
MicroPython library for the ST7789(TFT-SPI)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
import uframebuf
|
||||
from machine import Pin, PWM
|
||||
|
||||
class ST7789(uframebuf.FrameBuffer_Uincode):
|
||||
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()
|
||||
self.bl_led = bl_pin if callable(bl_pin) else PWM(Pin(bl_pin))
|
||||
self._oneclight = True
|
||||
self._brightness = brightness
|
||||
|
||||
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 [
|
||||
(0x11, None, 120000),
|
||||
(0x36, b'\x00', 10),
|
||||
(0x3A, b'\x05', 10),
|
||||
(0xB2, b'\x1F\x1F\x00\x33\x33', 10),
|
||||
(0xB7, b'\x00', 10),
|
||||
(0xBB, b'\x3F', 10),
|
||||
(0xC0, b'\x2C', 10),
|
||||
(0xC2, b'\x01', 10),
|
||||
(0xC3, b'\x0F', 10),
|
||||
(0xC4, b'\x20', 10),
|
||||
(0xC6, b'\x13', 10),
|
||||
(0xD0, b'\xA4\xA1', 10),
|
||||
(0xD6, b'\xA1', 10),
|
||||
(0xE0, b'\xF0\x06\x0D\x0B\x0A\x07\x2E\x43\x45\x38\x14\x13\x25\x29', 10),
|
||||
(0xE1, b'\xF0\x07\x0A\x08\x07\x23\x2E\x33\x44\x3A\x16\x17\x26\x2C', 10),
|
||||
(0xE4, b'\x1D\x00\x00', 10),
|
||||
(0x21, None, 10),
|
||||
(0x29, None, 10),
|
||||
]:
|
||||
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 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
|
||||
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 show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
if self._oneclight:
|
||||
self.set_brightness(self._brightness)
|
||||
self._oneclight = False
|
||||
self._write(0x2A, b'\x00\x00\x00\xef')
|
||||
self._write(0x2B, b'\x00\x00\x00\xef')
|
||||
self._write(0x2C, self._buffer)
|
||||
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
ST7789/FrameBuffer
|
||||
|
||||
MicroPython library for the ST7789(TFT-SPI)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time
|
||||
import uframebuf
|
||||
from machine import Pin
|
||||
from camera import Image, IMG
|
||||
|
||||
class ST7789(uframebuf.FrameBuffer_Uincode):
|
||||
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)
|
||||
if reset: reset(1, 100)
|
||||
self.font(font_address)
|
||||
self._init()
|
||||
# self.show()
|
||||
self._oneclight = True
|
||||
self._backlight = backlight
|
||||
|
||||
def display(self, data=None, x=None, y=None, scale_width=None, scale_height=None, rotation=0, sync=True):
|
||||
if type(data) is str:
|
||||
data = Image.open(data, scale_width, scale_height, self.width, self.height, rotation=rotation)
|
||||
if sync: self.fill(0x0, sync=False)
|
||||
self.blit_rgb565(data.image, data.width, data.height, x, y)
|
||||
if sync: self.show()
|
||||
|
||||
def screenshot(self, x=0, y=0, w=None, h=None):
|
||||
if (w is None and h is None):
|
||||
return IMG(memoryview(self._buffer), self.width, self.height)
|
||||
else:
|
||||
return IMG(memoryview(self.crop_rgb565(x,y,w,h)), w, h)
|
||||
|
||||
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 _init(self):
|
||||
"""Display initialization configuration"""
|
||||
for cmd, data, delay in [
|
||||
(0x11, None, 120000),
|
||||
(0x36, b'\x00', 50),
|
||||
(0x3A, b'\x05', 50),
|
||||
(0xB2, b'\x1F\x1F\x00\x33\x33', 10),
|
||||
(0xB7, b'\x00', 10),
|
||||
(0xBB, b'\x36', 10),
|
||||
(0xC0, b'\x2C', 10),
|
||||
(0xC2, b'\x01', 10),
|
||||
(0xC3, b'\x13', 10),
|
||||
(0xC4, b'\x20', 10),
|
||||
(0xC6, b'\x13', 10),
|
||||
(0xD0, b'\xA4\xA1', 10),
|
||||
(0xD6, b'\xA1', 10),
|
||||
(0xE0, b'\xF0\x08\x0E\x09\x08\x04\x2F\x33\x45\x36\x13\x12\x2A\x2D', 10),
|
||||
(0xE1, b'\xF0\x0E\x12\x0C\x0A\x15\x2E\x32\x44\x39\x17\x18\x2B\x2F', 10),
|
||||
(0xE4, b'\x1D\x00\x00', 10),
|
||||
(0x21, None, 10),
|
||||
(0x29, None, 10),
|
||||
]:
|
||||
self._write(cmd, data)
|
||||
if delay:
|
||||
time.sleep_us(delay)
|
||||
|
||||
def get_brightness(self):
|
||||
return self._backlight() / 100
|
||||
|
||||
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(0x2A, b'\x00\x00\x00\xef')
|
||||
self._write(0x2B, b'\x00\x00\x00\xef')
|
||||
self._write(0x2C, self._buffer)
|
||||
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
WS2812 RGB(x035)
|
||||
|
||||
Micropython library for the WS2812 NeoPixel-RGB(method inheritance)
|
||||
=======================================================
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
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 __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 __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 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 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)
|
||||
Reference in New Issue
Block a user