from machine import Pin
from time import sleep, ticks_ms
from dht import DHT22
# تنظیم پایههای رله (Relays) به صورت خروجی (OUT)
Relays = [Pin(i, Pin.OUT) for i in [28, 27, 26, 22]]
# تنظیم سنسور دما و رطوبت DHT22
dht_sensor = DHT22(Pin(16))
# تنظیم شستی پاور (Power button)، شستیهای دستی و شستی برای سوییچ بین حالت دستی و خودکار
power_button = Pin(2, Pin.IN, Pin.PULL_UP) # شستی پاور
manual_buttons = [Pin(i, Pin.IN, Pin.PULL_UP) for i in range(4, 7)] # شستیهای دستی برای کنترل رلهها
mode_switch = Pin(3, Pin.IN, Pin.PULL_UP) # شستی برای تغییر بین حالت دستی و خودکار
# وضعیت کلیدها و زمان آخرین فشردن آنها
button_flags = [False] * len(manual_buttons) # آرایهای برای نگهداری وضعیت دکمههای دستی
button_last_press = [0] * (len(manual_buttons) + 2) # زمان آخرین فشردن هر دکمه
# ذخیرهسازی وضعیتهای پاور و حالت سیستم (دستی یا خودکار)
state = {
"power_on": False, # وضعیت روشن یا خاموش بودن سیستم
"manual_mode": True, # حالت دستی یا خودکار
"last_power_state": False, # آخرین وضعیت پاور
"mode_switch": False, # وضعیت سوییچ حالت
"last_action_time": 0, # زمان آخرین عملی که انجام شده
"cooldown_time": 5000, # زمان خنککاری برای جلوگیری از تغییرات مکرر
"last_temp": None, # آخرین دمای خوانده شده
"last_auto_message": None, # آخرین پیام کنترل خودکار
}
# زمان مجاز برای دفع نویز دکمهها (Debounce) به میلیثانیه
DEBOUNCE_TIME = 50
# بازههای دمایی برای کنترل خودکار
TEMP_RANGES = {"MIN": 18, "NORMAL_MIN": 24, "NORMAL_MAX": 27}
# تابع خواندن دما از سنسور DHT22
def temperature():
try:
dht_sensor.measure() # خواندن دادهها از سنسور
temp = dht_sensor.temperature() # دریافت دما
if temp != state["last_temp"]: # فقط اگر دما تغییر کرده باشد
print(f"Temperature measured: {temp}C") # چاپ دما
state["last_temp"] = temp # بهروزرسانی دما
return temp
except Exception as e:
print(f"Sensor Error: {e}") # چاپ خطای سنسور
return None
# تابع کنترل خودکار
def auto_control():
temp = temperature() # دریافت دما از سنسور
if temp is None: # اگر خطا رخ داده باشد
return
current_time = ticks_ms() # زمان کنونی
# چک کردن بازه زمانی برای جلوگیری از تغییرات مکرر در کولر
if current_time - state["last_action_time"] < state["cooldown_time"]:
return # جلوگیری از روشن/خاموش کردن در بازه cooldown
relay_status = [0] * 4 # تنظیم تمامی رلهها به خاموش
# تصمیمگیری بر اساس دما
if temp < TEMP_RANGES["MIN"]:
relay_status = [0, 0, 0, 0] # همه رلهها خاموش
elif temp < TEMP_RANGES["NORMAL_MIN"]:
relay_status = [1, 0, 0, 0] # رلهها خاموش جز رله پاور
elif temp <= TEMP_RANGES["NORMAL_MAX"]:
relay_status = [1, 1, 1, 1] # همه رلهها روشن
else:
relay_status = [1, 1, 1, 0] # رلهها 1، 2 و 3 روشن و 4 خاموش
# بهروزرسانی وضعیت رلهها
for i in range(len(relay_status)):
if relay_status[i] != Relays[i].value(): # مطمئن شویم که به رله 0 تا 3 دسترسی داریم
Relays[i].value(relay_status[i]) # تغییر وضعیت رله
# تعیین پیام جدید
new_message = ""
if temp < TEMP_RANGES["MIN"]:
new_message = f"Temperature below {TEMP_RANGES['MIN']}C, all relays off."
elif temp < TEMP_RANGES["NORMAL_MIN"]:
new_message = f"Temperature below {TEMP_RANGES['NORMAL_MIN']}C, power on."
elif temp <= TEMP_RANGES["NORMAL_MAX"]:
new_message = f"Temperature in normal range ({TEMP_RANGES['NORMAL_MIN']}-{TEMP_RANGES['NORMAL_MAX']}C), all relays on."
else:
new_message = f"Temperature above {TEMP_RANGES['NORMAL_MAX']}C, relays 1, 2, 3 on, relay 4 off."
# فقط زمانی که پیام جدید با پیام قبلی متفاوت باشد، پرینت کن
if new_message != state["last_auto_message"]:
print(f"Auto control: {new_message}")
state["last_auto_message"] = new_message
state["last_action_time"] = current_time # بهروزرسانی زمان آخرین تغییر حالت
# تابع کنترل کلی سیستم و شستی پاور
def system_control():
current_time = ticks_ms() # زمان کنونی
# کنترل شستی پاور
if not power_button.value() == state["power_on"]: # اگر وضعیت دکمه پاور تغییر کند
if current_time - button_last_press[0] > DEBOUNCE_TIME: # جلوگیری از نویز
state["power_on"] = not state["power_on"] # تغییر وضعیت پاور
Relays[0].value(state["power_on"]) # تغییر وضعیت رله مرتبط با پاور
if not state["power_on"]: # اگر پاور خاموش شده باشد
for relay in Relays: # خاموش کردن تمامی رلهها
relay.value(0)
button_last_press[0] = current_time # بهروزرسانی زمان آخرین فشردن دکمه
print(f"System control: Power {'on' if state['power_on'] else 'off'}, relay 0 {'on' if state['power_on'] else 'off'}")
# کنترل شستی تغییر حالت
if not mode_switch.value() == state["mode_switch"]:
if current_time - button_last_press[1] > DEBOUNCE_TIME:
state["mode_switch"] = not state["mode_switch"] # تغییر وضعیت سوییچ حالت
state["manual_mode"] = not state["manual_mode"] # تغییر بین حالت دستی و خودکار
button_last_press[1] = current_time # بهروزرسانی زمان آخرین فشردن
print(f"System control: Switched to {'manual' if state['manual_mode'] else 'auto'} mode")
# کنترل شستیهای دستی فقط در حالت دستی
if state["manual_mode"]: # بررسی اینکه آیا در حالت دستی هستیم
for i in range(len(manual_buttons)):
if not manual_buttons[i].value() == button_flags[i]: # بررسی تغییر وضعیت دکمه
if current_time - button_last_press[i + 2] > DEBOUNCE_TIME: # جلوگیری از نویز
button_flags[i] = not button_flags[i] # تغییر وضعیت دکمه
Relays[i + 1].value(button_flags[i]) # تغییر وضعیت رله مرتبط
button_last_press[i + 2] = current_time # بهروزرسانی زمان آخرین فشردن
print(f"Manual control: Relay {i + 1} {'on' if button_flags[i] else 'off'}")
# حلقه اصلی برنامه که به صورت مداوم اجرا میشود
while True:
system_control() # کنترل سیستم و شستی پاور
if state["power_on"]: # بررسی روشن بودن سیستم
if not state["manual_mode"]: # اگر در حالت خودکار هستیم
auto_control() # کنترل خودکار بر اساس دما
sleep(0.2) # تاخیر 200 میلیثانیهای