Загрузка данных
import framebuf
class SSD1306_RUS:
def __init__(self, width, height, i2c, addr=0x3C):
self.width = width
self.height = height
self.i2c = i2c
self.addr = addr
self.buffer = bytearray(self.width * self.height // 8)
# Наш основной рабочий фреймбуфер для работы с памятью дисплея
self.framebuf = framebuf.FrameBuffer(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
# Компактный русский шрифт (А-Я, урезанный для экономии памяти ESP32)
self.font = {
'⚠️': [0x18, 0x3C, 0x24, 0x66, 0x42, 0x7E, 0x00, 0x00],
'А': [0x3F, 0x48, 0x48, 0x48, 0x3F], 'Б': [0x7F, 0x49, 0x49, 0x49, 0x31],
'В': [0x7F, 0x49, 0x49, 0x49, 0x36], 'Г': [0x7F, 0x01, 0x01, 0x01, 0x01],
'Д': [0x60, 0x3F, 0x21, 0x3F, 0x60], 'Е': [0x7F, 0x49, 0x49, 0x49, 0x41],
'Ж': [0x63, 0x14, 0x08, 0x14, 0x63], 'З': [0x31, 0x49, 0x49, 0x49, 0x26],
'И': [0x7F, 0x10, 0x08, 0x04, 0x7F], 'Й': [0x7F, 0x11, 0x09, 0x05, 0x7F],
'К': [0x7F, 0x08, 0x14, 0x22, 0x41], 'Л': [0x60, 0x1F, 0x01, 0x01, 0x7F],
'М': [0x7F, 0x02, 0x0C, 0x02, 0x7F], 'Н': [0x7F, 0x08, 0x08, 0x08, 0x7F],
'О': [0x3E, 0x41, 0x41, 0x41, 0x3E], 'П': [0x7F, 0x01, 0x01, 0x01, 0x7F],
'Р': [0x7F, 0x09, 0x09, 0x09, 0x06], 'С': [0x3E, 0x41, 0x41, 0x41, 0x22],
'Т': [0x01, 0x01, 0x7F, 0x01, 0x01], 'У': [0x27, 0x48, 0x48, 0x48, 0x3F],
'Ф': [0x1C, 0x22, 0x7F, 0x22, 0x1C], 'Х': [0x63, 0x14, 0x08, 0x14, 0x63],
'Ц': [0x7F, 0x40, 0x40, 0x7F, 0xC0], 'Ч': [0x07, 0x08, 0x08, 0x08, 0x7F],
'Ш': [0x7F, 0x40, 0x7F, 0x40, 0x7F], 'Щ': [0x7F, 0x40, 0x7F, 0x40, 0x7F, 0xC0],
'Ъ': [0x01, 0x7F, 0x48, 0x48, 0x30], 'Ы': [0x7F, 0x48, 0x30, 0x00, 0x7F],
'Ь': [0x7F, 0x48, 0x48, 0x30, 0x00], 'Э': [0x22, 0x49, 0x49, 0x49, 0x3E],
'Ю': [0x7F, 0x08, 0x3E, 0x41, 0x3E], 'Я': [0x46, 0x29, 0x19, 0x09, 0x7F]
}
# Дополнительный микро-буфер для попиксельного увеличения английских букв и цифр
self.tmp_buf = bytearray(8)
self.tmp_fbuf = framebuf.FrameBuffer(self.tmp_buf, 8, 8, framebuf.MONO_VLSB)
def poweron(self):
self.i2c.writeto(self.addr, b'\x00\xAF')
def poweroff(self):
self.i2c.writeto(self.addr, b'\x00\xAE')
def fill(self, col):
self.framebuf.fill(col)
def show(self):
# Строгая адресация памяти под высоту 32 пикселя (команда \x03 в конце)
self.i2c.writeto(self.addr, b'\x00\x21\x00\x7F\x22\x00\x03')
for i in range(0, len(self.buffer), 16):
self.i2c.writeto(self.addr, b'\x40' + self.buffer[i:i+16])
def text_rus(self, text, x, y, size=1):
"""Выводит русский и английский текст с поддержкой масштабирования size=1 или size=2"""
cursor = x
for char in text:
upper_char = char.upper()
# 1. Если это русская буква из нашего встроенного словаря
if upper_char in self.font:
char_data = self.font[upper_char]
for col in range(len(char_data)):
for row in range(8):
if (char_data[col] >> row) & 1:
if size == 2:
# Рисуем жирный пиксель 2х2 для масштаба 2
self.framebuf.fill_rect(cursor + col * 2, y + row * 2, 2, 2, 1)
else:
self.framebuf.pixel(cursor + col, y + row, 1)
cursor += (len(char_data) + 2) * size
# 2. Если это английская буква, цифра или знак (%, @, Па, С)
else:
if size == 2:
# Хитрый и надежный способ: рисуем символ в микро-буфер 8х8
self.tmp_fbuf.fill(0)
self.tmp_fbuf.text(char, 0, 0, 1)
# А потом берем получившуюся картинку и удваиваем её пиксели в большой буфер экрана
for col in range(8):
for row in range(8):
if self.tmp_fbuf.pixel(col, row):
self.framebuf.fill_rect(cursor + col * 2, y + row * 2, 2, 2, 1)
cursor += 16
else:
# Если масштаб обычный мелкий — используем стандартный быстрый вывод
self.framebuf.text(char, cursor, y, 1)
cursor += 8