import machine, network, dht, time
from machine import PWM, Pin, time_pulse_us, I2C, ADC, SoftI2C, Timer
from lcd_api import LcdApi
from umqtt.simple import MQTTClient
from i2c_lcd import I2cLcd
# LCD configuration
I2C_ADDR = 0x27
LCD_COLUMNS = 20
LCD_LINES = 4
# Initialize I2C and LCD
i2c = I2C(0, sda=Pin(23), scl=Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, LCD_LINES, LCD_COLUMNS)
lcd.clear()
lcd.backlight_on()
# Initialize sensors and pins
pirsensor = Pin(15, Pin.IN) # PIR sensor for motion detection
buttonpinOff = Pin(17, Pin.IN, Pin.PULL_DOWN)
buttonpinOn = Pin(4, Pin.IN, Pin.PULL_DOWN)
trigger_pin = Pin(5, Pin.OUT)
echo_pin = Pin(18, Pin.IN)
led_M = Pin(19, Pin.OUT) # LED for motor status
led_W = Pin(21, Pin.OUT) # LED for waterplant status
last_press_time = time.ticks_ms()
motor_is_on = False
dht_sensor = dht.DHT22(Pin(14))
Gaz_sensor = ADC(Pin(32)) # Gas sensor
# WiFi and MQTT settings
ssid = "Wokwi-GUEST"
password = ""
mqtt_server = "broker.mqttdashboard.com"
client_id = "3omda6999"
topic_pub_temp = "/unique_section1/temp"
topic_pub_hum = "/unique_section1/hum"
topic_pub_Gaz = "/unique_section1/Gaz"
topic_pub_twl = "/unique_global/tank_water_level"
topic_sub_motor = "/unique_global/motor"
topic_sub_waterplant = "/unique_global/waterplant"
topic_pub_Notif = "/unique_global/Notif"
# Connect to WiFi
def connect_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while not wlan.isconnected():
time.sleep(0.5)
lcd.move_to(2, 0)
lcd.clear()
lcd.putstr("WiFi connected")
time.sleep(1)
lcd.move_to(3, 0)
lcd.putstr("IP address: " + str(wlan.ifconfig()[0]))
# Measure gas levels
def Gaz_mesure(sensor):
Conv = 3.3 / 4095 # Conversion factor
sensor_value = sensor.read()
Gaz_value = sensor_value * Conv
return Gaz_value
# Measure temperature and humidity
def weather_mesure(dht_sensor):
dht_sensor.measure()
temp = dht_sensor.temperature()
humidity = dht_sensor.humidity()
return temp, humidity
# Measure water level
def water_level_mesure(trigger_pin, echo_pin):
trigger_pin.value(1)
time.sleep_us(10)
trigger_pin.value(0)
pulse_duration = time_pulse_us(echo_pin, 1)
distance = pulse_duration * 0.01715 # Calculate distance
return 100 - ((distance / 400) * 100)
# MQTT callback function
def mqtt_callback(topic, msg):
if topic == b'/unique_global/motor':
if msg == b'1':
led_M.value(1)
else:
led_M.value(0)
if topic == b'/unique_global/waterplant':
if msg == b'1':
led_W.value(1)
else:
led_W.value(0)
# Connect to MQTT broker
def connect_mqtt():
client = MQTTClient(client_id, mqtt_server)
client.set_callback(mqtt_callback)
client.connect()
client.subscribe(topic_sub_motor)
client.subscribe(topic_sub_waterplant)
lcd.clear()
lcd.move_to(2, 0)
lcd.putstr("Connected to MQTT broker")
time.sleep(1)
return client
# Connect to WiFi and MQTT
connect_wifi()
client = connect_mqtt()
# Function to handle button press
def func(pin):
global motor_is_on
if buttonpinOn.value() == 1:
led_M.value(1)
lcd.clear()
lcd.move_to(2, 0)
lcd.putstr("Water motor (LED) is ON")
motor_is_on = True
client.publish(topic_sub_motor, "1")
time.sleep(1)
lcd.clear()
if buttonpinOff.value() == 1:
led_M.value(0)
lcd.clear()
lcd.move_to(2, 0)
lcd.putstr("Water motor (LED) is OFF")
motor_is_on = False
client.publish(topic_sub_motor, "0")
time.sleep(1)
lcd.clear()
# Timer to handle button press
timer = Timer(0)
timer.init(period=50, mode=Timer.PERIODIC, callback=func)
# Function to handle notifications
def Notif(pin):
global Gaz, water_level, temp, humidity, lcd
temp, humidity = weather_mesure(dht_sensor)
water_level = water_level_mesure(trigger_pin, echo_pin)
Gaz = Gaz_mesure(Gaz_sensor)
client.check_msg()
client.publish(topic_pub_hum, str(humidity))
client.publish(topic_pub_Gaz, str(Gaz))
client.publish(topic_pub_temp, str(temp))
client.publish(topic_pub_twl, str(water_level))
# Initial measurements
temp, humidity = weather_mesure(dht_sensor)
water_level = water_level_mesure(trigger_pin, echo_pin)
Gaz = Gaz_mesure(Gaz_sensor)
# Timer to handle notifications
timer2 = Timer(1)
timer2.init(period=2000, mode=Timer.PERIODIC, callback=Notif)
# Initialize speaker for alarm
speaker = PWM(Pin(13), freq=1)
speaker.duty(1020)
# Main loop for alerts and status updates
while True:
if temp > 50 or pirsensor.value() == 1:
if temp > 50:
speaker.freq(512)
lcd.clear()
lcd.move_to(0, 1)
lcd.putstr(" !!!ALERT!!! ")
lcd.move_to(0, 2)
lcd.putstr(" !!!FIREEEE!!! ")
client.publish(topic_pub_Notif, " !!!ALERT!!! ")
time.sleep(2)
client.publish(topic_pub_Notif, " !!!FIREEEE!!! ")
time.sleep(2)
lcd.clear()
if pirsensor.value() == 1:
speaker.freq(256)
lcd.clear()
lcd.move_to(0, 1)
lcd.putstr(" !!!ALERT!!! ")
lcd.move_to(0, 2)
lcd.putstr("!!!Movement detected!!!")
client.publish(topic_pub_Notif, " !!!ALERT!!! ")
time.sleep(2)
client.publish(topic_pub_Notif, " !!!Movement detected!!! ")
time.sleep(2)
lcd.clear()
speaker.freq(1)
else:
lcd.clear()
lcd.move_to(0, 0)
if Gaz < 1:
lcd.putstr("Low Gaz Level")
client.publish(topic_pub_Notif, "Low Gaz Level")
elif Gaz < 2.5:
lcd.putstr("Moderate Gaz level ")
client.publish(topic_pub_Notif, "Moderate Gaz level")
else:
lcd.putstr("Optimal Gaz level")
client.publish(topic_pub_Notif, "Optimal Gaz level")
time.sleep(1)
lcd.move_to(0, 1)
if water_level >= 80:
lcd.putstr("Water tank is Full ")
client.publish(topic_pub_Notif, "Water tank is Full")
elif 40 <= water_level <= 80:
lcd.putstr("Water tank is moderate ")
client.publish(topic_pub_Notif, "Water tank is moderate")
else:
lcd.putstr("Water tank is low ")
client.publish(topic_pub_Notif, "Water tank is low")
time.sleep(1)
lcd.move_to(0, 2)
if 40 <= temp <= 50:
lcd.putstr(" High temp ")
client.publish(topic_pub_Notif, "High temp")
elif temp >= 30:
lcd.putstr(" Moderate temp ")
client.publish(topic_pub_Notif, "Moderate temp")
else:
lcd.putstr(" Low temp ")
client.publish(topic_pub_Notif, "Low temp")
time.sleep(1)
lcd.move_to(0, 3)
if humidity >= 65:
lcd.putstr(" High Humidity")
client.publish(topic_pub_Notif, "High Humidity ")
elif humidity >= 30:
lcd.putstr(" Moderate Humidity")
client.publish(topic_pub_Notif, "Moderate Humidity")
else:
lcd.putstr(" Low Humidity")
client.publish(topic_pub_Notif, "Low Humidity")
time.sleep(1)
lcd.clear()