更新 mini支持讯飞中英文识别大模型,sant增加image对图像处理

This commit is contained in:
dahanzimin
2025-10-27 10:32:44 +08:00
parent f9d3427b20
commit d98b9fb0ed
4 changed files with 465 additions and 425 deletions

View File

@@ -45,7 +45,6 @@ class ASR_WebSocket(Ws_Param):
"domain": "iat",
"language": "zh_cn",
"accent": "mandarin",
"vinfo": 1,
"vad_eos": 1000,
"nbest": 1,
"wbest": 1,
@@ -56,7 +55,10 @@ class ASR_WebSocket(Ws_Param):
self.ws.settimeout(1000)
def _frame(self, status, buf):
return {"status": status, "format": "audio/L16;rate=8000", "audio": str(b64encode(buf), 'utf-8'), "encoding": "raw"}
if status == 0:
return {"common": {"app_id": self.APPID}, "business": self.business, "data": {"status": status, "format": "audio/L16;rate=8000", "audio": str(b64encode(buf), 'utf-8'), "encoding": "raw"}}
else:
return {"data": {"status": status, "format": "audio/L16;rate=8000", "audio": str(b64encode(buf), 'utf-8'), "encoding": "raw"}}
def on_message(self, message):
result = ""
@@ -98,17 +100,16 @@ class ASR_WebSocket(Ws_Param):
if pace: print('=',end ="")
# 第一帧处理
if _state == 0:
d = {"common": {"app_id": self.APPID}, "business": self.business, "data": self._frame(_state, buf)}
d = self._frame(_state, buf)
_state = 1
# 中间帧处理
else:
d = {"data": self._frame(_state, buf)}
d = self._frame(_state, buf)
self.ws.send(json.dumps(d))
#print("------",len(buf), time.ticks_diff(time.ticks_ms(), _star))
if time.ticks_diff(time.ticks_ms(), _star) > timeout:
raise OSError("Timeout pcm read error")
# 最后一帧处理
d = {"data": self._frame(2, b'\x00')}
d = self._frame(2, b'\x00')
self.ws.send(json.dumps(d))
onboard_bot.pcm_en(False) #PCM关闭
if pace: print(']')
@@ -122,6 +123,45 @@ class ASR_WebSocket(Ws_Param):
else:
print("Run error: %s" % (e))
#中英识别大模型
class IAT_WebSocket(ASR_WebSocket):
def __init__(self, APPID, APIKey, APISecret, url='ws://iat.xf-yun.com/v1', accent="mandarin", res_id=None):
super().__init__(APPID, APIKey, APISecret, url)
self.res_id = res_id
self.business = {
"domain": "slm",
"language": "zh_cn",
"accent": accent,
"result": {
"encoding": "utf8",
"compress": "raw",
"format": "plain"
}
}
def _frame(self, status, buf):
if status == 0:
return {"header": {"status": status, "app_id": self.APPID, "res_id": self.res_id}, "parameter": {"iat": self.business}, "payload": {"audio": { "audio": str(b64encode(buf), 'utf-8'), "sample_rate": 8000, "encoding": "raw"}}}
else:
return {"header": {"status": status, "app_id": self.APPID, "res_id": self.res_id}, "payload": {"audio": { "audio": str(b64encode(buf), 'utf-8'), "sample_rate": 8000, "encoding": "raw"}}}
def on_message(self, message):
result = ""
msg = json.loads(message)
code = msg['header']["code"]
if code != 0:
raise AttributeError("%s Code:%s" % (msg['header']["message"], code))
else:
if "payload" in msg:
text = msg["payload"]["result"]["text"]
data = json.loads(b64decode(text).decode())['ws']
for i in data:
for w in i["cw"]:
result += w["w"]
if msg["header"]["status"]== 2:
return result, False
return result, True
#大模型
class LLM_WebSocket(Ws_Param):
Model_url = {

View File

@@ -1,47 +1,73 @@
"""
Camera
MicroPython library for the Camera(Inherit C module)
=======================================================
@dahanzimin From the Mixly Team
"""
import time
import base64
import jpeg
from _camera import *
from jpeg import Encoder
from machine import SoftI2C, Pin
from mixgo_sant import onboard_bot
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 snapshot(self, path=None, formats=0, quality=90, rotation=0):
if formats == 0 and path is None:
return self.capture()
else:
_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:
with open(path, 'wb') as f:
f.write(_jpeg)
return True
"""
Camera
MicroPython library for the Camera(Inherit C module)
=======================================================
@dahanzimin From the Mixly Team
"""
import time
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, 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(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_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, 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", quality=90, rotation=0, **kwargs):
_encoder = Encoder(pixel_format="RGB565_BE", quality=quality, rotation=rotation, width=img.width, height=img.height, **kwargs)
_jpeg = _encoder.encode(img.image)
del _encoder
if isinstance(path, str):
with open(path, 'wb') as f:
f.write(_jpeg)
else:
return _jpeg
def open(self, path="mixly.jpg", rotation=0, **kwargs):
with open(path, "rb") as f:
_jpeg = f.read()
_decoder = Decoder(pixel_format="RGB565_BE", rotation=rotation, **kwargs)
_info = _decoder.get_img_info(_jpeg)
_image = IMG(_decoder.decode(_jpeg), _info[0], _info[1])
del _decoder
return _image
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))
#图像处理
Image = Image()

View File

@@ -1,259 +1,245 @@
"""
mixgo_sant Onboard resources(v1.9)
Micropython library for the mixgo_sant Onboard resources
=======================================================
@dahanzimin From the Mixly Team
"""
from music import MIDI
from ws2812x import NeoPixel
from machine import *
import time
import gc
import st7789_cf
import math
'''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'''
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()
"""
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()

View File

@@ -1,113 +1,101 @@
"""
ST7789/FrameBuffer
MicroPython library for the ST7789(TFT-SPI)
=======================================================
@dahanzimin From the Mixly Team
"""
import time
import uframebuf
from machine import Pin
from jpeg import Decoder
from micropython import const
_CMD_SWRESET = const(0x01)
_CMD_SLPIN = const(0x10)
_CMD_SLPOUT = const(0x11)
_CMD_PTLON = const(0x12)
_CMD_NORON = const(0x13)
_CMD_INVOFF = const(0x20)
_CMD_INVON = const(0x21)
_CMD_DISPOFF = const(0x28)
_CMD_DISPON = const(0x29)
_CMD_CASET = const(0x2A)
_CMD_RASET = const(0x2B)
_CMD_RAMWR = const(0x2C)
_CMD_RAMRD = const(0x2E)
_CMD_PTLAR = const(0x30)
_CMD_VSCRDEF = const(0x33)
_CMD_COLMOD = const(0x3A)
_CMD_MADCTL = const(0x36)
class ST7789(uframebuf.FrameBuffer_Uincode):
def __init__(self, spi, width, height, dc_pin=None, backlight=None, reset=None, font_address=0x700000):
self.spi = spi
self.dc = Pin(dc_pin, Pin.OUT, value=1)
self._buffer = bytearray(width * height * 2)
super().__init__(self._buffer, width, height, uframebuf.RGB565)
reset(1, 100)
self.font(font_address)
self._init()
# self.show()
self._oneclight = True
self._backlight = backlight
def 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
def set_brightness(self, brightness):
if not 0.0 <= brightness <= 1.0:
raise ValueError(
"Brightness must be a decimal number in the range: 0.0~1.0")
self._backlight(int(brightness * 100))
def color(self, red, green=None, blue=None):
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
if green is None or blue is None:
return red
else:
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
def show(self):
"""Refresh the display and show the changes."""
if self._oneclight:
self.set_brightness(0.6)
self._oneclight = False
self._write(_CMD_CASET, b'\x00\x00\x00\xef')
self._write(_CMD_RASET, b'\x00\x00\x00\xef')
self._write(_CMD_RAMWR, self._buffer)
"""
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
from micropython import const
_CMD_SWRESET = const(0x01)
_CMD_SLPOUT = const(0x11)
_CMD_INVON = const(0x21)
_CMD_DISPON = const(0x29)
_CMD_CASET = const(0x2A)
_CMD_RASET = const(0x2B)
_CMD_RAMWR = const(0x2C)
_CMD_COLMOD = const(0x3A)
_CMD_MADCTL = const(0x36)
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)
reset(1, 100)
self.font(font_address)
self._init()
# self.show()
self._oneclight = True
self._backlight = backlight
def display(self, data=None, rotation=0, sync=True):
if type(data) is str:
data = Image.open(data, rotation)
self._buffer[:] = data.image # 后期做图像尺寸匹配处理
if sync: self.show()
def screenshot(self):
return IMG(memoryview(self._buffer), self.width, self.height)
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
def set_brightness(self, brightness):
if not 0.0 <= brightness <= 1.0:
raise ValueError(
"Brightness must be a decimal number in the range: 0.0~1.0")
self._backlight(int(brightness * 100))
def color(self, red, green=None, blue=None):
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
if green is None or blue is None:
return red
else:
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
def show(self):
"""Refresh the display and show the changes."""
if self._oneclight:
self.set_brightness(0.6)
self._oneclight = False
self._write(_CMD_CASET, b'\x00\x00\x00\xef')
self._write(_CMD_RASET, b'\x00\x00\x00\xef')
self._write(_CMD_RAMWR, self._buffer)