print("Smart Water Quality Monitoring System using IoT")
print("Mini Project")
# Import libraries/modules
from machine import Pin, PWM, SoftI2C, ADC
import ULTRASONIC_LIBRARY
import oled_library
from neopixel import NeoPixel
from time import sleep
import math
# -------------------- Pin Declaration --------------------
# ADC Inputs
# Potentiometer for pH level (GPIO27)
ph_sensor = ADC(Pin(27))
ph_sensor.atten(ADC.ATTN_11DB)
ph_sensor.width(ADC.WIDTH_10BIT)
# LDR (AO to GPIO13)
ldr = ADC(Pin(13))
ldr.atten(ADC.ATTN_11DB)
ldr.width(ADC.WIDTH_10BIT)
# Temperature sensor (NTC on GPIO26)
ntc = ADC(Pin(26))
ntc.atten(ADC.ATTN_11DB)
ntc.width(ADC.WIDTH_12BIT)
# Outputs
red_led = Pin(14, Pin.OUT) # Water level alert
green_led = Pin(12, Pin.OUT) # Normal pH
yellow_led = Pin(32, Pin.OUT) # Low pH
blue_led = Pin(25, Pin.OUT) # High pH
buzzer = PWM(Pin(33), freq=1000)
np = NeoPixel(Pin(16), 16)
# -------------------- OLED Setup --------------------
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
screen = oled_library.SSD1306_I2C(width=128, height=64, i2c=i2c)
# -------------------- Ultrasonic Sensor --------------------
TRIG = Pin(5, Pin.OUT)
ECHO = Pin(17, Pin.IN)
water_sensor = ULTRASONIC_LIBRARY.HCSR04(
trigger_pin=TRIG,
echo_pin=ECHO,
timeout_us=30000
)
# -------------------- Servo Setup --------------------
servo = PWM(Pin(18), freq=50)
def move_servo(angle):
duty = int(((angle / 180) * 2 + 0.5) / 20 * 1023)
servo.duty(duty)
# -------------------- Temperature Function --------------------
def read_temperature_celsius(samples=10):
BETA = 3950
total = 0
for _ in range(samples):
analog_value = ntc.read()
total += analog_value
sleep(0.01)
avg_value = total / samples
resistance = 4095.0 / avg_value - 1
temp_kelvin = 1 / (math.log(resistance) / BETA + 1.0 / 298.15)
temp_celsius = temp_kelvin - 273.15
return round(temp_celsius, 1)
# -------------------- Main Program --------------------
while True:
# Water level
measure_distance = water_sensor.distance_cm()
print("Water level =", measure_distance, "cm")
# LDR light level
light_value = ldr.read()
lux = (1023 - light_value) * (1000 / 1023)
print("Lux:", lux)
# pH value
pot_value = ph_sensor.read()
ph_value = round((pot_value / 1023) * 14, 1)
print("pH value:", ph_value)
# pH LED Logic
if ph_value < 6.5:
ph_status = "Low"
yellow_led.on()
green_led.off()
blue_led.off()
elif 6.5 <= ph_value <= 8.5:
ph_status = "OK"
yellow_led.off()
green_led.on()
blue_led.off()
else:
ph_status = "High"
yellow_led.off()
green_led.off()
blue_led.on()
# Temperature
temp_c = read_temperature_celsius()
# OLED Display
screen.fill(0)
screen.text("Monitor 1", 0, 0)
screen.text("Water: " + str(measure_distance) + "cm", 0, 10)
screen.text("Lux: " + str(int(lux)), 0, 20)
screen.text("pH: " + str(ph_value), 0, 30)
screen.text("pH Status: " + ph_status, 0, 40)
screen.text("Temp: {}C".format(temp_c), 0, 50)
screen.show()
# Water level alert (Red LED + Buzzer)
if measure_distance > 300:
red_led.on()
buzzer.duty(1023)
elif measure_distance < 150:
red_led.on()
buzzer.duty(1023)
else:
red_led.off()
buzzer.duty(0)
# NeoPixel (light based)
if lux < 500:
for i in range(16):
np[i] = (255, 255, 255)
np.write()
else:
for i in range(16):
np[i] = (0, 0, 0)
np.write()
# Servo (temperature based)
if temp_c >= 30:
move_servo(90)
else:
move_servo(0)
sleep(0.5)