autoclav/init.lua
2026-09-01 12:43:55 +04:00

152 lines
4.9 KiB
Lua

main_timer = tmr.create()
cycle_timer = tmr.create()
adc_timer = tmr.create()
srv = net.createServer(net.TCP)
ap_config = {}
local pin_relay = 1
local pin_thermostat = 2
local START_DELAY_MS = 5000
local time_table = {}
local table_size = 0
local function init_time_table()
local index = 0
for m = 5, 60, 5 do
time_table[index] = m * 60
index = index + 1
end
for m = 70, 180, 10 do
time_table[index] = m * 60
index = index + 1
end
table_size = index - 1
end
init_time_table()
local adc_history = {}
local adc_index = 1
local max_samples = 10
local adc_average = 0
local set_time_sec = 300
local remaining_time_sec = 300
local process_started = false
local process_finished = false
gpio.mode(pin_relay, gpio.OUTPUT)
gpio.write(pin_relay, gpio.LOW)
gpio.mode(pin_thermostat, gpio.INPUT, gpio.PULLUP)
print("System init delay...")
local function read_averaged_adc()
local raw = adc.read(0)
adc_history[adc_index] = raw
adc_index = adc_index + 1
if adc_index > max_samples then adc_index = 1 end
local sum = 0
local count = 0
for i = 1, max_samples do
if adc_history[i] then
sum = sum + adc_history[i]
count = count + 1
end
end
adc_average = sum / count
local tbl_index = (adc_average * table_size) / 1023
if tbl_index < 0 then tbl_index = 0 end
if tbl_index > table_size then tbl_index = table_size end
set_time_sec = time_table[tbl_index]
if not process_started then
remaining_time_sec = set_time_sec
end
end
adc_timer:register(200, tmr.ALARM_AUTO, read_averaged_adc)
main_timer:register(START_DELAY_MS, tmr.ALARM_SINGLE, function()
print("Heater ON. Waiting thermostat...")
gpio.write(pin_relay, gpio.HIGH)
adc_timer:start()
cycle_timer:register(1000, tmr.ALARM_AUTO, function()
local thermo_state = gpio.read(pin_thermostat)
local left_min = (remaining_time_sec + 59) / 60
local set_min = set_time_sec / 60
print("TMR: Left=" .. left_min .. "m | Set=" .. set_min .. "m | Input D2=" .. thermo_state)
if not process_started and not process_finished then
if thermo_state == gpio.HIGH then
process_started = true
adc_timer:stop()
print("Target reached! Timer active: " .. set_min .. "m")
end
elseif process_started and not process_finished then
if remaining_time_sec > 0 then
remaining_time_sec = remaining_time_sec - 1
else
process_started = false
process_finished = true
gpio.write(pin_relay, gpio.LOW)
print("Process finished. Heater OFF.")
cycle_timer:stop()
end
end
end)
cycle_timer:start()
end)
main_timer:start()
wifi.setmode(wifi.SOFTAP)
ap_config.ssid = "Autoclave_Control"
ap_config.auth = wifi.OPEN
wifi.ap.config(ap_config)
print("AP Ready. IP: " .. wifi.ap.getip())
srv:listen(80, function(conn)
conn:on("receive", function(client, request)
local function format_time_min(sec, is_set)
local total_min = 0
if is_set then
total_min = sec / 60
else
total_min = (sec + 59) / 60
end
local h = total_min / 60
local m = total_min % 60
return string.format("%02d:%02d", h, m)
end
local status_text = "Heating"
if process_started then status_text = "Sterilization" end
if process_finished then status_text = "Done" end
local html = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
html = html .. "<!DOCTYPE html><html><head>"
html = html .. "<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
html = html .. "<meta http-equiv='refresh' content='5'>"
html = html .. "<title>Autoclave</title>"
html = html .. "<style>body{font-family:sans-serif;text-align:center;background:#f4f4f4;padding:20px;}"
html = html .. ".card{background:white;padding:20px;border-radius:10px;box-shadow:0 4px 8px rgba(0,0,0,0.1);max-width:400px;margin:0 auto;}"
html = html .. "h1{color:#333;} .status{font-size:24px;font-weight:bold;color:#d9534f;}</style>"
html = html .. "</head><body><div class='card'>"
html = html .. "<h1>Autoclave Control</h1>"
html = html .. "<p>Status: <span class='status'>" .. status_text .. "</span></p>"
html = html .. "<p>Set Time: <b>" .. format_time_min(set_time_sec, true) .. "</b></p>"
html = html .. "<p>Remaining: <b style='font-size:30px;color:#5cb85c;'>" .. format_time_min(remaining_time_sec, false) .. "</b></p>"
html = html .. "</div></body></html>"
client:send(html)
client:close()
collectgarbage()
end)
end)