152 lines
4.9 KiB
Lua
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)
|