from machine import Pin, I2C, ADC, PWM
import ssd1306
import dht
import time
# === I2C setup for OLED ===
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# === Sensors setup ===
dht_sensor = dht.DHT22(Pin(15))
mq2 = ADC(Pin(34)); mq2.atten(ADC.ATTN_11DB)
ldr = ADC(Pin(35)); ldr.atten(ADC.ATTN_11DB)
# === Outputs ===
buzzer = PWM(Pin(27))
buzzer.freq(1000)
buzzer.duty(0)
led_sprinkler = Pin(26, Pin.OUT)
led_fan = Pin(25, Pin.OUT)
led_light = Pin(33, Pin.OUT)
relay = Pin(32, Pin.OUT)
# === RGB LED Pins ===
red = Pin(14, Pin.OUT)
green = Pin(12, Pin.OUT)
blue = Pin(13, Pin.OUT)
# === Button (Active Low) ===
button = Pin(4, Pin.IN, Pin.PULL_UP)
# === Thresholds ===
SMOKE_THRESHOLD = 80.0
TEMP_THRESHOLD = 20.0
LIGHT_THRESHOLD = 75.0 # Percentage (0 = very bright, 100 = very dark)
# === State Variables ===
system_on = False
last_button_state = 1
debounce_time = 0
# === Helper functions ===
def get_smoke_percent(value):
return min(max((value / 4095) * 100, 0), 100)
def get_light_percent(value):
return min(max((1 - value / 4095) * 100, 0), 100)
def set_rgb_color(r, g, b):
red.value(r)
green.value(g)
blue.value(b)
def shutdown_all():
buzzer.duty(0)
led_sprinkler.value(0)
led_fan.value(0)
led_light.value(0)
relay.value(0)
set_rgb_color(0, 0, 0)
oled.fill(0)
oled.text("System OFF", 20, 28)
oled.show()
# === Main loop ===
while True:
current_time = time.ticks_ms()
current_button = button.value()
# Toggle detection with debounce
if current_button == 0 and last_button_state == 1 and (current_time - debounce_time) > 300:
system_on = not system_on
debounce_time = current_time
last_button_state = current_button
if system_on:
try:
dht_sensor.measure()
temp = dht_sensor.temperature()
humidity = dht_sensor.humidity()
gas_value = mq2.read()
smoke_percent = get_smoke_percent(gas_value)
ldr_value = ldr.read()
light_percent = get_light_percent(ldr_value)
# Temp LED
led_fan.value(1 if temp >= TEMP_THRESHOLD and smoke_percent < SMOKE_THRESHOLD else 0)
# RGB LED color based on temperature
if temp <= 20:
set_rgb_color(0, 0, 1) # Blue
elif 20 <= temp <= 38:
set_rgb_color(0, 1, 0) # Green
elif 38 <= temp <= 80:
set_rgb_color(1, 0, 0) # Red
else:
set_rgb_color(0, 0, 0)
# Light LED only ON when it's truly dark
led_light.value(0 if light_percent >= LIGHT_THRESHOLD else 1)
# === OLED Update (no flickering) ===
oled.fill(0)
oled.text("Temp: {:.1f} C".format(temp), 0, 0)
oled.text("Hum: {:.1f}%".format(humidity), 0, 12)
oled.text("Smoke: {:.1f}%".format(smoke_percent), 0, 24)
oled.text("Light: {:.1f}%".format(light_percent), 0, 36)
# Smoke alert logic
if smoke_percent >= SMOKE_THRESHOLD:
led_sprinkler.value(1)
buzzer.duty(512)
relay.value(1)
oled.text("SMOKE ALERT!", 0, 48)
oled.text("FIRE WARNING!", 0, 56)
else:
led_sprinkler.value(0)
buzzer.duty(0)
relay.value(0)
oled.show()
except Exception:
pass # Silently ignore sensor read errors
else:
shutdown_all()
time.sleep(0.1)