diff --git a/revpimodio2/__init__.py b/revpimodio2/__init__.py index 5963bbf..6773474 100644 --- a/revpimodio2/__init__.py +++ b/revpimodio2/__init__.py @@ -22,7 +22,7 @@ __author__ = "Sven Sager " __copyright__ = "Copyright (C) 2020 Sven Sager" __license__ = "LGPLv3" __name__ = "revpimodio2" -__version__ = "2.5.8" +__version__ = "2.5.8c" # Global package values OFF = 0 diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py index 1a72e1c..a202382 100644 --- a/revpimodio2/helper.py +++ b/revpimodio2/helper.py @@ -365,7 +365,7 @@ class ProcimgWriter(Thread): """ __slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \ - "_adjwait", "_eventq", "_modio", \ + "_eventq", "_modio", \ "_refresh", "_work", "daemon", "lck_refresh", "newdata" def __init__(self, parentmodio): @@ -375,7 +375,6 @@ class ProcimgWriter(Thread): self.__eventth = Thread(target=self.__exec_th) self._eventqth = queue.Queue() self.__eventwork = False - self._adjwait = 0 self._eventq = queue.Queue() self._modio = parentmodio self._refresh = 0.05 @@ -512,22 +511,22 @@ class ProcimgWriter(Thread): def run(self): """Startet die automatische Prozessabbildsynchronisierung.""" fh = self._modio._create_myfh() - self._adjwait = self._refresh + mrk_delay = self._refresh mrk_warn = True - mrk_dt = default_timer() - bytesbuff = bytearray(self._modio._length) - while not self._work.is_set(): - ot = mrk_dt - # Lockobjekt holen und Fehler werfen, wenn nicht schnell genug - if not self.lck_refresh.acquire(timeout=self._adjwait): + while not self._work.is_set(): + ot = default_timer() + + # At this point, we slept and have the rest of delay from last cycle + if not self.lck_refresh.acquire(timeout=mrk_delay): warnings.warn( - "cycle time of {0} ms exceeded during executing function" + "cycle time of {0} ms exceeded in your cycle function" "".format(int(self._refresh * 1000)), RuntimeWarning ) + mrk_delay = self._refresh # Nur durch cycleloop erreichbar - keine verzögerten Events continue @@ -609,22 +608,18 @@ class ProcimgWriter(Thread): self._eventq.put(tup_fire, False) del self.__dict_delay[tup_fire] - # Sleep and not .wait (.wait uses system clock) - sleep(self._adjwait) - - # Wartezeit anpassen um echte self._refresh zu erreichen - mrk_dt = default_timer() - if mrk_dt - ot >= self._refresh: - self._adjwait -= 0.001 - if self._adjwait < 0: - warnings.warn( - "cycle time of {0} ms exceeded several times - can not" - " hold cycle time!".format(int(self._refresh * 1000)), - RuntimeWarning - ) - self._adjwait = 0 + mrk_delay = default_timer() % self._refresh + # Second default_timer call include calculation time from above + if default_timer() - ot > self._refresh: + warnings.warn( + "cycle time of {0} ms exceeded - can not hold cycle time!" + "".format(int(self._refresh * 1000)), + RuntimeWarning + ) + mrk_delay = 0.0 else: - self._adjwait += 0.001 + # Sleep and not .wait (.wait uses system clock) + sleep(self._refresh - mrk_delay) # Alle am Ende erneut aufwecken self._collect_events(False) @@ -639,9 +634,7 @@ class ProcimgWriter(Thread): """Setzt die Zykluszeit in Millisekunden. @param value Millisekunden""" if type(value) == int and 5 <= value <= 2000: - waitdiff = self._refresh - self._adjwait self._refresh = value / 1000 - self._adjwait = 0 if waitdiff < 0 else self._refresh - waitdiff else: raise ValueError( "refresh time must be 5 to 2000 milliseconds" diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index b81e3be..ea673ca 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -767,10 +767,10 @@ class RevPiModIO(object): # Zykluszeit übernehmen old_cycletime = self._imgwriter.refresh if not cycletime == self._imgwriter.refresh: + # Set new cycle time and wait one imgwriter cycle to sync fist cycle self._imgwriter.refresh = cycletime - - # Zeitänderung in _imgwriter neuladen self._imgwriter.newdata.clear() + self._imgwriter.newdata.wait(self._imgwriter._refresh) # Benutzerevent self.exitsignal.clear() @@ -781,6 +781,7 @@ class RevPiModIO(object): cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh, self) e = None # Exception ec = None # Return value of cycle_function + self._imgwriter.newdata.clear() try: while ec is None and not cycleinfo.last: # Auf neue Daten warten und nur ausführen wenn set() diff --git a/setup.py b/setup.py index 618a5d3..c8c704c 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( license="LGPLv3", name="revpimodio2", - version="2.5.8", + version="2.5.8c", packages=["revpimodio2"], python_requires="~=3.2",