"""
🔥 KAZÁN-SZIVATTYÚ VEZÉRLŐ (PICO) - 2 GOMBOS VÁLTOZAT
------------------------------------------------------
GOMBOK (GP7 = FEL, GP9 = LE):
1. BELÉPÉS LIMITHEZ: Tartsd nyomva a [LE] gombot (3-5 mp).
2. BELÉPÉS KALIBRÁCIÓHOZ: Tartsd nyomva a [FEL] gombot (3-5 mp).
3. VÁLTÁS (START/STOP): Beállítás közben [FEL+LE] rövid megnyomása.
4. MENTÉS ÉS KILÉPÉS: Bármely módban [FEL+LE] hosszú nyomása (3-5 mp).
5. RESET: Alaphelyzetben [FEL+LE] hosszú nyomása (5 mp).
6. IDŐTÚLLÉPÉS: 60 mp tétlenség után mentés nélkül kilép (Biztonság!).
------------------------------------------------------
"""
import machine
import utime
import math
import os
# --- PINEK ---
ntc_pin = machine.ADC(26)
szivattyu_relay_pin = machine.Pin(3, machine.Pin.OUT)
kazan_realy_pin = machine.Pin(2, machine.Pin.OUT)
led_pins = [machine.Pin(i, machine.Pin.OUT) for i in range(6, 16)]
btn_plus = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP) # FEL
btn_minus = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP) # LE
# --- VÁLTOZÓK ---
start_temp, stop_temp, offset = 30, 40, 0.0
mode = 0 # 0:Üzem, 1:Start, 2:Stop, 3:Kalibráció, 4:RESET
szivattyu_fut = False
last_measure = 0
last_activity = utime.ticks_ms()
# Időmérés a gombokhoz
p_start, m_start, both_start = 0, 0, 0
p_handled, m_handled, both_handled = False, False, False
def save_all():
try:
with open("settings.txt", "w") as f:
f.write(f"{start_temp},{stop_temp},{offset}")
print(f">>> MENTVE: Start:{start_temp} Stop:{stop_temp} Offset:{round(offset,1)}")
except: pass
def load_all():
global start_temp, stop_temp, offset
try:
if "settings.txt" in os.listdir():
with open("settings.txt", "r") as f:
d = f.read().split(",")
start_temp, stop_temp, offset = int(d[0]), int(d[1]), float(d[2])
print(">>> BEÁLLÍTÁSOK BETÖLTVE")
except: print(">>> ALAPÉRTÉKEK HASZNÁLATA")
load_all()
# ÜZEMIDŐ MÉRÉSE
total_runtime = 0.0
pump_start_ms = 0
def load_runtime():
global total_runtime
try:
with open("total_run.txt", "r") as f:
total_runtime = float(f.read())
except: total_runtime = 0.0
def save_runtime(plus_time):
global total_runtime
total_runtime += plus_time
try:
with open("total_run.txt", "w") as f:
f.write(str(total_runtime))
except: pass
load_runtime() # Indításkor betölti az eddigi összes üzemidőt
# Saját NTCM-10K-B3380 használatakor pico-n ez kell
"""
# --->
def get_ntc_temp():
# 10 mérés átlagolása a zajszűréshez (Pico ADC-je meghálálja)
total = 0
for _ in range(10):
total += ntc_pin.read_u16()
utime.sleep_ms(1)
avg = total / 10
# Biztonsági korlátok (szakadás vagy rövidzár)
if avg >= 65400: return 99.0
if avg <= 100: return -99.0
# Ellenállás kiszámítása a bekötésed alapján:
# 3.3V -> NTC -> GP26 -> 10k -> GND
# Képlet: R_ntc = R_fix * ( (ADC_max / ADC_val) - 1 )
try:
res_ntc = 10000.0 * ((65535.0 / avg) - 1.0)
# B-paraméteres egyenlet (B=3380 az NTC-d adatlapja szerint)
# T0=25C (298.15K), R0=10k
inv_t = (math.log(res_ntc / 10000.0) / 3380.0) + (1.0 / (25.0 + 273.15))
temp_c = (1.0 / inv_t) - 273.15
return temp_c + offset
except:
return -99.0
# <---
"""
# WOKWI: 3950 ez kell ha pico-n ezt az egész def fügvényt ki kommentelni. """
def get_temp():
raw = ntc_pin.read_u16()
if raw < 100: raw = 100
res = 10000.0 * (raw / (65535.0 - raw))
try:
# WOKWI: 3950, VALÓDI NTC-3380: Írd át 3380-ra!
st = math.log(res / 10000.0) / 3950.0
st += 1.0 / (25.0 + 273.15)
return (1.0 / st) - 273.15 + offset
except: return -99.0
# """
print("--- RENDSZER INDUL (2 GOMB + BIZTONSÁG) ---")
while True:
t_ms = utime.ticks_ms()
p_act = btn_plus.value() == 0
m_act = btn_minus.value() == 0
if p_act or m_act: last_activity = t_ms
# AUTOMATIKUS KILÉPÉS (60 mp)
if mode != 0 and utime.ticks_diff(t_ms, last_activity) > 60000:
mode = 0; print(">>> IDŐTÚLLÉPÉS: Kilépés mentés nélkül!")
# --- GOMB LOGIKA ---
if p_act and m_act: # MINDKETTŐ NYOMVA
if both_start == 0: both_start = t_ms
if not both_handled and utime.ticks_diff(t_ms, both_start) > 3000:
if mode == 0: mode = 4; print(">>> MÓD: RESET VÁRAKOZÁS")
elif mode == 4:
offset = 0.0; save_all(); mode = 0; print(">>> RESET KÉSZ")
else: save_all(); mode = 0; print(">>> MENTVE ÉS KILÉPVE")
both_handled = True
p_start = m_start = 0
elif p_act: # CSAK FEL
if p_start == 0: p_start = t_ms
if not p_handled and mode == 0 and utime.ticks_diff(t_ms, p_start) > 3000:
mode = 3; p_handled = True; print(">>> MÓD: KALIBRÁCIÓ")
if mode > 0 and not p_handled:
if mode == 1 and start_temp < 34: start_temp += 2; print(f"Start: {start_temp}")
if mode == 2 and stop_temp < 44: stop_temp += 2; print(f"Stop: {stop_temp}")
if mode == 3: offset += 0.1; print(f"Offset: {round(offset,1)}")
utime.sleep_ms(250)
both_start = 0
utime.sleep_ms(400)
elif m_act: # CSAK LE
if m_start == 0: m_start = t_ms
if not m_handled and mode == 0 and utime.ticks_diff(t_ms, m_start) > 3000:
mode = 1; m_handled = True; print(">>> MÓD: LIMIT (START)")
if mode > 0 and not m_handled:
if mode == 1 and start_temp > 26: start_temp -= 2; print(f"Start: {start_temp}")
if mode == 2 and stop_temp > 36: stop_temp -= 2; print(f"Stop: {stop_temp}")
if mode == 3: offset -= 0.1; print(f"Offset: {round(offset,1)}")
utime.sleep_ms(250)
both_start = 0
utime.sleep_ms(400)
else: # SEMMI NINCS NYOMVA
if 0 < utime.ticks_diff(t_ms, both_start) < 1000 and not both_handled:
if mode == 1: mode = 2; print(">>> VÁLTÁS: STOP LIMIT")
elif mode == 2: mode = 1; print(">>> VÁLTÁS: START LIMIT")
both_start = p_start = m_start = 0
both_handled = p_handled = m_handled = False
# --- MEGJELENÍTÉS ÉS VEZÉRLÉS ---
if mode == 1 or mode == 2:
for i, lp in enumerate(led_pins):
target = start_temp if mode == 1 else stop_temp
lp.value(1 if (26+i*2 == target and (t_ms//200)%2) else 0)
elif mode == 3:
abs_step = int(abs(offset) * 10 + 0.05)
phase = (t_ms // 350) % (abs_step + 2)
for i, lp in enumerate(led_pins):
led_state = 0
if offset >= 0.05:
if phase < abs_step: led_state = 1 if i == phase else 0
else: led_state = 1 if (i == abs_step-1 and (t_ms//250)%2) else 0
elif offset <= -0.05:
target_idx = 10 - abs_step
if phase < abs_step: led_state = 1 if i == (9-phase) else 0
else: led_state = 1 if (i == target_idx and (t_ms//250)%2) else 0
else: led_state = 1 if (i == 0 and (t_ms//400)%2) else 0
lp.value(led_state)
elif mode == 4:
for i, lp in enumerate(led_pins):
lp.value(1 if (i in [4, 5] and (t_ms//300)%2) else 0)
else: # MODE 0 - NORMÁL ÜZEM
for i, lp in enumerate(led_pins):
lepcso = 26 + (i * 2)
lp.value(1 if (lepcso == start_temp or lepcso == stop_temp) else 0)
if utime.ticks_diff(t_ms, last_measure) > 1000:
akt = get_temp()
last_measure = t_ms
if not szivattyu_fut and akt >= stop_temp:
szivattyu_fut = True
pump_start_ms = utime.ticks_ms() # Elmentjük az indulás pillanatát
print("SZIVATTYÚ BEKAPCSOL")
elif szivattyu_fut and akt <= start_temp:
szivattyu_fut = False
# Üzemidő kiszámítása és mentése
diff = utime.ticks_diff(utime.ticks_ms(), pump_start_ms)
save_runtime(diff / 1000.0)
print(f"SZIVATTYÚ KIKAPCSOL. Összesen: {round(total_runtime/3600, 2)} óra")
# --- FIZIKAI KIMENETEK FRISSÍTÉSE ---
# Szivattyú relé
szivattyu_relay_pin.value(1 if szivattyu_fut else 0)
# Kazán relé (48 fok felett tilt)
# Ha akt > 48, akkor a relé 0 (kikapcsol), különben 1 (mehet)
if akt > 48:
kazan_realy_pin.value(1)
print(f"!!! KAZÁN TILTVA (T > 48°C) !!!")
else:
kazan_realy_pin.value(0)
print(f"KAZÁN MEGY")
print(f"Víz: {round(akt,1)}°C | Start:{start_temp} Stop:{stop_temp} Offset: {round(offset,1)} | Keringető: {'BE' if szivattyu_fut else 'KI'}")
utime.sleep_ms(20)