From 06b8f701faa6e434dfa1a744c013d0d5268e9851 Mon Sep 17 00:00:00 2001 From: Markus Kuhn Date: Fri, 22 Nov 2024 14:28:09 +0100 Subject: [PATCH] FIX: SlowPwmDevice.cycle no longer depends in input ... within sensible limits: *Input.interval should be less than SlowPwmDevice.cycle, otherwise the PWM will react unproportionally (non linear). Too short cycle time may wear your relay contacts. I'd recommend semiconductor switches for short cycle times. After all its named SLOWPwmDevice! --- aquaPi/machineroom/out_nodes.py | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/aquaPi/machineroom/out_nodes.py b/aquaPi/machineroom/out_nodes.py index 1a3d491..01cfd79 100644 --- a/aquaPi/machineroom/out_nodes.py +++ b/aquaPi/machineroom/out_nodes.py @@ -252,10 +252,10 @@ def toggle_and_wait(state: bool, end: float) -> bool: >>>>>>> 9037c8a (FIX: SlowPwmDevice 100% showed as 50% in History) def listen(self, msg): if isinstance(msg, MsgData): - log.brief('SlowPwmDevice %s: got %f %%', self.name, msg.data) self.set(float(msg.data)) return super().listen(msg) +<<<<<<< HEAD def _pulse(self, dur: float): log.brief(' PID pulse: %s -> %f s', self.name, round(dur, 1)) if dur > 0.1: @@ -269,12 +269,41 @@ def _pulse(self, dur: float): self.post(MsgData(self.id, 0)) log.brief(' PID pulse: done') >>>>>>> 5f2158d (Fixes and tuning of PidCtrl on real HW) +======= + def _pulse(self, hi_sec: float): + def toggle_and_wait(state: bool, end: float) -> bool: + start = time.time() + self._driver.write(state if not self._inverted else not state) + self.post(MsgData(self.id, 100 if state else 0)) + # avoid error accumulation by exact final sleep() + while time.time() < end - .1: + if self._thread_stop: + self._thread_stop = False + return False + time.sleep(.1) + time.sleep(end - time.time()) + log.debug(' _pulse needed %f instead of %f', + time.time() - start, end - start) + return True + + while True: + lead_edge = time.time() + if hi_sec > 0.1: + if not toggle_and_wait(True, lead_edge + hi_sec): + return + if hi_sec < self.cycle: + if not toggle_and_wait(False, lead_edge + self.cycle): + return +>>>>>>> 0ee1ae1 (FIX: SlowPwmDevice.cycle no longer depends in input) return def set(self, perc: float) -> None: self.data: float = perc <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 0ee1ae1 (FIX: SlowPwmDevice.cycle no longer depends in input) log.info('SlowPwmDevice %s: sets %.1f %% (%.3f of %f s)', self.id, self.data, self.cycle * perc/100, self.cycle) if self._thread: @@ -283,6 +312,7 @@ def set(self, perc: float) -> None: self._thread = Thread(name='PIDpulse', target=self._pulse, args=[self.data / 100 * self.cycle], daemon=True) self._thread.start() +<<<<<<< HEAD ======= log.error('SlowPwmDevice %s: sets %.1f', self.id, self.data) #if self._thread: @@ -293,6 +323,8 @@ def set(self, perc: float) -> None: self._thread = Thread(name='PIDpulse', target=self._pulse, args=[self.data / 100. * self.cycle], daemon=True).start() >>>>>>> 5f2158d (Fixes and tuning of PidCtrl on real HW) +======= +>>>>>>> 0ee1ae1 (FIX: SlowPwmDevice.cycle no longer depends in input) def get_settings(self): settings = super().get_settings()