from machine import Pin, PWM, SoftI2C
import neopixel
import time
import ssd1306
# --- НАСТРОЙКА ПЕРИФЕРИИ ---
NUM_LEDS = 16
LED_PIN = 13 # Кольцо переехало на пин 13!
BUZZER_PIN = 14
ring = neopixel.NeoPixel(Pin(LED_PIN), NUM_LEDS)
buzzer = PWM(Pin(BUZZER_PIN), freq=440, duty_u16=0)
# Инициализация I2C: SCL жестко на 22, SDA жестко на 21
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# --- СВЯТКОВА МЕЛОДІЯ (Happy Birthday) ---
NOTES = {
'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392, 'A4': 440, 'A#4': 466, 'B4': 494,
'C5': 523, 'D5': 587, 'E5': 659, 'F5': 698, 'G5': 784, 'PAUSE': 0
}
BIRTHDAY_MELODY = [
('G4', 0.2), ('G4', 0.2), ('A4', 0.4), ('G4', 0.4), ('C5', 0.4), ('B4', 0.8),
('G4', 0.2), ('G4', 0.2), ('A4', 0.4), ('G4', 0.4), ('D5', 0.4), ('C5', 0.8),
('G4', 0.2), ('G4', 0.2), ('G5', 0.4), ('E5', 0.4), ('C5', 0.4), ('B4', 0.4), ('A4', 0.4),
('F5', 0.2), ('F5', 0.2), ('E5', 0.4), ('C5', 0.4), ('D5', 0.4), ('C5', 0.8)
]
def wheel(pos):
if pos < 85: return (pos * 3, 255 - pos * 3, 0)
elif pos < 170: return (255 - pos * 3, 0, pos * 3)
else: return (0, pos * 3, 255 - pos * 3)
# --- СТАРТ РОБОТИ ЛИСТІВКИ ---
print("Листівку відкрито! Увімкнення екрана та музики...")
# Виводимо привітання на екран
oled.fill(0) # Очищення екрана
oled.rect(0, 0, 128, 64, 1) # Малюємо красиву рамку по контуру
oled.text(" HAPPY ", 36, 15) # Текст (Координати X, Y)
oled.text("BIRTHDAY!", 28, 30)
oled.text(" * * * * ", 28, 45)
oled.show() # Застосовуємо зміни на OLED
offset = 0
# Програємо один цикл привітання
for note, duration in BIRTHDAY_MELODY:
freq = NOTES[note]
if freq == 0:
buzzer.duty_u16(0)
ring.fill((0, 0, 0))
ring.write()
else:
buzzer.freq(freq)
buzzer.duty_u16(15000)
duration_ms = int(duration * 1000)
steps = duration_ms // 40
for _ in range(steps):
for i in range(NUM_LEDS):
idx = (i * 256 // NUM_LEDS) + offset
ring[i] = wheel(idx & 255)
ring.write()
offset = (offset + 10) % 256
time.sleep_ms(40)
buzzer.duty_u16(0)
time.sleep_ms(30)
# --- ФІНАЛ: ЗАКРИТТЯ ЛИСТІВКИ ---
print("Вітання завершено. Перехід у режим глибокого сну.")
# Плавне згасання вогників кільця
for brightness in range(255, -1, -15):
for i in range(NUM_LEDS):
ring[i] = (0, brightness // 5, brightness // 2)
ring.write()
time.sleep_ms(30)
ring.fill((0, 0, 0))
ring.write()
buzzer.deinit()
# Очищаємо та повністю вимикаем екран (імітація закриття обкладинки)
oled.fill(0)
oled.text("Good Bye...", 24, 28)
oled.show()
time.sleep(1.5)
oled.poweroff() # Апаратне вимкнення матриці OLED для енергозбереження
# Спимо
while True:
time.sleep(1)