Skip to content

Commit

Permalink
FIX: SlowPwmDevice.cycle no longer depends in input
Browse files Browse the repository at this point in the history
... 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!
  • Loading branch information
schwabix-1311 committed Nov 22, 2024
1 parent 9037c8a commit 0ee1ae1
Showing 1 changed file with 33 additions and 22 deletions.
55 changes: 33 additions & 22 deletions aquaPi/machineroom/out_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def __init__(self, name, inputs, port, inverted=0, cycle=60., _cont=False):
self._port = None
self._inverted = int(inverted)
self._thread = None
#self._thread_stop = False
self._thread_stop = False
self.port = port
self.set(self.data)
log.info('%s init to %f|%r|%r s', self.name, self.data, inverted, cycle)
Expand Down Expand Up @@ -176,35 +176,46 @@ def inverted(self, inverted):

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)

def _pulse(self, dur: float):
log.brief(' PID pulse: %s -> %f s', self.name, round(dur, 1))
if dur > 0.1:
log.brief(' PID on')
self._driver.write(True if not self._inverted else False)
self.post(MsgData(self.id, 100))
time.sleep(dur)
if dur < self.cycle:
log.brief(' PID off')
self._driver.write(False if not self._inverted else True)
self.post(MsgData(self.id, 0))
log.brief(' PID pulse: done')
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
return

def set(self, perc: float) -> None:
self.data: float = perc

log.error('SlowPwmDevice %s: sets %.1f', self.id, self.data)
#if self._thread:
# self._thread_stop = True
# log.brief(' PID pulse: stopping ...')
# self._thread.join()
# log.brief(' PID pulse: ... stopeed')
self._thread = Thread(name='PIDpulse', target=self._pulse, args=[self.data / 100. * self.cycle], daemon=True).start()

log.info('SlowPwmDevice %s: sets %.1f %% (%.3f of %f s)',
self.id, self.data, self.cycle * perc/100, self.cycle)
if self._thread:
self._thread_stop = True
self._thread.join()
self._thread = Thread(name='PIDpulse', target=self._pulse,
args=[self.data / 100 * self.cycle], daemon=True)
self._thread.start()

def get_settings(self):
settings = super().get_settings()
Expand Down

0 comments on commit 0ee1ae1

Please sign in to comment.