print("DOOR SECURITY SYSTEM WITH ESP32")

# Import necessary libraries
from machine import Pin, PWM, SoftI2C, time_pulse_us
from utime import sleep
import lcd_library
from servo import Servo
import time

# Initialize unlock and lock counters
unlock = 0
lock = 0

# Ultrasound sensor pins
TRIG_PIN = 32
ECHO_PIN = 33
ULTRASONIC_LED_PIN = 25
trig = Pin(TRIG_PIN, Pin.OUT)
echo = Pin(ECHO_PIN, Pin.IN)
ultrasonic_led = Pin(ULTRASONIC_LED_PIN, Pin.OUT)

# Buzzer and LEDs
buzzer = PWM(Pin(26), Pin.OUT)
led_red = Pin(19, Pin.OUT)
led_blue = Pin(23, Pin.OUT)

# LCD screen setup
i2c_oled = SoftI2C(scl=Pin(22), sda=Pin(21))
oled_width = 128
oled_height = 64
screen = lcd_library.SSD1306_I2C(oled_width, oled_height, i2c_oled)
screen.text('Waiting...', 10, 10)
screen.show()

# Keypad setup
class Key:
    def __init__(self, name):
        self.name = name
        self.active = False

keys = [
    [Key('1'), Key('2'), Key('3'), Key('A')],
    [Key('4'), Key('5'), Key('6'), Key('B')],
    [Key('7'), Key('8'), Key('9'), Key('C')],
    [Key('*'), Key('0'), Key('#'), Key('D')]
]

rows = [18, 5, 4, 2]
cols = [13, 12, 14, 27]
row_pins = [Pin(pin, Pin.OUT) for pin in rows]
col_pins = [Pin(pin, Pin.IN, Pin.PULL_DOWN) for pin in cols]

def scan_keys():
    for row, row_pin in enumerate(row_pins):
        row_pin.on()
        for col, col_pin in enumerate(col_pins):
            keys[row][col].active = bool(col_pin.value())
        row_pin.off()

entered_password = ''
correct_password = '1234'

# Servo motor setup
servo_pin = Pin(15, Pin.OUT)
my_servo = Servo(servo_pin)

buzzer.init(freq=1, duty=0)

def measure_distance():
    """
    Measures the distance using the ultrasonic sensor.
    Returns the distance in centimeters.
    """
    trig.off()
    time.sleep_us(2)
    trig.on()
    time.sleep_us(10)
    trig.off()

    pulse_duration = time_pulse_us(echo, 1, 30000)  # Timeout after 30ms
    distance = (pulse_duration / 2) * 0.0343  # Convert to cm
    return distance

# Main loop
while True:
    # Measure distance
    distance = measure_distance()

    if distance < 100:  # Object within 1 meter
        ultrasonic_led.on()  # Indicate system is active
        screen.fill(0)
        screen.text('System Active', 10, 10)
        screen.show()
        
        # Stop displaying distance in serial monitor
        #print("System Active, Distance Below 1m")

        # Scan for keypad input
        scan_keys()
        for row in keys:
            for key in row:
                if key.active:
                    if key.name == '#':  # User pressed 'Enter'
                        if entered_password == correct_password:
                            screen.fill(0)
                            print("Welcome in!")
                            screen.text('Welcome in!', 20, 10)
                            screen.show()
                            led_blue.on()
                            led_red.off()
                            my_servo.write_angle(180)
                            unlock += 1
                            print('unlock = ', unlock)
                        else:
                            lock += 1
                            print('lock = ', lock)
                            for i in range(10):
                                screen.fill(0)
                                print("Wrong")
                                screen.text('Wrong!', 20, 10)
                                screen.show()
                                led_red.on()
                                led_blue.off()
                                my_servo.write_angle(90)
                                buzzer.init(freq=1500, duty=300)
                                sleep(0.05)
                                buzzer.init(freq=1, duty=0)
                                sleep(0.05)
                        entered_password = ''
                    else:
                        print(key.name, end='')
                        entered_password += key.name
                    sleep(0.25)  # Debounce
    else:  # Object farther than 1 meter
        ultrasonic_led.off()  # Indicate system is inactive
        screen.fill(0)
        screen.text('System Inactive', 10, 10)
        screen.show()
        led_red.off()
        led_blue.off()
        buzzer.init(freq=1, duty=0)
        my_servo.write_angle(90)  # Ensure servo is in locked position
        
        # Display distance only when inactive
        #print("Distance: {:.2f} cm".format(distance))
        sleep(1)  # Add delay to prevent rapid updates



from machine import Pin, ADC
import time

# Define LDR (Analog Input)
ldr = ADC(Pin(34))  # Use GPIO 36 (ADC0) for LDR
ldr.atten(ADC.ATTN_11DB)  # Configure for full 3.3V range

# Define LED (Digital Output)
led = Pin(35, Pin.OUT)  # Use GPIO 25 for LED

# Threshold for light intensity (adjust based on your setup)
THRESHOLD = 2000  # Adjust this value as needed (0-4095 for 12-bit ADC)

while True:
    # Read the LDR value
    light_value = ldr.read()  # Value ranges from 0 to 4095
    print(f"Light Intensity: {light_value}")
    
    # Control the LED based on the threshold
    if light_value < THRESHOLD:
        led.value(1)  # Turn on LED (low light detected)
        print("LED ON")
    else:
        led.value(0)  # Turn off LED (sufficient light detected)
        print("LED OFF")
    
    time.sleep(0.5)  # Delay for readability