from machine import Pin, I2C, PWM
from ssd1306 import SSD1306_I2C
import framebuf, utime
# Setting OLED
pix_res_x = 128
pix_res_y = 64
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000) # ganti sesuai wiring ESP32 kamu
oled = SSD1306_I2C(pix_res_x, pix_res_y, i2c)
# Setting Buzzer pake PWM
speaker = PWM(Pin(15)) # ganti sesuai pin buzzer di ESP32 kamu
speaker.duty(0) # awalnya buzzer mati
# Setting Keypad
rows = [Pin(i, Pin.IN, Pin.PULL_DOWN) for i in (32, 33, 25, 26)]
cols = [Pin(i, Pin.OUT) for i in (27, 14, 12, 13)]
keys = [
['1','2','3','A'],
['4','5','6','B'],
['7','8','9','C'],
['*','0','#','D']
]
password = "040606"
input_pw = ""
# Gambar hati
def draw_heart(oled, x, y):
heart = bytearray([
0b00000000, 0b00000000, 0b00000000,
0b00001110, 0b00001110, 0b00000000,
0b00011111, 0b10011111, 0b00000000,
0b00111111, 0b11111111, 0b10000000,
0b01111111, 0b11111111, 0b11000000,
0b01111111, 0b11111111, 0b11000000,
0b01111111, 0b11111111, 0b11000000,
0b00111111, 0b11111111, 0b10000000,
0b00011111, 0b11111111, 0b00000000,
0b00001111, 0b11111110, 0b00000000,
0b00000111, 0b11111100, 0b00000000,
0b00000011, 0b11111000, 0b00000000,
0b00000001, 0b11110000, 0b00000000,
0b00000000, 0b11100000, 0b00000000,
0b00000000, 0b01000000, 0b00000000
])
fb = framebuf.FrameBuffer(heart, 24, 15, framebuf.MONO_HLSB)
oled.blit(fb, x, y)
# Nada Happy Birthday
melody = [
(262, 0.3), (262, 0.3), (294, 0.4), (262, 0.4), (349, 0.4), (330, 0.5),
(262, 0.3), (262, 0.3), (294, 0.4), (262, 0.4), (392, 0.4), (349, 0.5),
(262, 0.3), (262, 0.3), (523, 0.4), (440, 0.4), (349, 0.4), (330, 0.4), (294, 0.5),
(466, 0.3), (466, 0.3), (440, 0.4), (349, 0.4), (392, 0.4), (349, 0.5)
]
def play_happy_birthday():
for note, duration in melody:
speaker.freq(note)
speaker.duty(512) # setengah duty cycle
utime.sleep(duration)
speaker.duty(0) # matikan suara
utime.sleep(0.01) # jeda antar nada
# Baca tombol keypad
def read_key():
for col_num, col in enumerate(cols):
col.value(1)
for row_num, row in enumerate(rows):
if row.value():
utime.sleep(0.3) # debounce
col.value(0)
return keys[row_num][col_num]
col.value(0)
return None
# Tampilan awal OLED
oled.fill(0)
oled.text("Password:", 5, 10)
oled.show()
# Proses input password
while True:
key = read_key()
if key:
if key == '#': # Submit password
if input_pw == password:
for i in range(10, -1, -1):
oled.fill(0)
oled.text("Make a Wish", 23, 8)
oled.text("Sayang", 38, 25)
oled.text(str(i), 60, 41)
oled.show()
utime.sleep(1)
oled.fill(0)
draw_heart(oled, 100, 50)
draw_heart(oled, 100, 25)
draw_heart(oled, 100, 0)
oled.text("Happy", 5, 8)
oled.text("Birthday", 5, 25)
oled.text("Sayang <3", 5, 40)
oled.show()
play_happy_birthday() # Mainkan lagu
else:
oled.fill_rect(0, 50, 128, 14, 0)
oled.text("Salah! Coba lagi", 5, 52)
oled.show()
input_pw = ""
utime.sleep(1.5)
oled.fill_rect(0, 50, 128, 14, 0)
elif key == '*': # Reset
input_pw = ""
oled.fill_rect(0, 30, 128, 20, 0)
oled.show()
else:
if len(input_pw) < 6:
input_pw += key
oled.fill_rect(0, 30, 128, 20, 0)
oled.text("*" * len(input_pw), 5, 35)
oled.show()