我有一个带压力传感器的水泵。一个输入(低),一个输出(高)。我的问题是我的低压传感器。有时低压恰好处于截止点,导致电机快速启动和停止 - 这是不可取的。该系统在自制的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()
答案 0 :(得分:0)
我实际上会使用不同的方法:只需设置一个大于转动阈值的阈值。例如:
这样你就不需要处理它的时间安排,仍然可以消除状态转换时的紧张情绪。您也可以对此进行调整,以说明传感器的噪音程度。
修改强>
下面我嘲笑了你要问的系统。它可能比您最初寻找的方式更多,但我想测试以确保它在我发布之前一切正常,所以欢迎您全部或部分使用它。至于您询问的计时器,它基于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()
这可能看起来很多,但有一半是你可能会忽略的模型类。如果您有任何疑惑,请告诉我,我很乐意解释发生了什么。