from machine import Pin, PWM
import time
# Configuration constants - Replace YOUR_ID_HERE with your actual ID number
secretCode = '21906322' # Example ID, please replace
MAX_ATTEMPTS = 3 # Maximum number of attempts
LOCKDOWN_TIME = 10 # Lockdown time (seconds)
# Global variables
isLocked = False # Initial state: unlocked
inbuffer = "--------" # Input buffer
attempts = 0 # Current number of attempts
last_failed_time = 0 # Time of last failed attempt
last_key_time = 0 # Time of last key press (for debouncing)
# Define keypad matrix layout (4x3)
# Key mapping:
# 1 2 3
# 4 5 6
# 7 8 9
# * 0 #
keymap = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['*', '0', '#']
]
# Initialize pins
# Row pins (output)
row_pins = [
Pin(26, Pin.OUT),
Pin(22, Pin.OUT),
Pin(21, Pin.OUT),
Pin(20, Pin.OUT)
]
# Column pins (input with pull-up resistor)
col_pins = [
Pin(19, Pin.IN, Pin.PULL_UP),
Pin(18, Pin.IN, Pin.PULL_UP),
Pin(17, Pin.IN, Pin.PULL_UP)
]
# Initialize servo motor (GPIO15)
servo = PWM(Pin(15))
servo.freq(50) # 50Hz frequency for servo motor
# Initialize LEDs (Red:GPIO5, Green:GPIO9)
led_red = Pin(5, Pin.OUT)
led_green = Pin(9, Pin.OUT)
# Set initial LED state
led_red.value(0)
led_green.value(1) # Green LED on for unlocked state
# Servo motor control function
def set_servo_angle(angle):
"""Set servo motor angle (0 degrees: locked, 90 degrees: unlocked)"""
# Convert angle to PWM duty cycle (500-2500us)
min_duty = 500 # 0 degrees
max_duty = 2500 # 180 degrees
duty_us = int(min_duty + (angle / 180) * (max_duty - min_duty))
duty_ns = duty_us * 1000 # Convert to nanoseconds
# Calculate duty cycle (0-65535)
period_ns = 20000000 # 20ms period
duty = int((duty_ns * 65535) / period_ns)
servo.duty_u16(duty)
# System lock function
def lock_system():
"""Lock the system"""
global isLocked
isLocked = True
set_servo_angle(0) # Move servo to locked position
led_red.value(1) # Turn on red LED
led_green.value(0) # Turn off green LED
print("\n" + "="*40)
print("STATE = LOCKED")
print("="*40)
print("Enter 8-digit code and press *")
print("Current input: ________")
# System unlock function
def unlock_system():
"""Unlock the system"""
global isLocked, attempts
isLocked = False
attempts = 0 # Reset attempt counter
set_servo_angle(90) # Move servo to unlocked position
led_red.value(0) # Turn off red LED
led_green.value(1) # Turn on green LED
print("\n" + "="*40)
print("STATE = UNLOCKED")
print("="*40)
print("Press * to lock the system")
# Check if in lockdown period
def is_in_lockdown():
"""Check if the system is in lockdown period"""
global attempts
if attempts >= MAX_ATTEMPTS:
current_time = time.time()
elapsed = current_time - last_failed_time
if elapsed < LOCKDOWN_TIME:
remaining = int(LOCKDOWN_TIME - elapsed)
if remaining % 5 == 0 or remaining == LOCKDOWN_TIME-1: # Reduce output frequency
print(f"\rSystem locked. Wait {remaining:2d}s...", end="")
return True
else:
# Lockdown period ended, reset attempt counter
attempts = 0
print("\n\nLockdown period ended. You may try again.")
if isLocked:
print("Enter 8-digit code and press *")
print("Current input: ________")
return False
# Process key input
def process_key(key):
"""Process key press input"""
global isLocked, inbuffer, attempts, last_failed_time, last_key_time
current_time = time.time()
# Debounce handling: prevent duplicate key triggers
if current_time - last_key_time < 0.3: # 300ms debounce
return
last_key_time = current_time
print(f"\nKey pressed: {key}")
# Check if in lockdown period
if attempts >= MAX_ATTEMPTS and is_in_lockdown():
return
# Process key based on system state
if isLocked:
if key == '*': # User attempts to unlock
print(f"Checking code: {inbuffer}")
if inbuffer == secretCode: # Correct code
print("✓ Code correct!")
unlock_system()
else:
attempts += 1
last_failed_time = time.time()
print(f"✗ Incorrect code! Attempt {attempts}/{MAX_ATTEMPTS}")
if attempts >= MAX_ATTEMPTS:
print(f"\n🔒 SYSTEM LOCKDOWN ACTIVATED!")
print(f" Please wait {LOCKDOWN_TIME} seconds")
print(" " + "⏳" * 10)
else:
remaining_attempts = MAX_ATTEMPTS - attempts
print(f" {remaining_attempts} attempt(s) remaining")
inbuffer = "--------" # Reset input buffer
if attempts < MAX_ATTEMPTS:
print("Current input: ________")
else: # Input digit
# Shift buffer and add new digit
inbuffer = inbuffer[1:] + key
# Display masked input
masked = ""
for char in inbuffer:
if char == '-':
masked += '_'
else:
masked += '*'
print(f"Current input: {masked}")
elif key == '*': # Press * to lock when unlocked
lock_system()
elif key == '#': # Special function key (extendable)
print("\nSpecial functions:")
print("1. Show current code")
print("2. Reset attempts counter")
print("# key pressed in unlocked state")
# Scan keypad matrix
def scan_keypad():
"""Scan keypad matrix to detect key presses"""
for row in range(4):
# Set current row to LOW, others to HIGH
for r in range(4):
row_pins[r].value(1 if r != row else 0)
# Short delay for signal stabilization
time.sleep_us(10)
# Read column states
for col in range(3):
if col_pins[col].value() == 0: # Key press detected
# Wait for key release (debounce)
time.sleep_ms(20)
while col_pins[col].value() == 0:
time.sleep_ms(10)
# Return corresponding key value
return keymap[row][col]
return None # No key pressed
# Initialize system
def init_system():
"""Initialize system state"""
print("\n" + "="*50)
print(" SECURITY SYSTEM INITIALIZATION")
print("="*50)
time.sleep(1)
# Test servo motor
print("\nTesting servo motor...")
set_servo_angle(0)
time.sleep(0.5)
set_servo_angle(90)
time.sleep(0.5)
# Test LEDs
print("Testing LEDs...")
for _ in range(2):
led_red.value(1)
led_green.value(0)
time.sleep(0.2)
led_red.value(0)
led_green.value(1)
time.sleep(0.2)
# Display system information
print("\n" + "-"*50)
print(f"Default Code: {secretCode}")
print(f"Max attempts: {MAX_ATTEMPTS}")
print(f"Lockdown time: {LOCKDOWN_TIME} seconds")
print("-"*50)
# Set initial state
set_servo_angle(90) # Unlocked position
led_red.value(0)
led_green.value(1)
print("\n✅ System ready!")
unlock_system()
# Initialize system
init_system()
# Main loop
print("\n" + "="*50)
print(" SYSTEM IS RUNNING")
print("="*50)
print("\nScanning for keypad input...")
while True:
try:
# Scan for key presses
key = scan_keypad()
if key is not None:
process_key(key)
# Periodically check lockdown status
if attempts >= MAX_ATTEMPTS:
is_in_lockdown()
# Short delay to reduce CPU usage
time.sleep_ms(10)
except KeyboardInterrupt:
print("\n\nSystem shutdown by user")
break
except Exception as e:
print(f"\nError: {e}")
time.sleep(1)