更新其他后台播放音乐,C3支持v1.25.0,修改sant的es-dl
This commit is contained in:
@@ -3,14 +3,9 @@ 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
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import _thread, gc
|
||||
from time import sleep_ms
|
||||
from machine import Pin, PWM
|
||||
|
||||
@@ -30,13 +25,15 @@ Letter = 'ABCDEFG#R'
|
||||
class MIDI():
|
||||
def __init__(self, pin, volume=100, invert=0, pa_ctrl=None):
|
||||
self.reset()
|
||||
self._invert=invert
|
||||
self._invert = invert
|
||||
self._pin = pin
|
||||
self._volume = volume
|
||||
self._play = False
|
||||
self._over = True
|
||||
self._pwm = None
|
||||
self._pa_ctrl = pa_ctrl
|
||||
|
||||
def set_volume(self,volume):
|
||||
def set_volume(self, volume):
|
||||
if not 0 <= volume <= 100:
|
||||
raise ValueError("Volume value is in the range: 0-100")
|
||||
self._volume=volume
|
||||
@@ -97,45 +94,60 @@ class MIDI():
|
||||
self.set_duration(int(tone[(pos + 1):]))
|
||||
tone = tone[:pos]
|
||||
|
||||
def play(self, tune, duration=None):
|
||||
if self._pa_ctrl: self._pa_ctrl(1)
|
||||
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)
|
||||
self._play = True
|
||||
self._over = False
|
||||
if duration is None:
|
||||
self.set_default(tune[0])
|
||||
else:
|
||||
self.set_duration(duration)
|
||||
for tone in tune:
|
||||
tone = tone.upper()
|
||||
if not self._play:
|
||||
break
|
||||
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])
|
||||
if self._play: self._pwm.duty((1023-self._volume) if self._invert else self._volume)
|
||||
if self._play: self._pwm.freq(midi[0])
|
||||
sleep_ms(midi[1])
|
||||
self._pwm.freq(400000)
|
||||
if self._play: self._pwm.freq(400000)
|
||||
sleep_ms(1)
|
||||
if self._pa_ctrl: self._pa_ctrl(0)
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
self._over = True
|
||||
|
||||
def pitch(self, freq):
|
||||
if self._pa_ctrl: self._pa_ctrl(1)
|
||||
def play_thread(self, tune, duration=None, pa_delay=100):
|
||||
self._play = False
|
||||
while not self._over:
|
||||
sleep_ms(10)
|
||||
if not self._play:
|
||||
gc.collect()
|
||||
_thread.start_new_thread(self.play, (tune, duration, pa_delay))
|
||||
sleep_ms(100)
|
||||
|
||||
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.duty((1023-self._volume) if self._invert else self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
|
||||
def pitch_time(self, freq, delay):
|
||||
if self._pa_ctrl: self._pa_ctrl(1)
|
||||
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.duty((1023-self._volume) if self._invert else self._volume)
|
||||
self._pwm.freq(int(freq))
|
||||
sleep_ms(delay)
|
||||
if self._pa_ctrl: self._pa_ctrl(0)
|
||||
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)
|
||||
self._play = False
|
||||
if self._pa_ctrl: self._pa_ctrl(0, 0)
|
||||
if self._pwm: self._pwm.deinit()
|
||||
sleep_ms(10)
|
||||
|
||||
|
||||
@@ -553,15 +553,17 @@ class FrameBuffer_Uincode(FrameBuffer_Base):
|
||||
self.show()
|
||||
time.sleep_ms(speed)
|
||||
|
||||
def qrcode(self, data, x=0, y=0, size=None, bold=0, type=None, correct=0, color=0xffff, bg_color=0x0, sync=True):
|
||||
def qrcode(self, data, x=None, y=None, size=None, bold=0, type=None, correct=0, color=0xffff, bg_color=0x0, sync=True):
|
||||
if self._miniqr is None:
|
||||
from adafruit_miniqr import QRCode
|
||||
self._miniqr = QRCode
|
||||
_qr = self._miniqr(qr_type=type, error_correct=correct)
|
||||
_qr.add_data(data)
|
||||
_qr.add_data(str(data))
|
||||
_qr.make()
|
||||
if sync: self.fill(bg_color, sync=False)
|
||||
size = min(self.height // _qr.matrix.height, self.width // _qr.matrix.width) if size is None else size
|
||||
x = (self.width - _qr.matrix.width * size) // 2 if x is None else x
|
||||
y = (self.height - _qr.matrix.height * size) // 2 if y is None else y
|
||||
for j in range(_qr.matrix.height):
|
||||
for i in range(_qr.matrix.width):
|
||||
if _qr.matrix[i, j]:
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
"""
|
||||
MixGo CC -Onboard resources
|
||||
MixGo CC Onboard resources
|
||||
|
||||
MicroPython library for the MixGo CC -Onboard resources
|
||||
MicroPython library for the MixGo CC Onboard resources
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20221010
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time, gc
|
||||
from machine import Pin, SoftI2C, ADC, PWM, RTC
|
||||
from machine import *
|
||||
|
||||
'''i2c-onboard'''
|
||||
onboard_i2c=SoftI2C(scl = Pin(7), sda = Pin(6), freq = 400000)
|
||||
@@ -95,7 +92,7 @@ onboard_rgb = NeoPixel(Pin(8), 4, ORDER=(0, 1, 2, 3))
|
||||
|
||||
'''1Buzzer-Music'''
|
||||
from music import MIDI
|
||||
onboard_music =MIDI(10)
|
||||
onboard_music = MIDI(10)
|
||||
|
||||
'''MIC_Sensor'''
|
||||
class MICSensor:
|
||||
@@ -119,20 +116,23 @@ class MICSensor:
|
||||
|
||||
onboard_sound = MICSensor(pin=4 if version else 3)
|
||||
|
||||
'''4,5KEY_Sensor'''
|
||||
'''5KEY_Sensor'''
|
||||
class KEYSensor:
|
||||
def __init__(self, pin, range):
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_11DB)
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_11DB)
|
||||
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 - 300) < min(sorted(values)[25:]) < (self.range + 300)
|
||||
for _ in range(25):
|
||||
try:
|
||||
values.append(self.adc.read())
|
||||
except: #IDF>5.2.2存在ADC2问题
|
||||
pass
|
||||
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
|
||||
@@ -148,7 +148,7 @@ class KEYSensor:
|
||||
def was_pressed(self):
|
||||
if(self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag :
|
||||
if self.flag:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@@ -156,34 +156,15 @@ class KEYSensor:
|
||||
def irq(self, handler, trigger):
|
||||
Pin(self.pin, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
'''2,1KEY_Button'''
|
||||
class Button:
|
||||
'''1KEY_Button'''
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = Pin(pin, Pin.IN)
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def get_presses(self, delay = 1):
|
||||
last_time,presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep(0.05)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def is_pressed(self):
|
||||
return not self.pin.value()
|
||||
|
||||
def was_pressed(self, flag = 0):
|
||||
if(self.pin.value() != self.flag):
|
||||
self.flag = self.pin.value()
|
||||
time.sleep(0.02)
|
||||
if self.flag:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
self.pin.irq(handler = handler, trigger = trigger)
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
if version==0:
|
||||
B1key = Button(9)
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
"""
|
||||
MixGo ME -Onboard resources
|
||||
MixGo ME Onboard resources
|
||||
|
||||
MicroPython library for the MixGo ME -Onboard resources
|
||||
MicroPython library for the MixGo ME Onboard resources
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20221010
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
|
||||
import time, gc
|
||||
from machine import Pin, SoftI2C, ADC, PWM, RTC
|
||||
from machine import *
|
||||
|
||||
'''i2c-onboard'''
|
||||
onboard_i2c=SoftI2C(scl = Pin(7), sda = Pin(6), freq = 400000)
|
||||
@@ -52,7 +48,7 @@ onboard_rgb = NeoPixel(Pin(9), 2, ORDER=(0, 1, 2, 3), multiplex=1)
|
||||
|
||||
'''1Buzzer-Music'''
|
||||
from music import MIDI
|
||||
onboard_music =MIDI(10)
|
||||
onboard_music = MIDI(10)
|
||||
|
||||
'''MIC_Sensor'''
|
||||
class MICSensor:
|
||||
@@ -78,17 +74,21 @@ onboard_sound = MICSensor()
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
class KEYSensor:
|
||||
def __init__(self,range):
|
||||
self.adc=ADC(Pin(5), atten=ADC.ATTN_11DB)
|
||||
self.range=range
|
||||
def __init__(self, pin, range):
|
||||
self.pin = pin
|
||||
self.adc = ADC(Pin(pin), atten=ADC.ATTN_11DB)
|
||||
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 - 300) < min(sorted(values)[25:]) < (self.range + 300)
|
||||
for _ in range(25):
|
||||
try:
|
||||
values.append(self.adc.read())
|
||||
except: #IDF>5.2.2存在ADC2问题
|
||||
pass
|
||||
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
|
||||
@@ -104,50 +104,30 @@ class KEYSensor:
|
||||
def was_pressed(self):
|
||||
if(self._value() != self.flag):
|
||||
self.flag = self._value()
|
||||
if self.flag :
|
||||
if self.flag:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
Pin(5, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
B2key = KEYSensor(20)
|
||||
A1key = KEYSensor(800)
|
||||
A2key = KEYSensor(1600)
|
||||
A3key = KEYSensor(2500)
|
||||
A4key = KEYSensor(3500)
|
||||
Pin(self.pin, Pin.IN).irq(handler = handler, trigger = trigger)
|
||||
|
||||
'''1KEY_Button'''
|
||||
class Button:
|
||||
class Button(KEYSensor):
|
||||
def __init__(self, pin):
|
||||
self.pin = Pin(pin, Pin.IN)
|
||||
self.pin = pin
|
||||
self.key = Pin(pin, Pin.IN)
|
||||
self.flag = True
|
||||
|
||||
def get_presses(self, delay = 1):
|
||||
last_time,presses = time.time(), 0
|
||||
while time.time() < last_time + delay:
|
||||
time.sleep(0.05)
|
||||
if self.was_pressed():
|
||||
presses += 1
|
||||
return presses
|
||||
|
||||
def is_pressed(self):
|
||||
return not self.pin.value()
|
||||
|
||||
def was_pressed(self, flag = 0):
|
||||
if(self.pin.value() != self.flag):
|
||||
self.flag = self.pin.value()
|
||||
time.sleep(0.02)
|
||||
if self.flag:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def irq(self, handler, trigger):
|
||||
self.pin.irq(handler = handler, trigger = trigger)
|
||||
def _value(self):
|
||||
return not self.key.value()
|
||||
|
||||
B1key = Button(9)
|
||||
B2key = KEYSensor(5,20)
|
||||
A1key = KEYSensor(5,800)
|
||||
A2key = KEYSensor(5,1600)
|
||||
A3key = KEYSensor(5,2500)
|
||||
A4key = KEYSensor(5,3500)
|
||||
|
||||
'''2LED-Multiplex RGB'''
|
||||
class LED:
|
||||
|
||||
@@ -3,13 +3,10 @@ MixGo CAR -Onboard resources
|
||||
|
||||
MicroPython library for the MixGo CAR (ESP32C3)
|
||||
=======================================================
|
||||
|
||||
#Preliminary composition 20220804
|
||||
|
||||
dahanzimin From the Mixly Team
|
||||
@dahanzimin From the Mixly Team
|
||||
"""
|
||||
import time,gc,ms32006
|
||||
from machine import Pin,SoftI2C,ADC,RTC
|
||||
from machine import *
|
||||
|
||||
'''RTC'''
|
||||
rtc_clock=RTC()
|
||||
@@ -17,7 +14,7 @@ rtc_clock=RTC()
|
||||
'''i2c-onboard'''
|
||||
onboard_i2c=SoftI2C(scl = Pin(7), sda = Pin(6), freq = 400000)
|
||||
|
||||
'''4RGB_WS2812''' #color_chase(),rainbow_cycle()方法移至类里
|
||||
'''4RGB_WS2812'''
|
||||
from ws2812 import NeoPixel
|
||||
onboard_rgb = NeoPixel(Pin(8), 4, ORDER=(0, 1, 2, 3))
|
||||
|
||||
|
||||
@@ -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,45 @@
|
||||
"""
|
||||
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 base64, 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
|
||||
|
||||
@@ -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]
|
||||
@@ -17,6 +17,9 @@ rtc_clock = RTC()
|
||||
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
|
||||
@@ -25,7 +28,7 @@ except Exception as 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 :
|
||||
@@ -73,7 +76,7 @@ from ws2812x import NeoPixel
|
||||
onboard_rgb = NeoPixel(onboard_bot.rgb_sync, 4)
|
||||
|
||||
'''1Buzzer-Music'''
|
||||
from musicx import MIDI
|
||||
from music import MIDI
|
||||
onboard_music = MIDI(46, pa_ctrl=onboard_bot.spk_en)
|
||||
|
||||
'''5KEY_Sensor'''
|
||||
|
||||
@@ -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()
|
||||
@@ -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']
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -1,29 +1,89 @@
|
||||
"""
|
||||
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
|
||||
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
|
||||
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.show()
|
||||
self._init()
|
||||
# self.show()
|
||||
self._oneclight = True
|
||||
self._backlight = backlight
|
||||
if backlight: self.set_brightness(0.5)
|
||||
|
||||
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 _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 [
|
||||
##(_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 get_brightness(self):
|
||||
return self._backlight() / 100
|
||||
@@ -40,9 +100,11 @@ class ST7789(uframebuf.FrameBuffer_Uincode):
|
||||
else:
|
||||
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
||||
|
||||
def picture(self, x, y, path):
|
||||
self.display.Picture(x, y, path)
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
self.display.write_buf(self._buffer, 0, 0, self._width, self._height)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user