1
0
forked from M-Labs/kirdy

Update pid autotuner code

This commit is contained in:
linuswck 2024-09-03 12:13:15 +08:00
parent 2fe2ef531b
commit 6782cda790
2 changed files with 48 additions and 42 deletions

View File

@ -73,7 +73,7 @@
src = "${self}/pykirdy";
nativeBuildInputs = [ pkgs.qt6.wrapQtAppsHook ];
propagatedBuildInputs = [ pkgs.qt6.qtbase ] ++ (with pkgs.python3Packages; [ pyqtgraph pyqt6 qasync pglive aenum]);
propagatedBuildInputs = [ pkgs.qt6.qtbase ] ++ (with pkgs.python3Packages; [ pyqtgraph pyqt6 qasync pglive aenum sipyco]);
dontWrapQtApps = true;
postFixup = ''
@ -94,7 +94,7 @@
buildInputs = with pkgs; [
rust openocd dfu-util glibc
] ++ (with python3Packages; [
numpy matplotlib pyqtgraph setuptools pyqt6 qasync pglive aenum
numpy matplotlib pyqtgraph setuptools pyqt6 qasync pglive aenum sipyco
]);
shellHook=
''

View File

@ -8,6 +8,7 @@ import time
import signal
from driver.kirdy import Kirdy, FilterConfig
import asyncio
from sipyco.asyncio_tools import SignalHandler
# Based on hirshmann pid-autotune libiary
# See https://github.com/hirschmann/pid-autotune
@ -76,6 +77,10 @@ class PIDAutotune:
def setOff(self):
self._state = PIDAutotuneState.STATE_OFF
def setFailed(self):
self._state = PIDAutotuneState.STATE_FAILED
self._peak_count = 30
def state(self):
"""Get the current state."""
return self._state
@ -246,7 +251,7 @@ class PIDAutotune:
return False
def main():
async def main():
"""
PID AutoTune Tools for Kirdy
The obtained temperature works best at the target temperature specified.
@ -271,46 +276,46 @@ def main():
noiseband = 2.0
kirdy = Kirdy()
kirdy.start_session(host='192.168.1.128', port=1337)
kirdy.start_session(host='192.168.1.126', port=1337)
await kirdy.wait_until_connected()
while not(kirdy.connected()):
pass
kirdy.laser.set_power_on(False)
kirdy.laser.set_i(0)
await kirdy.laser.set_power_on(False)
await kirdy.laser.set_i(0)
kirdy.thermostat.set_power_on(False)
kirdy.thermostat.set_constant_current_control_mode()
kirdy.thermostat.set_tec_i_out(0)
kirdy.thermostat.clear_alarm()
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()
kirdy.device.set_active_report_mode(False)
signal_handler.setup()
async def sig_handling():
await signal_handler.wait_terminate()
tuner.setFailed()
asyncio.create_task(sig_handling())
await kirdy.device.set_active_report_mode(False)
# Configure the Thermistor Parameters
kirdy.thermostat.set_sh_beta(3950)
kirdy.thermostat.set_sh_r0(10.0 * 1000)
kirdy.thermostat.set_sh_t0(25)
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
kirdy.thermostat.set_temp_mon_upper_limit(target_temperature + 20)
kirdy.thermostat.set_temp_mon_lower_limit(target_temperature - 20)
await kirdy.thermostat.set_temp_mon_upper_limit(target_temperature + 20)
await kirdy.thermostat.set_temp_mon_lower_limit(target_temperature - 20)
kirdy.thermostat.set_tec_max_cooling_i(output_step)
kirdy.thermostat.set_tec_max_heating_i(output_step)
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
kirdy.thermostat.config_temp_adc_filter(FilterConfig.Sinc5Sinc1With50hz60HzRejection.f16sps)
settings = kirdy.device.get_settings_summary()
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))
@ -318,10 +323,10 @@ def main():
tuner = PIDAutotune(target_temperature, output_step,
lookback, noiseband, 1/sampling_rate)
kirdy.thermostat.set_power_on(True)
await kirdy.thermostat.set_power_on(True)
while True and signal_handler.KEEP_PROCESSING:
status_report = kirdy.device.get_status_report()
while True:
status_report = await kirdy.device.get_status_report()
temperature = status_report["thermostat"]["temperature"]
ts = status_report['ts']
@ -332,19 +337,20 @@ def main():
break
tuner_out = tuner.output()
kirdy.thermostat.set_tec_i_out(float(tuner_out))
await kirdy.thermostat.set_tec_i_out(float(tuner_out))
kirdy.thermostat.set_tec_i_out(0)
kirdy.thermostat.set_power_on(False)
await kirdy.thermostat.set_tec_i_out(0)
await kirdy.thermostat.set_power_on(False)
pid_params = tuner.get_pid_parameters(tuning_rule="tyreus-luyben")
kirdy.thermostat.set_pid_kp(pid_params.Kp)
kirdy.thermostat.set_pid_ki(pid_params.Ki)
kirdy.thermostat.set_pid_kd(pid_params.Kd)
kirdy.thermostat.set_pid_output_max(1.0)
kirdy.thermostat.set_pid_output_min(1.0)
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)
kirdy.end_session(block=True)
await kirdy.end_session()
if __name__ == "__main__":
main()
asyncio.run(main())