igendel icon

Xiao RP2040 MicroPython Membrane Keypad PIN Reader

igendel | PRO | 11/06/22 09:19:02 AM UTC | 0 ⭐ | 1290 👁️ | Never ⏰ | []
Python |

3 KB

|

None

|

0 👍

/

0 👎

# Xiao RP2040 Membrane keypad "PIN code" reader
# by Ido Gendel, 2022
# Connections:
#   D7 (P1) -> 510R -> Buzzer -> GND
#   D10 (P3) -> Red LED [Cathode] -> 510R -> 3V3
#   D10 (p3) -> Green LED [Anode] -> 510R -> GND
#   D0-2 (p26-28) -> Keypad columns
#   D3-6 (p29,6,7,0) -> Keypad rows
 
 
from machine import Pin, PWM, Timer
import time
 
# Constants
#================================
 
# This is a demo, not a secure application!
SECRET_CODE = const("4567*")
 
KEYPAD_TIMEOUT = const(5000)
BEEP_FREQ = const(360)
 
row_pin_ref = (0,7,6,29)
# For each column in the keypad, pin ref and keys
key_map = ((28, ("1", "4", "7", "*")),
           (27, ("2", "5", "8", "0")),
           (26, ("3", "6", "9", "#")))
 
 
# Functions
#================================
 
def read_keypad(caller):
    
    global col_pin, row_pin
    global keypad_input
    global last_key
    global last_key_time, KEYPAD_TIMEOUT
    global beep_flag
    
    # Scan for keypad short circuit and get appropriate key value
    result = ""
    for col in range(len(col_pin)):
        if result == "":
            col_pin[col].init(Pin.OUT)
            col_pin[col].low()
            for row in range(len(row_pin)):
                if row_pin[row].value() == 0:
                    result = key_map[col][1][row]
                    beep_flag = True
                    break
            col_pin[col].init(Pin.IN)
 
    # Avoid artificial repetitions
    if result != last_key:
        # Reset iput string if timed out
        if time.ticks_diff(time.ticks_ms(), last_key_time) > KEYPAD_TIMEOUT:
            keypad_input = ""
        last_key_time = time.ticks_ms()
        last_key = result
        keypad_input += result
 
 
# Global variables and setup
#================================
 
row_pin = []
for pin_ref in row_pin_ref:
    row_pin.append(Pin(pin_ref, Pin.IN, pull=Pin.PULL_UP))
    
col_pin = []
for key in key_map:
    col_pin.append(Pin(key[0], Pin.IN))
 
keypad_input = ""
last_key = "Unlikely!"
last_key_time = time.ticks_ms()
beep_flag = False
 
keypad_timer = Timer(-1, mode=Timer.PERIODIC, period=50,
                     callback=read_keypad)
 
led_pin = Pin(3, Pin.OUT)
led_pin.low()
led_timer = Timer(-1)
 
buzzer_pin = Pin(1)
buzzer_pwm = PWM(buzzer_pin)
buzzer_pwm.deinit()
buzzer_timer = Timer(-1)
 
 
# Main loop
#================================
 
while True:
 
    if keypad_input.find(SECRET_CODE) >= 0:
        led_pin.high()
        led_timer.init(mode=Timer.ONE_SHOT, period=2500,
                       callback=lambda caller:led_pin.low())
        keypad_input = ""
 
    # Prevent memory overflow, without losing last presses
    elif len(keypad_input) > 32:
        keypad_input = keypad_input[16:]
    
    if beep_flag:
        buzzer_pwm.freq(BEEP_FREQ)
        buzzer_pwm.duty_u16(32768)
        buzzer_timer.init(mode=Timer.ONE_SHOT, period=60,
                          callback=lambda caller:buzzer_pwm.deinit())        
        beep_flag = False
    
    
 
 
 

Comments