Python multipul事件计时器

时间:2015-07-05 19:16:50

标签: python

我有一个带压力传感器的水泵。一个输入(低),一个输出(高)。我的问题是我的低压传感器。有时低压恰好处于截止点,导致电机快速启动和停止 - 这是不可取的。该系统在自制的PLS上运行。

我是编程的初学者,3个月,但系统大部分都在工作。我需要帮助在低压警报事件之间创建一个计时器。我认为系统可以在30秒内有3个事件,但如果任何一个事件在不到5秒内发生,系统应该关闭。

因此,如果第一次事件和第二次事件之间的时间少于5秒,则电机会关闭。第二至第三和第三至第四事件也是如此。在第四个事件中,如果在第一个事件和第四个事件之间发生少于30秒,系统也会关闭。请记住,这是一个更大的循环的一部分。这是我能够创建的代码:

def Systemofftimer():
    EventCounter = (0)
    OneTimeLoopVarable = (0)
    While True
        if (is_low_pressure_alarm_on() and (OneTimeLoopVarable ==0)):
            Timer = time.time()
            EventCounter = EventCounter + (1)
            OneTimeLoopVarable = 1


            if EventCounter == (2) and (time.time() - Timer >= (10))
                EventCounter = EventCounter + (1)
                stop_motor()


            if EventCounter == (3) and (time.time() - Timer >= (20))
                EventCounter = EventCounter + (1)
                stop_motor()

            if EventCounter == (4) and (time.time() - Timer >= (30))
                EventCounter = EventCounter + (1)
                stop_motor()
        else:
            start_motor()

1 个答案:

答案 0 :(得分:0)

我实际上会使用不同的方法:只需设置一个大于转动阈值的阈值。例如: graph

这样你就不需要处理它的时间安排,仍然可以消除状态转换时的紧张情绪。您也可以对此进行调整,以说明传感器的噪音程度。

修改

下面我嘲笑了你要问的系统。它可能比您最初寻找的方式更多,但我想测试以确保它在我发布之前一切正常,所以欢迎您全部或部分使用它。至于您询问的计时器,它基于Hans this thread的帖子。要触发闹钟,只需在TriggerAlarm()课程上拨打PumpSystem即可。它将记录触发警报,然后检查您在问题中提到的两个条件(5秒和30秒错误)。 self.alarms的每个元素包含特定秒钟内发生的警报数,每秒钟计时器触发从列表中删除最早的第二个并创建一个新的。如果运行该程序,则可以通过按空格键来触发警报,并查看列表的更新方式。 MockUp类仅用于测试和演示其工作原理。如果您决定将其中的一部分插入到您正在处理的内容中,我想您会将其删除。无论如何,这是代码。

from threading import Timer, Thread, Event

class PumpSystem():
    def __init__(self):
        self.alarms = [0 for x in range(30)]
        self.Start()
        return None

    def SetUpdateFlag(self, flag):
        self.update_flag = flag
        return True

    def Start(self):
        self.stop_flag = Event()
        self.thread = ClockTimer(self.OnTimerExpired, self.stop_flag)
        self.thread.start()
        return True

    def Stop(self):
        self.stop_flag.set()
        return True

    def TriggerAlarmEvent(self):
        self.alarms[-1] += 1
        self.CheckConditions()
        self.update_flag.set()
        return True

    def OnTimerExpired(self):
        self.UpdateRunningAverage()

    def CheckConditions(self):
        # Check if another error has triggered in the past 5 seconds
        if sum(self.alarms[-5:]) > 1:
            print('5 second error')

        # Check if more than 3 errors have triggered in the past 30 seconds
        if sum(self.alarms) > 3:
            print('30 second error')

        return True

    def UpdateRunningAverage(self):
        self.alarms.append(0)
        self.alarms.pop(0)
        self.update_flag.set()
        return True

class ClockTimer(Thread):
    def __init__(self, callback, event):
        Thread.__init__(self)
        self.callback = callback
        self.stopped = event
        return None

    def SetInterval(self, time_in_seconds):
        self.delay_period = time_in_seconds
        return True

    def run(self):
        while not self.stopped.wait(1.0):
            self.callback()
        return True


## START MOCKUP CODE ##

import tkinter as tk
class MockUp():
    def __init__(self):
        self.pump_system = PumpSystem()
        self.update_flag = Event()
        self.pump_system.SetUpdateFlag(self.update_flag)
        self.StartSensor()
        return None

    def StartSensor(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.Exit)
        self.alarms = tk.StringVar()
        w = tk.Label(self.root, textvariable=self.alarms, width=100, height=15)
        self.alarms.set(self.pump_system.alarms)
        w.pack()
        self.root.after('idle', self.ManageUpdate)
        self.root.bind_all('<Key>', self.ManageKeypress)
        self.root.mainloop()
        return True

    def ManageUpdate(self):
        if self.update_flag.isSet():
            self.alarms.set(self.pump_system.alarms)
            self.update_flag.clear()
        self.root.after(1, self.ManageUpdate)
        return True

    def ManageKeypress(self, event):
        if event.keysym == 'Escape':
            self.Exit()
        if event.keysym == 'space':
            self.pump_system.TriggerAlarmEvent()
        return True

    def Exit(self):
        self.pump_system.Stop()
        self.root.destroy()


mockup = MockUp()

这可能看起来很多,但有一半是你可能会忽略的模型类。如果您有任何疑惑,请告诉我,我很乐意解释发生了什么。