from machine import Pin
import utime
# ===================== SWITCH ======================
switch = Pin(2, Pin.IN, Pin.PULL_DOWN)
def wait_until_switch_on():
while switch.value() == 0:
utime.sleep(0.05)
# ===================== FORCE RESET KEYPAD ======================
def reset_keypad():
for r in keypad_rows:
r.low()
utime.sleep(0.05)
# ===================== LCD ======================
class LCD:
def __init__(self, rs, en, d4, d5, d6, d7):
self.rs = Pin(rs, Pin.OUT)
self.en = Pin(en, Pin.OUT)
self.data_pins = [Pin(d4, Pin.OUT), Pin(d5, Pin.OUT), Pin(d6, Pin.OUT), Pin(d7, Pin.OUT)]
self.init_lcd()
def pulse_enable(self):
self.en.value(1)
utime.sleep_us(40)
self.en.value(0)
utime.sleep_us(40)
def send_nibble(self, data):
for i in range(4):
self.data_pins[i].value((data >> i) & 1)
self.pulse_enable()
def send_byte(self, data, mode):
self.rs.value(mode)
self.send_nibble(data >> 4)
self.send_nibble(data & 0x0F)
utime.sleep_ms(2)
def command(self, cmd):
self.send_byte(cmd, 0)
def write_char(self, char):
self.send_byte(ord(char), 1)
def clear(self):
self.command(0x01)
utime.sleep_ms(2)
def move_to(self, col, row):
pos = col + 0x40 * row
self.command(0x80 | pos)
def putstr(self, string):
for char in string:
self.write_char(char)
def init_lcd(self):
utime.sleep_ms(20)
self.command(0x33)
self.command(0x32)
self.command(0x28)
self.command(0x0C)
self.command(0x06)
self.command(0x01)
utime.sleep_ms(5)
# ===================== LCD & KEYPAD ======================
lcd = LCD(rs=16, en=13, d4=19, d5=20, d6=21, d7=26)
keypad_rows = [Pin(pin, Pin.OUT) for pin in [28, 22, 27, 18]]
keypad_columns = [Pin(pin, Pin.IN, Pin.PULL_DOWN) for pin in [17, 15, 14, 4]]
keys = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
password = "1234"
input_buffer = ""
is_unlocked = False
# ===================== READ KEYPAD ======================
def read_keypad():
for row in range(4):
keypad_rows[row].high()
utime.sleep_us(400)
for col in range(4):
if keypad_columns[col].value() == 1:
keypad_rows[row].low()
return keys[row][col]
keypad_rows[row].low()
return None
# ===================== PASSWORD SCREEN ======================
def request_password():
global input_buffer, is_unlocked
is_unlocked = False
input_buffer = ""
lcd.clear()
lcd.putstr("Enter Password:")
while True:
# --- SWITCH CHECK ---
if switch.value() == 0:
lcd.clear()
reset_keypad()
wait_until_switch_on()
lcd.init_lcd() # reinitialize LCD
reset_keypad()
lcd.putstr("Enter Password:")
input_buffer = ""
continue
# ---------------------
key = read_keypad()
if key:
if key == '#': # ENTER
if input_buffer == password:
lcd.clear()
lcd.putstr("Unlocked!")
utime.sleep(2)
return True
else:
lcd.clear()
lcd.putstr("Wrong Password!")
utime.sleep(2)
lcd.clear()
lcd.putstr("Enter Password:")
input_buffer = ""
elif key == '*': # CLEAR
input_buffer = ""
lcd.clear()
lcd.putstr("Enter Password:")
else:
input_buffer += key
lcd.move_to(0, 1)
lcd.putstr('*' * len(input_buffer))
utime.sleep(0.25)
# ===================== TEXT ENTRY MODE ======================
def enter_text():
global input_buffer
input_buffer = ""
lcd.clear()
lcd.putstr("Enter Text:")
while True:
if switch.value() == 0:
lcd.clear()
reset_keypad()
wait_until_switch_on()
lcd.init_lcd()
return # go back to main loop → ask password again
key = read_keypad()
if key:
if key == '#':
lcd.clear()
lcd.putstr(input_buffer)
input_buffer = ""
elif key == '*':
input_buffer = ""
lcd.clear()
lcd.putstr("Enter Text:")
else:
input_buffer += key
lcd.move_to(0, 1)
lcd.putstr(input_buffer)
utime.sleep(0.25)
# ======================= MAIN LOOP =========================
try:
while True:
wait_until_switch_on()
reset_keypad()
if request_password(): # when unlocked
enter_text()
except KeyboardInterrupt:
lcd.clear()
print("Program interrupted.")