我知道以前可能会问过类似的问题。但我找不到适合我情况的解决方案。提前为这个愚蠢的问题道歉。
我正在从USB集线器(连接到两个传感器)读取两个电压值。问题是,我的代码的方式,将有一个约。它们之间有0.8秒的延迟,所以我永远不能同时拥有它们的两个值(如果我减少两个time.sleep()
中的任何一个,则不会报告第二个def的值)。我想如果两者都可以同时运行,也许我可以拥有属于完全相同时间点的值,而不会随时间移动。如果您有任何可以改进此代码的评论,我会很感激
我提前感谢您的意见。
import sys
import time
import datetime
from Phidget22.Devices.VoltageRatioInput import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
from Phidget22.Net import *
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
try:
ch = VoltageRatioInput()
except RuntimeError as e:
print("Runtime Exception %s" % e.details)
print("Press Enter to Exit...\n")
readin = sys.stdin.read(1)
exit(1)
a=[]
b=[]
try:
start = time.time()
while True:
def VoltageRatioChangeHandler(e, voltageRatio):
n=voltageRatio
a.append(n)
ch.setOnVoltageRatioChangeHandler(VoltageRatioChangeHandler)
ch.setHubPort(1)
ch.setIsHubPortDevice(1)
ch.openWaitForAttachment(5000)
if(ch.getChannelSubclass() == ChannelSubclass.PHIDCHSUBCLASS_VOLTAGERATIOINPUT_BRIDGE):
ch.setBridgeEnabled(1)
time.sleep(0.3)
ch.close()
end1 = time.time()
Elt1 = end1-start
print (Elt1)
print a
###
def VoltageRatioChangeHandler(e, voltageRatio2):
m=voltageRatio2
if m is None:
b.append(0)
else:
b.append(m)
ch.setOnVoltageRatioChangeHandler(VoltageRatioChangeHandler)
ch.setHubPort(0)
ch.setIsHubPortDevice(0)
ch.openWaitForAttachment(5000)
if(ch.getChannelSubclass() == ChannelSubclass.PHIDCHSUBCLASS_VOLTAGERATIOINPUT_BRIDGE):
ch.setBridgeEnabled(1)
time.sleep(0.4)
ch.close()
end = time.time()
Elt = end - start
print (Elt)
print b
except KeyboardInterrupt:
print ("gracefully aborted")
sys.exit()
答案 0 :(得分:0)
长话短说:“平行”的成本对您的用例来说是毁灭性的。
同样重新发明一个轮子是非常昂贵的,所以让我给你一个概念,这个概念几乎免费并且像魅力一样。
您的测量结果与多智能体控制系统非常接近,所以让我们重新使用完全出于同样原因开发的框架 - MVC(是的,一个焦虑和好主意,就像一个起源于XEROX Palo Alto研究中心着名的智慧思想家。
import Tkinter as tk # YESSSS! re-using a GUI-tool ( i.e. multi-agent by-design )
关键价值在于“概念控制器”部分“设计自由”,使用内置的所有非常精心打磨的工具,而不是打扰低级细节。
让传感器按照您的需要随时阅读(只需通过常识,理性气味或实验控制环稳定性理论的严格奈奎斯特边界来驱动)。 p>
首先,我们可能需要一种方法,如何被动地读取一对值(同时一致地读取(好吧,更好地使用一个共同的时间窗口,对吗?)。
SENSOR_A_Last_Voltage_Value = tk.DoubleVar()
SENSOR_B_Last_Voltage_Value = tk.DoubleVar()
SCHEDULED_EVENT_READ_A = tk.StringVar()
SCHEDULED_EVENT_READ_B = tk.StringVar()
SIGNAL_2_READ_Voltage_Value = tk.IntVar()
如果您愿意,这些是MVC模型部分智能“寄存器”。
def aSensorREAD_A():
#--------------------------------------------------
# handle all the tricks to read a given sensor ONCE
#--------------------------------------------------
...
ch.setHubPort( 0 )
ch.setIsHubPortDevice( 0 )
ch.openWaitForAttachment( 5000 )
...
a_just_read_value = ...
#--------------------------------------------------
# Let the MVC-framework store this value into MODEL
#--------------------------------------------------
SENSOR_A_Last_Voltage_Value.set( a_just_read_value )
#--------------------------------------------------
# schedule a ( self-operated ) read "next" ONCE
#--------------------------------------------------
SCHEDULED_EVENT_READ_A.set( root.after( 100, aSensorREAD_A ) )
# repeat after 100 [ms]
#
# a cool way to command actually your Boss, isn't it?
# + may,
# if at need, root.after_cancel( SCHEDULED_EVENT_READ_A )
因此,我们可能会认为SensorREAD_*()
的角色是这样一个独立的代理人,负责用实际的传感器读数做低级别的工作。
对于被动的价值消费者,只会有一对“智能”变量,它们被授予始终携带更新的(最后读取)值。
print( "[A] {0: >16.3f}[mV]".format( SENSOR_A_Last_Voltage_Value.get() )
print( "[B] {0: >16.3f}[mV]".format( SENSOR_B_Last_Voltage_Value.get() )
对于触发预期的价值消费者,可能还有一个额外的工具,可以通知任何这样的触发期待读者。
idTrA1 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN1ToCallOnA )
idTrA2 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN2ToCallOnA )
idTrA3 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN3ToCallOnA )
idTrB1 = SENSOR_B_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN1ToCallOnB )
...
idTrB7 = SENSOR_B_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN7ToCallOnB )
# as one may wish and need
最后但并非最不重要的是,可能还有另一种连贯阅读策略:
SIGNAL_2_READ_Voltage_Value = tk.IntVar() # MVC-Model "register"
idTrSIG2R_A = SIGNAL_2_READ_Voltage_Value( "w", aSensorREAD_A ) # MVC-Controller actor
idTrSIG2R_B = SIGNAL_2_READ_Voltage_Value( "w", aSensorREAD_B )
这使得一个外部的触发读取工具,实际上有助于“触发”“同时”读取,只需触摸:
SIGNAL_2_READ_Voltage_Value.set( 1 + SIGNAL_2_READ_Voltage_Value.get() )
优雅终止的最后一步也是明确而诚实的:
finally:
#---------------------------------------------------
SIGNAL_2_READ_Voltage_Value.trace_vdelete( "w", idTrSIG2R_A )
SIGNAL_2_READ_Voltage_Value.trace_vdelete( "w", idTrSIG2R_B )
#---------------------------------------------------
SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA1 )
SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA2 )
SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA3 )
#---------------------------------------------------
SENSOR_B_Last_Voltage_Value.trace_vdelete( "w", idTrB1 )
...
SENSOR_B_Last_Voltage_Value.trace_vdelete( "w", idTrB7 )
For more details and mock-up case inspiration may like to read this