Files
kirdy/pykirdy/autotune_example.py
2025-03-11 18:26:27 +08:00

108 lines
3.8 KiB
Python

from pykirdy.aioclient import Kirdy, FilterConfig
from pykirdy.autotune import PIDAutotune
import asyncio
import signal
import json
from sipyco.asyncio_tools import SignalHandler
async def main():
"""
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
In case of PID Autotune Failure, you can
1. Run the PID Autotune again
2. Or increase the lookback period
3. Or increase the sampling rate
"""
# Target temperature of the autotune routine, celsius
target_temperature = 20
# Value by which output will be increased/decreased from zero, amps
output_step = 1
# Reference period for local minima/maxima, seconds
lookback = 2.0
# Determines by how much the input value must
# overshoot/undershoot the setpoint, celsius
noiseband = 2.0
kirdy = Kirdy()
kirdy.start_session(host='192.168.1.134', port=1550)
await kirdy.wait_until_connected()
while not(kirdy.connected()):
pass
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()
signal_handler = SignalHandler()
signal_handler.setup()
async def sig_handling():
await signal_handler.wait_terminate()
tuner.setFailed()
asyncio.create_task(sig_handling())
# Configure the Thermistor Parameters
await kirdy.thermostat.set_sh_beta(3950)
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_cooling_i(output_step)
await kirdy.thermostat.set_tec_max_heating_i(output_step)
# The Polling Rate of Temperature Adc is equal to the PID Update Interval
await kirdy.thermostat.config_temp_adc_filter(FilterConfig.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,
lookback, noiseband, 1/sampling_rate)
await kirdy.thermostat.set_power_on(True)
while True:
status_report = await kirdy.device.get_status_report()
temperature = status_report["thermostat"]["temperature"]
ts = status_report['ts']
print("Ts: {0} Current Temperature: {1} degree".format(ts, temperature))
if (tuner.run(temperature, ts / 1000.0)):
print(tuner._state)
break
tuner_out = tuner.output()
await kirdy.thermostat.set_tec_i_out(float(tuner_out))
await kirdy.thermostat.set_tec_i_out(0)
await kirdy.thermostat.set_power_on(False)
# if tuner.state() == PIDAutotuneState.STATE_SUCCEEDED:
# pid_params = tuner.get_pid_parameters(tuning_rule="tyreus-luyben")
# await kirdy.thermostat.set_pid_kp(pid_params.Kp)
# await kirdy.thermostat.set_pid_ki(pid_params.Ki)
# await kirdy.thermostat.set_pid_kd(pid_params.Kd)
# await kirdy.thermostat.set_pid_output_max(1.0)
# await kirdy.thermostat.set_pid_output_min(1.0)
await kirdy.end_session()
if __name__ == "__main__":
asyncio.run(main())