print("Hello, PRACTICAL TEST PROJECT FOR SDG 16 SMART ACCESS")
print("TITLE: SMART ACCESS")
import machine
import time
import neopixel
from machine import Pin, PWM, SoftI2C, ADC
# 1. Import library
from oled_library import SSD1306_I2C
from rfid_library import MFRC522
print("Hello, SDG 16 SMART ACCESS SYSTEM (LDR MODE)")
# --- Pin Declarations ---
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = SSD1306_I2C(128, 64, i2c)
# LDR Sensor (Pin 34)
ldr = ADC(Pin(34))
ldr.atten(ADC.ATTN_11DB) # Untuk bacaan 0-3.3V
trig = Pin(26, Pin.OUT)
echo = Pin(25, Pin.IN)
pir = Pin(27, Pin.IN)
reset_button = Pin(32, Pin.IN, Pin.PULL_UP)
buzzer = PWM(Pin(14))
buzzer.duty(0)
servo = PWM(Pin(15), freq=50)
np = neopixel.NeoPixel(Pin(12), 16)
# RFID Setup
rfid = MFRC522(18, 23, 19, 4, 5)
ALLOWED_UID = [4, 34, 4, 0]
# --- Functions ---
def set_neopixel(color):
for i in range(16):
np[i] = color
np.write()
def set_servo_angle(angle):
duty = int(((angle / 180) * 75) + 40)
servo.duty(duty)
def get_distance():
trig.off()
time.sleep_us(2)
trig.on()
time.sleep_us(10)
trig.off()
while echo.value() == 0: pass
t1 = time.ticks_us()
while echo.value() == 1: pass
t2 = time.ticks_us()
return (time.ticks_diff(t2, t1) * 0.0343) / 2
def reset_system():
global system_alarm
system_alarm = False
buzzer.duty(0)
oled.fill(0)
oled.text("SYSTEM READY", 15, 25)
oled.show()
set_neopixel((150, 150, 0))
set_servo_angle(0)
# --- Main Loop ---
reset_system()
system_alarm = False
while True:
if reset_button.value() == 0:
reset_system()
time.sleep(0.5)
# Baca nilai LDR dan tukar ke Lux (Anggaran dalam Wokwi)
# Wokwi LDR: Gelap = nilai besar, Terang = nilai kecil
ldr_value = ldr.read()
# Anggaran 100 lux dalam Wokwi (bergantung kepada litar, kita guna threshold 2000)
# Kalau gelap (lux rendah), ldr_value akan tinggi
is_dark = ldr_value > 2000
if system_alarm:
# Siren Polis & Lampu Kelip
buzzer.freq(600)
buzzer.duty(512)
set_neopixel((255, 0, 0))
time.sleep(0.2)
buzzer.freq(900)
buzzer.duty(512)
set_neopixel((0, 0, 0))
time.sleep(0.2)
continue
if not system_alarm:
# LOGIK BARU: Cek PIR + LDR
if pir.value() == 1:
if is_dark:
# Lux bawah 100 (GELAP): Keluar bunyi siren
system_alarm = True
oled.fill(0)
oled.text("MOTION TRIGGERED!", 4, 25)
oled.show()
else:
# Lux atas 100 (TERANG): Hanya OLED sahaja, tiada bunyi
oled.fill(0)
oled.text("MOTION DETECTED", 5, 25)
oled.text("(DAY MODE)", 20, 40)
oled.show()
set_neopixel((255, 165, 0)) # Orange sekejap
time.sleep(2)
reset_system()
continue
if get_distance() < 50:
oled.fill(0)
oled.text("PLEASE SCAN RFID", 0, 25)
oled.show()
uid = rfid.read_uid()
if uid:
if uid == ALLOWED_UID:
oled.fill(0)
oled.text("SUCCESSFUL", 25, 25)
oled.show()
set_neopixel((0, 255, 0))
set_servo_angle(90)
# DING DONG 7-ELEVEN
buzzer.duty(512)
buzzer.freq(1318)
time.sleep(0.2); buzzer.duty(0); time.sleep(0.05); buzzer.duty(512)
buzzer.freq(1047)
time.sleep(0.4); buzzer.duty(0)
time.sleep(2.5)
reset_system()
else:
# TOL TAK CUKUP BAKI
oled.fill(0)
oled.text("ACCESS DENIED", 10, 25)
oled.show()
set_neopixel((255, 0, 0))
for _ in range(3):
buzzer.freq(300); buzzer.duty(512); time.sleep(0.2)
buzzer.duty(0); time.sleep(0.1)
reset_system()
else:
oled.fill(0)
oled.text("SYSTEM READY", 15, 25)
# Tunjuk status cahaya kat OLED untuk senang kau debug
status_cahaya = "DARK" if is_dark else "LIGHT"
oled.text("MODE: " + status_cahaya, 15, 40)
oled.show()
set_neopixel((150, 150, 0))
time.sleep(0.1)