mirror of
https://github.com/sinseman44/PyCNC.git
synced 2026-07-16 08:37:09 +00:00
utils for PID control
This commit is contained in:
Executable
+147
@@ -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()
|
||||||
Executable
+107
@@ -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()
|
||||||
Reference in New Issue
Block a user