forked from M-Labs/kirdy
Update PID Autotune Code
This commit is contained in:
parent
0380c8d30b
commit
c06491a8b2
|
@ -6,6 +6,8 @@ import socket
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
import signal
|
import signal
|
||||||
|
from driver.kirdy_async import Kirdy
|
||||||
|
import asyncio
|
||||||
|
|
||||||
# Based on hirshmann pid-autotune libiary
|
# Based on hirshmann pid-autotune libiary
|
||||||
# See https://github.com/hirschmann/pid-autotune
|
# See https://github.com/hirschmann/pid-autotune
|
||||||
|
@ -219,92 +221,96 @@ class PIDAutotune:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tec_power_up = {
|
|
||||||
"thermostat_cmd": "PowerUp",
|
|
||||||
}
|
|
||||||
|
|
||||||
tec_power_down = {
|
async def main():
|
||||||
"thermostat_cmd": "PowerDown",
|
"""
|
||||||
}
|
PID AutoTune Tools for Kirdy
|
||||||
|
The obtained temperature works best at the target temperature specified.
|
||||||
|
Before running PID AutoTune, please
|
||||||
|
1. Secure the laser diode onto the LD adapter and copper heat sink
|
||||||
|
2. Make sure Kirdy has warmed up and reached thermal equilibrium state
|
||||||
|
|
||||||
kirdy_get_status_report = {
|
In case of PID Autotune Failure, you can
|
||||||
"device_cmd": "GetStatusReport",
|
1. Run the PID Autotune again
|
||||||
}
|
2. Or increase the lookback period
|
||||||
|
3. Or increase the sampling rate
|
||||||
|
"""
|
||||||
|
|
||||||
tec_get_tec_status = {
|
|
||||||
"thermostat_cmd": "GetTecStatus",
|
|
||||||
}
|
|
||||||
|
|
||||||
tec_pid_dis_engage = {
|
|
||||||
"thermostat_cmd": "SetPidDisEngage",
|
|
||||||
}
|
|
||||||
|
|
||||||
tec_set_i_out = {
|
|
||||||
"tec_set_i": 0.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kirdy IP and Port Number
|
|
||||||
HOST = "192.168.1.132"
|
|
||||||
PORT = 1337
|
|
||||||
SAMPLING_RATE = 16.67
|
|
||||||
|
|
||||||
def send_cmd(input, socket):
|
|
||||||
socket.send(bytes(json.dumps(input), "UTF-8"))
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
def read_cmd(input, socket):
|
|
||||||
socket.send(bytes(json.dumps(input), "UTF-8"))
|
|
||||||
data = socket.recv(1024).decode('utf8')
|
|
||||||
return json.loads(data)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Target temperature of the autotune routine, celsius
|
# Target temperature of the autotune routine, celsius
|
||||||
target_temperature = 20
|
target_temperature = 20
|
||||||
# Value by which output will be increased/decreased from zero, amps
|
# Value by which output will be increased/decreased from zero, amps
|
||||||
output_step = 1
|
output_step = 1
|
||||||
# Reference period for local minima/maxima, seconds
|
# Reference period for local minima/maxima, seconds
|
||||||
lookback = 1
|
lookback = 2.0
|
||||||
# Determines by how much the input value must
|
# Determines by how much the input value must
|
||||||
# overshoot/undershoot the setpoint, celsius
|
# overshoot/undershoot the setpoint, celsius
|
||||||
noiseband = 1.5
|
noiseband = 1.5
|
||||||
|
|
||||||
|
kirdy = Kirdy()
|
||||||
|
await kirdy.start_session(host='192.168.1.128', port=1337, timeout=0.25)
|
||||||
|
|
||||||
|
await kirdy.laser.set_power_on(False)
|
||||||
|
await kirdy.laser.set_i(0)
|
||||||
|
|
||||||
|
await kirdy.thermostat.set_power_on(False)
|
||||||
|
await kirdy.thermostat.set_constant_current_control_mode()
|
||||||
|
await kirdy.thermostat.set_tec_i_out(0)
|
||||||
|
await kirdy.thermostat.clear_alarm()
|
||||||
|
|
||||||
|
class SignalHandler:
|
||||||
|
KEEP_PROCESSING = True
|
||||||
|
def __init__(self):
|
||||||
|
signal.signal(signal.SIGINT, self.exit_gracefully)
|
||||||
|
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||||
|
|
||||||
|
def exit_gracefully(self, signum, frame):
|
||||||
|
self.KEEP_PROCESSING = False
|
||||||
|
signal_handler = SignalHandler()
|
||||||
|
|
||||||
|
await kirdy.device.set_active_report_mode(False)
|
||||||
|
|
||||||
|
# Configure the Thermistor Parameters
|
||||||
|
await kirdy.thermostat.set_sh_beta(3900)
|
||||||
|
await kirdy.thermostat.set_sh_r0(10.0 * 1000)
|
||||||
|
await kirdy.thermostat.set_sh_t0(25)
|
||||||
|
|
||||||
|
# Set a large enough temperature range so that it won't trigger overtemperature protection
|
||||||
|
await kirdy.thermostat.set_temp_mon_upper_limit(target_temperature + 20)
|
||||||
|
await kirdy.thermostat.set_temp_mon_lower_limit(target_temperature - 20)
|
||||||
|
|
||||||
|
await kirdy.thermostat.set_tec_max_i_pos(output_step)
|
||||||
|
await kirdy.thermostat.set_tec_max_i_neg(output_step)
|
||||||
|
|
||||||
|
# The Polling Rate of Temperature Adc is equal to the PID Update Interval
|
||||||
|
await kirdy.thermostat.config_temp_adc_filter("Sinc5Sinc1With50hz60HzRejection", "F16SPS")
|
||||||
|
settings = await kirdy.device.get_settings_summary()
|
||||||
|
sampling_rate = settings["thermostat"]["temp_adc_settings"]["rate"]
|
||||||
|
|
||||||
|
print("Settings: {0}".format(settings))
|
||||||
|
|
||||||
tuner = PIDAutotune(target_temperature, output_step,
|
tuner = PIDAutotune(target_temperature, output_step,
|
||||||
lookback, noiseband, 1/SAMPLING_RATE)
|
lookback, noiseband, 1/sampling_rate)
|
||||||
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
await kirdy.thermostat.set_power_on(True)
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
while True and signal_handler.KEEP_PROCESSING:
|
||||||
send_cmd(tec_power_down, s)
|
status_report = await kirdy.device.get_status_report()
|
||||||
s.close()
|
|
||||||
exit()
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
temperature = status_report["thermostat"]["temperature"]
|
||||||
|
|
||||||
s.connect((HOST, PORT))
|
|
||||||
|
|
||||||
send_cmd(tec_pid_dis_engage, s)
|
|
||||||
send_cmd(tec_power_down, s)
|
|
||||||
send_cmd(tec_power_up, s)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
status_report = read_cmd(kirdy_get_status_report, s)
|
|
||||||
|
|
||||||
temperature = status_report["tec"]["temperature"] - 273.15
|
|
||||||
print(temperature)
|
|
||||||
ts = status_report['ts']
|
ts = status_report['ts']
|
||||||
|
print("Ts: {0} Current Temperature: {1} degree".format(ts, temperature))
|
||||||
|
|
||||||
if (tuner.run(temperature, ts / 1000.0)):
|
if (tuner.run(temperature, ts / 1000.0)):
|
||||||
|
print(tuner._state)
|
||||||
break
|
break
|
||||||
|
|
||||||
tuner_out = tuner.output()
|
tuner_out = tuner.output()
|
||||||
|
await kirdy.thermostat.set_tec_i_out(float(tuner_out))
|
||||||
|
|
||||||
tec_set_i_out["tec_set_i"] = float(tuner_out * 1000.0)
|
await kirdy.thermostat.set_tec_i_out(0)
|
||||||
|
await kirdy.thermostat.set_power_on(False)
|
||||||
|
|
||||||
send_cmd(tec_set_i_out, s)
|
await kirdy.end_session()
|
||||||
|
|
||||||
tec_set_i_out["tec_set_i"] = 0.0
|
|
||||||
send_cmd(tec_power_down, s)
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
asyncio.run(main())
|
||||||
|
|
Loading…
Reference in New Issue