import network
import time
from machine import Pin, ADC
from umqtt.simple import MQTTClient
#WiFi
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""
#MQTT
MQTT_BROKER = "broker.hivemq.com"
MQTT_PORT = 1883
MQTT_CLIENT_ID = "ESP32_MicroPython_Mousa"
MQTT_TOPIC_RELAY = b"relay/status"
MQTT_TOPIC_CURRENT = b"current/status"
MQTT_TOPIC_ALERT = b"alert/status"
#Pins
RELAY_PIN = Pin(26, Pin.OUT)
LED_PIN = Pin(27, Pin.OUT)
ALERT_LED_PIN = Pin(12, Pin.OUT)
CURRENT_SENSOR = ADC(Pin(34))
CURRENT_SENSOR.width(ADC.WIDTH_12BIT)
BUTTON_PIN = Pin(25, Pin.IN, Pin.PULL_UP)
RESET_BUTTON_PIN = Pin(33, Pin.IN, Pin.PULL_UP)
#Relay & Control State
relay_state = False
manual_control = False
OVER_CURRENT_THRESHOLD_A = 15
VREF = 1.65
SENSITIVITY = 0.103
ADC_MAX = 4095
ADC_VOLTAGE = 3.3
# ==== Functions ====
def connect_wifi():
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(WIFI_SSID, WIFI_PASSWORD)
print("Connecting to WiFi...", end="")
while not wifi.isconnected():
print(".", end="")
time.sleep(0.5)
print("\nWiFi connected:", wifi.ifconfig()[0])
def set_relay(state):
global relay_state
relay_state = state
RELAY_PIN.value(0 if state else 1) # Active LOW relay
LED_PIN.value(1 if state else 0) # LED ON when relay ON
print("Relay", "ON" if state else "OFF")
def read_current():
if not relay_state:
return 0 # Relay OFF →
adc_val = CURRENT_SENSOR.read()
voltage = adc_val * ADC_VOLTAGE / ADC_MAX
current = (voltage - VREF) / SENSITIVITY
return max(current, 0)
def check_alert(current):
if current > OVER_CURRENT_THRESHOLD_A:
ALERT_LED_PIN.value(1)
client.publish(MQTT_TOPIC_ALERT, b"Overcurrent")
set_relay(False)
else:
ALERT_LED_PIN.value(0)
def mqtt_callback(topic, msg):
global manual_control
print("Message:", msg)
if msg == b"ON":
manual_control = True
set_relay(True)
elif msg == b"OFF":
manual_control = True
set_relay(False)
elif msg == b"AUTO":
manual_control = False
# ==== Main Program ====
connect_wifi()
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, port=MQTT_PORT)
client.set_callback(mqtt_callback)
client.connect()
client.subscribe(MQTT_TOPIC_RELAY)
print("Connected_MQTT_broker_&_subscribed_relay topic")
# Start with relay OFF
set_relay(False)
while True:
client.check_msg()
# ==== Read Current from ACS712 ====
current_reading = read_current()
formatted_current = "{:.2f}".format(current_reading)
print(f"Current: {formatted_current}A")
client.publish(MQTT_TOPIC_CURRENT, formatted_current)
#Check Overcurrent Alert
check_alert(current_reading)
#control by current sensor
if not manual_control:
if current_reading > 0.5 and not relay_state: # Load detected
set_relay(True)
client.publish(MQTT_TOPIC_RELAY, b"ON")
elif current_reading <= 0.5 and relay_state: # No load
set_relay(False)
client.publish(MQTT_TOPIC_RELAY, b"OFF")
# ==== Toggle button (manual override) ====
if BUTTON_PIN.value() == 0:
time.sleep(0.2)
set_relay(not relay_state)
manual_control = True # manual button press overrides auto
client.publish(MQTT_TOPIC_RELAY, b"ON" if relay_state else b"OFF")
while BUTTON_PIN.value() == 0:
pass
# ==== Reset button ====
if RESET_BUTTON_PIN.value() == 0:
time.sleep(0.2)
manual_control = False # back to auto
set_relay(False)
client.publish(MQTT_TOPIC_RELAY, b"OFF")
while RESET_BUTTON_PIN.value() == 0:
pass
time.sleep(1)
Relay Status
Toggle Button
Reset Button
Alert/High Current