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 .. "" html = html .. "" html = html .. "" html = html .. "Autoclave" html = html .. "" html = html .. "
" html = html .. "

Autoclave Control

" html = html .. "

Status: " .. status_text .. "

" html = html .. "

Set Time: " .. format_time_min(set_time_sec, true) .. "

" html = html .. "

Remaining: " .. format_time_min(remaining_time_sec, false) .. "

" html = html .. "
" client:send(html) client:close() collectgarbage() end) end)