from machine import Pin, PWM, ADC, I2C, SPI
import time
from i2c_lcd import I2cLcd
from ili9341 import Display, color565
from xglcd_font import XglcdFont
import random
# **Konfigurasi Pin**
led = Pin(2, Pin.OUT) # LED status sistem
buzzer = PWM(Pin(15), freq=1000, duty=0) # Buzzer dengan PWM
relay = Pin(4, Pin.OUT) # Relay untuk kunci pintu
pir = Pin(13, Pin.IN) # Sensor PIR
switch = Pin(14, Pin.IN) # switch aktifkan sistem
emergency_button = Pin(32, Pin.IN, Pin.PULL_UP) # Butang kecemasan (Pin 32)
pot = ADC(Pin(34)) # Potensiometer untuk kawalan
pot.atten(ADC.ATTN_11DB)
servo = PWM(Pin(12), freq=50, duty=0) # Servo untuk pintuu
# I2C LCD
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# **SPI untuk LCD ILI9341**
sck = Pin(18)
mosi = Pin(23)
miso = Pin(19)
spi = SPI(1, baudrate=32000000, sck=sck, mosi=mosi, miso=miso)
cs = Pin(5)
dc = Pin(16)
rst = Pin(17)
display = Display(spi, dc=dc, cs=cs, rst=rst)
arcadepix = XglcdFont('ArcadePix9x11.c', 9, 11)
# **Fungsi Menulis Log ke Fail**
def write_log(message):
with open("log.txt", "a") as f:
f.write(message + "\n")
print("Log saved:", message)
# **Fungsi Paparan LCD untuk Status Sistem**
def display_status(message):
lcd.clear()
lcd.putstr(message)
# **Fungsi Kawalan Pintu (Relay + Servo)**
def lock_door():
relay.on()
servo.duty(40) # Tutup pintu
def unlock_door():
relay.off()
servo.duty(115) # Buka pintu
# **Fungsi Kawalan Buzzer apabila Intruder dikesan**
def alarm_on():
# Ambil nilai dari potentiometer dan tukar menjadi duty untuk buzzer
pot_value = pot.read() # Baca nilai potensiometer
duty = int((pot_value / 4095) * 1023) # Tukar nilai ADC ke duty (0-1023)
buzzer.duty(duty) # Setkan duty cycle buzzer
def alarm_off():
buzzer.duty(0) # Matikan buzzer
# **Fungsi Paparan ILI9341**
def display_armed():
display.fill_rectangle(0, 0, 240, 320, color565(0, 0, 0)) # Kosongkan skrin (hitam)
display.fill_rectangle(85, 135, 70, 70, color565(0, 255, 0)) # Kotak hijau sebagai indikator "Armed"
def display_intruder():
display.fill_rectangle(0, 0, 240, 320, color565(0, 0, 0)) # Kosongkan skrin (hitam)
display.fill_rectangle(85, 135, 70, 70, color565(255, 0, 0)) # Kotak merah sebagai indikator "Intruder"
display.draw_text(110, 160, "X", arcadepix, color565(255, 255, 255)) # Huruf "X" putih
# Fungsi untuk mematikan sistem
def disarm_system(pin):
global system_armed
system_armed = False
led.off()
unlock_door()
alarm_off() # Matikan buzzer apabila sistem dimatikan
display_status("Disarmed")
write_log("System Disarmed")
display_armed() # Ubah paparan ILI9341 kembali kepada hijau
# **Interrupt untuk butang kecemasan**
emergency_button.irq(trigger=Pin.IRQ_FALLING, handler=disarm_system)
system_armed = False # Status sistem
display_status("Slide Switch to Arm")
write_log("Waiting...")
# **Variabel untuk menjejaki jika buzzer sudah berbunyi**
buzzer_activated = False
# slide switch
prev_switch_state = switch.value()
while True:
current_switch_state = switch.value() # Read the current state of the switch
# Check if the switch state has changed
if current_switch_state != prev_switch_state:
prev_switch_state = current_switch_state # Update the previous state
if current_switch_state == 1: # Switch is turned ON
if not system_armed:
system_armed = True
led.on()
display_status("ARMED")
write_log("System Armed")
display_armed()
time.sleep(1)
else:
# If system is already armed, disarm it
system_armed = False
led.off()
unlock_door()
alarm_off() # Turn off buzzer when disarmed
display_status("Disarmed")
write_log("System Disarmed")
display_armed() # Change ILI9341 display back to green
time.sleep(1)
# Check for intruder detection only when system is armed
if system_armed:
if pir.value(): # If PIR sensor detects movement
if not buzzer_activated: # Ensure the buzzer only activates once
display_status("Intruder Detected")
alarm_on() # Activate buzzer with volume based on potentiometer
lock_door() # Lock the door
display_intruder() # Display intruder alert
buzzer_activated = True # Mark buzzer as activated
else:
alarm_off() # Turn off buzzer if no intruder
buzzer_activated = False # Reset buzzer for next detection
time.sleep(0.1)