Загрузка данных
from machine import import Pin, I2C
import ssd1306
import time
# ==========================================
# # НАСТРОЙКИ
# ==========================================
OLED_WIDTH = 128
OLED_HEIGHT = 64
OLED_ADDRESS = 0x3C
# Тексты можно менять здесь.
# Стандартный шрифт SSD1306 поддерживает только латинские символы.
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"
TEXT_BUTTON_4 = "kto prochital tot nigadai"
# Период защиты от дребезга кнопок, миллисекунды
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,
TEXT_BUTTON_4
]
# Последнее мгновенное состояние кнопок
last_raw_states = [button.value() for button in button_pins]
# Подтвержденное стабильное состояние кнопок
stable_states = last_raw_states[:]
# Время последнего изменения мгновенного состояния
change_times = [time.ticks_ms()] * len(button_pins)
# ==========================================
# # РАБОТА С ТЕКСТОМ
# ==========================================
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):
"""
Переносит текст по словам.
Для OLED 128x64:
128 / 8 = 16 символов в строке
64 / 8 = 8 строк
"""
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
oled.fill(0)
# Получаем строки с переносом
lines = wrap_text(text)
# На экране 128x64 помещается максимум 8 строк
max_lines = OLED_HEIGHT // 8
for line_number, line in enumerate(lines[:max_lines]):
y = line_number * 8
oled.text(line, 0, y)
# Передача изображения на OLED
oled.show()
def clear_screen():
"""
Полностью очищает дисплей.
"""
oled.fill(0)
oled.show()
# ==========================================
# # ЗАПУСК
# ==========================================
clear_screen()
show_text(START_TEXT)
# Небольшая задержка после стартовой надписи
time.sleep_ms(500)
# Переменные для режима часов
show_time_mode = False
last_time_update = 0
# ==========================================
# # ГЛАВНЫЙ ЦИКЛ
# ==========================================
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
# Кнопка нажата: состояние LOW (0)
if stable_states[index] == 0:
if index == 2: # Если нажата 3-я кнопка (индекс 2)
show_time_mode = not show_time_mode # Переключаем режим часов
if not show_time_mode:
show_text("Menu closed") # Надпись при закрытии часов
else:
show_time_mode = False # Любая другая кнопка отключает часы
show_text(button_texts[index])
# Динамическое обновление времени каждую секунду
if show_time_mode and time.ticks_diff(now, last_time_update) >= 1000:
last_time_update = now
t = time.localtime() # Получаем текущее время контроллера
# Форматируем красивое меню с часами
time_str = " TIME MENU\n\n {:02d}:{:02d}:{:02d}".format(t[3], t[4], t[5])
show_text(time_str)
# Короткая пауза, чтобы не загружать процессор
time.sleep_ms(5)