Skip to content

Commit

Permalink
utils for PID control
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolay-Kha committed Jun 18, 2017
1 parent 87df112 commit df7eba6
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 0 deletions.
147 changes: 147 additions & 0 deletions utils/heater_model_finder.py
Original file line number Diff line number Diff line change
@@ -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()
107 changes: 107 additions & 0 deletions utils/pid_finder.py
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit df7eba6

Please sign in to comment.