diff --git a/utils/heater_model_finder.py b/utils/heater_model_finder.py new file mode 100755 index 0000000..e39058e --- /dev/null +++ b/utils/heater_model_finder.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python + +import os +import sys +import time + +cnc_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) +sys.path.append(cnc_dir) +from cnc.hal_raspberry import hal + + +""" +This executable module is looking for heating and cooling transfer coefficients. +Can be ran only on real hardware. +""" + +# change settings below for your hardware/environment +EXTRUDER_MAX_TEMPERATURE = 200 +EXTRUDER_DELTA_TEMPERATURE = 50 +BED_MAX_TEMPERATURE = 70 +BED_DELTA_TEMPERATURE = 10 +ENVIRONMENT_TEMPERATURE = 25 + + +# finder itself +def finder(max_temperature, delta_temperature, get_temperature, control): + ca = 0 + cn = 0 + ha = 0 + hn = 0 + print("Heating...") + control(100) + last_t = get_temperature() + last_time = time.time() + heated = False + while True: + t = get_temperature() + if t >= max_temperature: + if not heated: + control(0) + heated = True + if heated and t <= max_temperature: + break + if abs(last_t - t) >= 1: + print("Temperature is " + str(t)) + last_time = time.time() + last_t = t + time.sleep(0.1) + print("Heated, measure cooling transfer coefficient.") + while True: + t = get_temperature() + if abs(last_t - t) >= 1: + current_time = time.time() + if t <= max_temperature - delta_temperature: + break + v = abs(last_t - t) \ + / abs((last_t + t) / 2.0 - ENVIRONMENT_TEMPERATURE) \ + / (current_time - last_time) + print("Temperature is {}, coefficient is {}".format(t, v)) + ca += v + cn += 1 + last_time = current_time + last_t = t + time.sleep(0.001) + c = ca / float(cn) + print("Cooled off, waiting...") + time.sleep(60) + print("Heating, measure heating transfer coefficient.") + control(100) + heat_start = 0 + while True: + t = get_temperature() + if abs(last_t - t) >= 1: + current_time = time.time() + if t > max_temperature: + heat_end = current_time + break + if t >= max_temperature - delta_temperature: + ct = last_t \ + - c * (current_time - last_time) \ + * abs((last_t + t) / 2.0 - ENVIRONMENT_TEMPERATURE) + v = abs(t - ct) / (current_time - last_time) + print("Temperature is {}, coefficient is {}".format(t, v)) + if hn == 0: + heat_start = current_time + ha += v + hn += 1 + else: + print("Temperature is " + str(t)) + last_time = current_time + last_t = t + time.sleep(0.001) + h = ha / float(hn) + control(0) + print("Testing results...") + # quick test + heat_time = heat_end - heat_start + t = max_temperature - delta_temperature + for i in range(0, int(heat_time + 0.5)): + t -= abs((t - ENVIRONMENT_TEMPERATURE)) * c + t += h + model_status = abs(max_temperature - t) < max_temperature * 0.1 + print("Model quick test result is {}/{} - {}" + .format(t, max_temperature, model_status)) + print("Cooling transfer coefficient is " + str(c)) + print("Heating transfer coefficient is " + str(h)) + return c, h + + +# finder itself +def main(): + hal.init() + try: + hal.fan_control(True) + print("Running for extruder...") + try: + ec, eh = finder(EXTRUDER_MAX_TEMPERATURE, + EXTRUDER_DELTA_TEMPERATURE, + hal.get_extruder_temperature, + hal.extruder_heater_control) + except (IOError, OSError): + ec, eh = None, None + print("Extruder malfunction") + hal.extruder_heater_control(0) + print("Running for bed...") + try: + bc, bh = finder(BED_MAX_TEMPERATURE, + BED_DELTA_TEMPERATURE, + hal.get_bed_temperature, + hal.bed_heater_control) + except (IOError, OSError): + bc, bh = None, None + print("Bed malfunction") + hal.bed_heater_control(0) + print("Done") + print("Extruder transfer coefficients, cooling {}, heating {}" + .format(ec, eh)) + print("Bed transfer coefficients, cooling {}, heating {}" + .format(bc, bh)) + hal.fan_control(False) + except KeyboardInterrupt: + pass + hal.deinit() + + +if __name__ == '__main__': + main() diff --git a/utils/pid_finder.py b/utils/pid_finder.py new file mode 100755 index 0000000..2aa16f1 --- /dev/null +++ b/utils/pid_finder.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +import os +import sys +import time + +cnc_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) +sys.path.append(cnc_dir) +from cnc.hal_raspberry import hal + +""" +This executable module is looking for PID coefficients. +Can be ran only on real hardware. +""" + +# change settings below for your hardware/environment +EXTRUDER_TARGET_TEMPERATURE = 200 +BED_TARGET_TEMPERATURE = 70 +DUMMY_CYCLES = 2 +TOTAL_CYCLES = 7 + + +# finder itself +def finder(target_temperature, get_temperature, control): + print("Heating...") + on = True + control(100) + last_t = get_temperature() + last_time = time.time() + max_t = 0 + min_t = 10000 + cycle_number = 0 + cycle_accumulator = 0 + cycle_counter = 0 + cycle_time = 0 + while True: + current_time = time.time() + t = get_temperature() + time_filter = (current_time - last_time) > 0.1 + if t >= target_temperature and on and time_filter: + on = False + control(0) + last_time = current_time + cycle_number += 1 + if cycle_number > DUMMY_CYCLES: + print("Cycle took {} s".format(current_time - cycle_time)) + cycle_accumulator += current_time - cycle_time + cycle_counter += 1 + cycle_time = current_time + if t < target_temperature and not on and time_filter: + if cycle_number > TOTAL_CYCLES: + break + on = True + control(100) + last_time = current_time + if abs(last_t - t) >= 1: + print("Temperature is {}, cycle #{}".format(t, cycle_number)) + last_t = t + if cycle_number > DUMMY_CYCLES: + if t > max_t: + max_t = t + if t < min_t: + min_t = t + time.sleep(0.001) + d_temperature = max_t - min_t + d_time = cycle_accumulator / cycle_counter + print("dT={}, dt={}".format(d_temperature, d_time)) + p = 1.0 / (1.2 * d_temperature) + i = 1.0 / (15.0 * d_time) + d = 1.0 / (0.15 * d_time) + print("Finder result P={}, I={}, D={}".format(p, i, d)) + return p, i, d + + +# finder itself +def main(): + hal.init() + try: + hal.fan_control(True) + print("Running for extruder...") + try: + ep, ei, ed = finder(EXTRUDER_TARGET_TEMPERATURE, + hal.get_extruder_temperature, + hal.extruder_heater_control) + except (IOError, OSError): + ep, ei, ed = None, None, None + print("Extruder malfunction") + hal.extruder_heater_control(0) + print("Running for bed...") + try: + bp, bi, bd = finder(BED_TARGET_TEMPERATURE, + hal.get_bed_temperature, + hal.bed_heater_control) + except (IOError, OSError): + bp, bi, bd = None, None, None + print("Bed malfunction") + print("Done") + print("Extruder P={}, I={}, D={}".format(ep, ei, ed)) + print("Bed P={}, I={}, D={}".format(bp, bi, bd)) + hal.bed_heater_control(0) + hal.fan_control(False) + except KeyboardInterrupt: + pass + hal.deinit() + + +if __name__ == '__main__': + main()