from machine import Pin, I2C
import dht
import time
from BlynkLib import Blynk
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
from ds1307 import DS1307
import network
# Wi-Fi credentials
SSID = 'Wokwi-GUEST'
PASSWORD = ''
# Connect to Wi-Fi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(1)
print("Connected to Wi-Fi:", wlan.ifconfig())
# Blynk authentication token
BLYNK_AUTH = 'np-OPFzaZiwkwKAJPq2--IUJ14Ld75Qp'
blynk = Blynk(BLYNK_AUTH)
# Initialize sensors and devices
dht_sensor = dht.DHT22(Pin(14))
pir_sensor = Pin(27, Pin.IN)
relay = Pin(19, Pin.OUT)
led = Pin(25, Pin.OUT)
led.value(0)
relay.value(0)
i2c_lcd = I2C(1, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c_lcd, 0x27, 4, 20)
i2c_rtc = I2C(0, scl=Pin(26), sda=Pin(23), freq=400000)
rtc = DS1307(i2c_rtc)
DELAY_TIME = 10 # Delay after motion detected before turning off lamp
lamp_on = False
last_motion_time = 0
lamp_start_time = 0
last_temp = None
last_humidity = None
last_lamp_status = None
last_time = None
def get_time():
"""Get the current time from RTC."""
try:
datetime = rtc.datetime()
if isinstance(datetime, tuple) and len(datetime) >= 7:
return "{:02}:{:02}:{:02}".format(datetime[4], datetime[5], datetime[6])
except Exception as e:
print("Error reading from RTC:", e)
return "00:00:00"
def update_lcd(temp, humidity, lamp_status, time_str, usage_time):
"""Update the LCD display with temperature, humidity, lamp status, time, and usage time."""
global last_temp, last_humidity, last_lamp_status, last_time
if (temp != last_temp or
humidity != last_humidity or
lamp_status != last_lamp_status or
time_str != last_time):
lcd.clear()
lcd.putstr("Suhu: {}C".format(temp))
lcd.move_to(0, 1)
lcd.putstr("Kelembapan: {:.1f}%".format(humidity))
lcd.move_to(0, 2)
lcd.putstr("Lampu: {}".format("HIDUP" if lamp_status else "MATI"))
lcd.move_to(0, 3)
lcd.putstr("WaktuLampu: {} detik".format(usage_time))
last_temp = temp
last_humidity = humidity
last_lamp_status = lamp_status
last_time = time_str
def control_lamp(motion_detected):
"""Control lamp based on motion detection."""
global lamp_on, last_motion_time, lamp_start_time
if motion_detected:
last_motion_time = time.time()
if not lamp_on:
turn_on_lamp()
else:
if lamp_on and (time.time() - last_motion_time > DELAY_TIME):
turn_off_lamp()
def turn_on_lamp():
"""Turn on the lamp and LED."""
global lamp_on, lamp_start_time
relay.value(1)
led.value(1)
lamp_on = True
lamp_start_time = time.time()
print("Lamp ON - Time:", get_time())
def turn_off_lamp():
"""Turn off the lamp and LED."""
global lamp_on
relay.value(0)
led.value(0)
lamp_on = False
print("Lamp OFF - Time:", get_time())
@blynk.on("V1") # Handler for Virtual Pin 1
def v1_handler(value):
global last_temp
last_temp = value[0] # Capture the temperature value
print("Temperature set to:", last_temp)
@blynk.on("V2") # Handler for Virtual Pin 2
def v2_handler(value):
global last_humidity
last_humidity = value[0] # Capture the humidity value
print("Humidity set to:", last_humidity)
@blynk.on("V3") # Handler for Virtual Pin 3
def v3_handler(value):
global lamp_on
lamp_on = bool(value[0]) # Capture lamp status
print("Lamp status set to:", lamp_on)
if lamp_on:
turn_on_lamp()
else:
turn_off_lamp()
try:
while True:
try:
dht_sensor.measure()
temperature = int(dht_sensor.temperature())
humidity = dht_sensor.humidity()
except OSError as e:
print("Failed to read from DHT22:", e)
continue
current_time = get_time()
motion_detected = pir_sensor.value()
control_lamp(motion_detected)
usage_time = int(time.time() - lamp_start_time) if lamp_on else 0
update_lcd(temperature, humidity, lamp_on, current_time, usage_time)
# Update Blynk with current readings
blynk.virtual_write(1, temperature) # Send temperature to virtual pin 1
time.sleep(0.1)
blynk.virtual_write(2, int(humidity)) # Send humidity to virtual pin 2
blynk.virtual_write(3, int(lamp_on)) # Send lamp status to virtual pin 3
blynk.run() # Call the run method to handle Blynk communication
time.sleep(1)
except KeyboardInterrupt:
print("Program stopped")
lcd.clear()