【发布时间】:2019-10-24 12:47:03
【问题描述】:
我想运行一个测量程序,该程序在同一时期从两个不同的设备获取测量值。我想在一个小 gui 内开始和停止测量。由于我需要一个 while 循环来测量、绘制和保存其中一个测量值并运行它,直到我用停止按钮中断它,我想我需要将它作为不同的线程调用以不冻结 gui 并能够使用停止按钮。另外我认为我不应该使用 .join() 来不冻结 gui。但不知何故,我的 gui 似乎仍然冻结,我无法使用停止按钮。我已经在论坛中阅读过类似的问题,但我无法弄清楚我做错了什么。 这实际上是我第一个使用线程的项目,所以我对选项和事件没有任何经验,但我也看不出它们会如何帮助我。
所以我有一个类来与我的 arduino 通信,一个与 saleae(第二个设备)通信,还有一个 data_treatment 类来绘制和保存来自 arduino 的数据。
所以我主要有一个带有开始和停止按钮的小 gui。当我按下开始按钮时,我想启动 saleae 测量(它可以在自己的程序中舒适地运行)并调用我的 ardunio 类的记录功能。该函数有一个 while 循环,它读取值并将它们提供给 data_treatment 函数。当我按开始时,它会启动 saleae 测量和 arduino 测量,一切都按计划进行,但我不能按停止,因为 gui 似乎在等待另一个威胁,直到我按停止才结束。
所以这里是我的主函数(cambine_func)只是一个可以通过按钮调用几个函数的函数),下面是arduino类:
if __name__ == '__main__':
window = gui.Window("Measurement")
start_button = window.add_button("Start")
start_button.pack(pady = 20)
gui.on("btnPress", start_button, lambda: combine_funcs(saleae.start_measurement(),
threading.Thread(target = arduino.record_values(300)).start()))
stop_button = window.add_button("Stopp")
stop_button.pack(pady = 20)
gui.on("btnPress", stop_button, lambda: combine_funcs(saleae.end_measurement(),
saleae.save_data(),
arduino.close_port(),
window.destroy()))
window.start()
import time
class Arduino_communication:
"""
reads what comes in from Arduino and transformes it into single values
"""
def __init__(self, arduino, data_treatment):
self.arduino = arduino
self.data_treatment = data_treatment
self.interrupted = False
def record_values(self, measurement_period):
"""
reads values from the Arduino and converts it into single values,
counts faulty lines received from Arduino
:return: array of 6 columns (roll, pitch, yaw, x-position, y-position, z-position)
"""
faulty_values = 0
data = [0, 0, 0, 0, 0, 0]
start_time = float(time.time())
time_vector = []
while self.interrupted == False:
self.arduino.flushInput() # delete what's in buffer
self.arduino.readline() # read a byte string and throw away (deleting buffer may lead to uncomplete line)
b = self.arduino.readline() # read next line
time_vector.append(float(time.time())-start_time)
try:
string_n = b.decode() # decode byte string into Unicode
except UnicodeDecodeError: # Arduino sometimes sends faulty lines
faulty_values += 1
string = string_n.rstrip() # remove \n and \r
single_strings = string.split('/')
try:
data = [float(j) for j in single_strings] # convert string to float
except (ValueError, UnicodeDecodeError): # Arduino sometimes sends faulty lines
faulty_values += 1
self.data_treatment.plot_new_data_line(time_vector[-1], data)
self.data_treatment.write_to_csv(time_vector[-1], data)
print('Es gab ', faulty_values, ' fehlerhafte Übertragungen.')
self.data_treatment.finish_plotting()
def close_port(self):
"""
stops measurement and closes arduino port
"""
self.interrupted = True
self.arduino.close()
【问题讨论】:
标签: python multithreading user-interface