from machine import Pin, ADC, I2C, PWM
import dht
import ssd1306
import time
from ultrasonic_library import HCSR04
# ===== OLED SETUP =====
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# ===== SENSOR SETUP =====
dht_sensor = dht.DHT22(Pin(4))
ldr = ADC(Pin(33))
ldr.atten(ADC.ATTN_11DB)
ultrasonic = HCSR04(trigger_pin=5, echo_pin=18)
ph_sensor = ADC(Pin(35)) # potentiometer untuk pH
ph_sensor.atten(ADC.ATTN_11DB)
# ===== OUTPUT SETUP =====
green_led = Pin(13, Pin.OUT)
red_led = Pin(14, Pin.OUT)
buzzer = PWM(Pin(27), freq=1000, duty=0)
# Servo motor setup (PWM)
servo = PWM(Pin(26), freq=50) # 50Hz untuk servo
def buzzer_on():
buzzer.duty(512)
def buzzer_off():
buzzer.duty(0)
def servo_angle(angle):
duty = int((angle/180)*102 + 26) # kiraan kasar untuk ESP32 PWM (0–1023)
servo.duty(duty)
# ===== MAIN LOOP =====
while True:
try:
# Read sensors
dht_sensor.measure()
temp = dht_sensor.temperature()
distance = ultrasonic.distance_cm()
ldr_raw = ldr.read()
lux = (ldr_raw / 4095) * 1000 # skala 0–1000 lux
ph_raw = ph_sensor.read()
ph_value = (ph_raw / 4095) * 14 # mapping ADC ke pH 0–14
# ===== CONDITION =====
safe = (20 <= temp <= 35) and (200 <= lux <= 800) and (distance < 50) and (6.5 <= ph_value <= 8.5)
# ===== OUTPUT =====
if safe:
status = "SAFE"
green_led.on()
red_led.off()
buzzer_off()
servo_angle(0) # servo di posisi asal
else:
status = "UNSAFE"
green_led.off()
red_led.on()
buzzer_on()
servo_angle(90) # servo bergerak (contoh buka injap)
# ===== OLED DISPLAY =====
oled.fill(0)
oled.text("Water Monitor", 0, 0)
oled.text("Temp: {:.1f}C".format(temp), 0, 10)
oled.text("Lux: {:.0f}".format(lux), 0, 20)
oled.text("Dist: {:.1f}cm".format(distance), 0, 30)
oled.text("pH: {:.2f}".format(ph_value), 0, 40)
oled.text(status, 0, 55)
oled.show()
# ===== SERIAL OUTPUT =====
print("Temp:", temp)
print("Lux:", lux)
print("Distance:", distance)
print("pH:", ph_value)
print("Status:", status)
print("------------------")
except Exception as e:
print("Error:", e)
time.sleep(2)