Загрузка данных


from machine import Pin, I2C
import ssd1306
import time
import math

# НАСТРОЙКИ
OLED_WIDTH = 128
OLED_HEIGHT = 64
OLED_ADDRESS = 0x3C

START_TEXT = "Najimai lubuiu knopky"

TEXT_BUTTON_1 = "a/(sin a)=b/(sin b)=c/(sin c)=2R|a^2=b^2+c^2-2bc*cosa..."
TEXT_BUTTON_2 = "blablabla super puper poleznaya formula"
TEXT_BUTTON_3 = "predstavte budto zdes chtoto ochen vajnoe"

DEBOUNCE_MS = 50

# ИНИЦИАЛИЗАЦИЯ OLED
i2c = I2C(
    0,
    scl=Pin(22),
    sda=Pin(21),
    freq=400000
)

oled = ssd1306.SSD1306_I2C(OLED_WIDTH, OLED_HEIGHT, i2c, addr=OLED_ADDRESS)

# ИНИЦИАЛИЗАЦИЯ КНОПОК
button_pins = [
    Pin(13, Pin.IN, Pin.PULL_UP),
    Pin(14, Pin.IN, Pin.PULL_UP),
    Pin(25, Pin.IN, Pin.PULL_UP),
    Pin(26, Pin.IN, Pin.PULL_UP)
]

button_texts = [TEXT_BUTTON_1, TEXT_BUTTON_2, TEXT_BUTTON_3]

last_raw_states = [button.value() for button in button_pins]
stable_states = last_raw_states[:]
change_times = [time.ticks_ms()] * len(button_pins)

# НАСТРОЙКИ И ПЕРЕМЕННЫЕ ДЛЯ 3D-КУБА
cube_size = 20
width_offset = OLED_WIDTH // 2
height_offset = OLED_HEIGHT // 2
angle_x = 0.0
angle_y = 0.0
angle_z = 0.0

vertices = [
    [-cube_size, -cube_size,  cube_size],
    [ cube_size, -cube_size,  cube_size],
    [ cube_size,  cube_size,  cube_size],
    [-cube_size,  cube_size,  cube_size],
    [-cube_size, -cube_size, -cube_size],
    [ cube_size, -cube_size, -cube_size],
    [ cube_size,  cube_size, -cube_size],
    [-cube_size,  cube_size, -cube_size]
]

cube_active = False

def draw_cube():
    global angle_x, angle_y, angle_z
    oled.fill(0)
    projected = []
    
    for vertex in vertices:
        x, y, z = vertex
        
        y1 = y * math.cos(angle_x) - z * math.sin(angle_x)
        z1 = y * math.sin(angle_x) + z * math.cos(angle_x)
        x2 = x * math.cos(angle_y) + z1 * math.sin(angle_y)
        z2 = -x * math.sin(angle_y) + z1 * math.cos(angle_y)
        x3 = x2 * math.cos(angle_z) - y1 * math.sin(angle_z)
        y3 = x2 * math.sin(angle_z) + y1 * math.cos(angle_z)
        
        distance = 50.0
        perspective = distance / (distance + z2)
        
        px = int(width_offset + x3 * perspective)
        py = int(height_offset + y3 * perspective)
        projected.append((px, py))
        
    for i in range(4):
        oled.line(projected[i][0], projected[i][1], projected[(i+1)%4][0], projected[(i+1)%4][1], 1)
        oled.line(projected[i+4][0], projected[i+4][1], projected[((i+1)%4)+4][0], projected[((i+1)%4)+4][1], 1)
        oled.line(projected[i][0], projected[i][1], projected[i+4][0], projected[i+4][1], 1)
        
    oled.show()
    
    angle_x += 0.04
    angle_y += 0.06
    angle_z += 0.02

# РАБОТА С ТЕКСТОМ
def split_long_word(word, max_chars):
    parts = []
    while len(word) > max_chars:
        parts.append(word[:max_chars])
        word = word[max_chars:]
    if word:
        parts.append(word)
    return parts

def wrap_text(text, max_chars=16):
    words = text.split()
    lines = []
    current_line = ""
    
    for word in words:
        if len(word) > max_chars:
            if current_line:
                lines.append(current_line)
                current_line = ""
            long_word_parts = split_long_word(word, max_chars)
            for part in long_word_parts:
                lines.append(part)
        else:
            if current_line == "":
                current_line = word
            elif len(current_line) + 1 + len(word) <= max_chars:
                current_line += " " + word
            else:
                lines.append(current_line)
                current_line = word
    if current_line:
        lines.append(current_line)
    return lines

def show_text(text):
    oled.fill(0)
    lines = wrap_text(text)
    max_lines = OLED_HEIGHT // 8
    
    for line_number, line in enumerate(lines[:max_lines]):
        y = line_number * 8
        oled.text(line, 0, y)
    oled.show()

def clear_screen():
    oled.fill(0)
    oled.show()

# ЗАПУСК
clear_screen()
show_text(START_TEXT)
time.sleep_ms(500)

# ГЛАВНЫЙ ЦИКЛ
while True:
    now = time.ticks_ms()
    
    for index, button in enumerate(button_pins):
        raw_state = button.value()
        
        if raw_state != last_raw_states[index]:
            last_raw_states[index] = raw_state
            change_times[index] = now
            
        elif time.ticks_diff(now, change_times[index]) >= DEBOUNCE_MS:
            if stable_states[index] != raw_state:
                stable_states[index] = raw_state
                
                if stable_states[index] == 0:
                    if index == 3:
                        cube_active = True
                    else:
                        cube_active = False
                        show_text(button_texts[index])
                        
    if cube_active:
        draw_cube()
    else:
        time.sleep_ms(5)