#padlock system
#code is generated using input from real world - temp sensor, humidity sensor and light sensor

## imports
from machine import Pin, I2C, ADC
import ssd1306
import time
from math import log
from dht import DHT22

#oled display
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
display = ssd1306.SSD1306_I2C(128, 64, i2c)

#keypad
mkeys= [['A', '3', '2', '1'],
        ['B', '6', '5', '4'],
        ['C', '9', '8', '7'],
        ['D', '#', '0', '*']]

rows = [13, 12, 11, 10]
columns = [6, 7, 8, 9]

rpins = [Pin(13, Pin.OUT), Pin(12, Pin.OUT), Pin(11, Pin.OUT), Pin(10, Pin.OUT)]
cpins = [Pin(6, Pin.IN, Pin.PULL_DOWN), Pin(7, Pin.IN, Pin.PULL_DOWN), Pin(8, Pin.IN, Pin.PULL_DOWN), Pin(9, Pin.IN, Pin.PULL_DOWN)]

for i in range(4):
    rpins[i].value(1)
    cpins[i].value(0)

#thermistor
temp = ADC(28)
b = 3950
kc = 273.15

#photoresistor
photo = ADC(27)

#humidity sensor
humid = DHT22(Pin(26))

#code variables
timer = 0
strikes = 0
string = ""
strikelog = 0

#default screen
display.text("enter code", 0, 0, 1)
display.text("to unlock!", 0, 25, 1)
display.show()

while True:
    if timer % 12000 == 0: #collect data to create code
        tempval = temp.read_u16()
        cels = (1/(log(1/(65535/tempval - 1))/b + 1/298.15) - kc)
        lux = photo.read_u16()
        humid.measure()
        h = humid.humidity()
        code = int(h *lux // cels) % 10000
        while len(str(code)) < 4: #standardises length
            code = "0" + str(code)
    for i in range(4): #rows
        for j in range(4): #columns
            rpins[i].high()
            key = None
            if cpins[j].value() == 1:
                string += mkeys[i][j]
                display.fill(0)
                display.text(string, 0, 0, 1)
                display.show()
                kpress = mkeys[i][j]
        rpins[i].low()
    if string == str(code): #verification of code
        display.fill(0)
        display.text("unlocked", 0, 0, 1)
        display.text("welcome!", 0, 50, 1)
        display.show()
        strikes = 0
        strikelog = 0
    else:
        if string == "****": #developer code - reveals code
            display.fill(0)
            display.text(str(code), 0, 0, 1)
            display.show()
            string = ""
        elif len(string) == 4 and string != str(code): #adds strike, returns string to nothing
            strikes += 1
            string = ""
    if strikes == 3: #strike system
        if strikelog == 0:
            sleepy = 40
        elif strikelog > 0:
            sleepy = 40 + 40*strikelog
        display.fill(0)
        display.text("wait " + str(sleepy) + " seconds", 0, 0, 1)
        display.text("3 strikes,", 0, 25, 1)
        display.text("you're out!", 0, 50, 1)
        display.show()
        time.sleep(1)
        while sleepy > 0: #displays seconds remaining
            sleepy -= 1
            display.fill(0)
            display.text("wait " + str(sleepy) + " seconds", 0, 0, 1)
            display.text("3 strikes,", 0, 25, 1)
            display.text("you're out!", 0, 50, 1)
            display.show()
            time.sleep(1)
        strikes = 0
        strikelog += 1
        display.fill(0)
        display.show()
    time.sleep(0.1)
    timer += 1 #time system
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT