# import libraries
from machine import Pin, I2C
import ssd1306
from time import sleep

# ESP32 Pin assignment 
i2c = I2C(-1, scl=Pin(22), sda=Pin(21))

# LCD Display Parameters
lcd_width = 128
lcd_height = 64
lcd = ssd1306.SSD1306_I2C(lcd_width, lcd_height, i2c)

# Keypad Parameters
ROW_PINS = [14, 27, 26, 25] # GPIO pins for rows (R1-R4)
COL_PINS = [13, 12, 4] # GPIO pins for columns (C1-C3)
KEYS = [['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'], ['*', '0', '#']] # key labels

# Initialize keypad pins as inputs or outputs 
row_pins = [Pin(pin_num, Pin.IN) for pin_num in ROW_PINS]
col_pins = [Pin(pin_num, Pin.OUT) for pin_num in COL_PINS]

# Initialize key press count variable 
key_count = 0

def read_keypad():
    global key_count # use global variable to store key press count 
    key_pressed = None # initialize key pressed as None 
    for col_pin in col_pins:
        col_pin.value(0) # set column pin to low 
        for row_pin in row_pins:
            if row_pin.value() == 0: # check if any row pin is low 
                row_index = row_pins.index(row_pin) # get row index 
                col_index = col_pins.index(col_pin) # get column index 
                key_pressed = KEYS[row_index][col_index] # get key label 
                key_count += 1 # increment key press count by one 
                while row_pin.value() == 0: # wait until the key is released 
                    pass
        col_pin.value(1) # set column pin back to high 
    return key_pressed

while True:
    try:
        # Read keypad input
        key_input = read_keypad()
        
        if key_input != None: # if a valid key is pressed  
            print('Key:',key_input) # print the key label on serial monitor 
            
            # Clear LCD display 
            lcd.fill(0)

            # Display the last pressed key and total count on LCD  
            lcd.text('Last Key: ' + str(key_input), 0, 0)
            lcd.text('Count: ' + str(key_count), 0 ,10)

            # Update LCD display