![](/img/trans.png)
[英]Python serial communication with Arduino, blinking the built-in led using an user input at the same time reading from the Arduino signal
[英]Threading using Kivy to read serial and get user input at the same time
我正在制作一个 controller,它通过串行发送命令从真空泵连续更新标签。 这个 controller 还需要用户输入来启动和停止吸尘器。 我已经开始工作了,但是我的问题是时机似乎不对。 在程序开始时按钮是响应的,但是在运行几分钟后,schedule_interval() function 似乎压倒了基于序列号 output 的用户输入响应,并且按钮 output 显着滞后并且全部堆积在最后当我终止程序时。 (请注意,我正在使用 Raspberry Pi 发送串口。我不知道是否还需要考虑任何设备限制。)
Clock.max_iteration = 20
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 9600
ser.bytesize = serial.EIGHTBITS #number of bits per bytes
ser.parity = serial.PARITY_NONE #set parity check: no parity
ser.stopbits = serial.STOPBITS_ONE #number of stop bits
ser.timeout = 1 #non-block read
ser.xonxoff = False #disable software flow control
ser.rtscts = False #disable hardware (RTS/CTS) flow control
ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
ser.writeTimeout = 2 #timeout for write
Builder.load_file('MyApp.kv')
class MyLayout(Widget):
def Button1(self):
#read serial
#write serial
#update labels
def Button2(self):
#read serial
#write serial
#update labels
def Button3(self):
#read serial
#write serial
#update labels
def exitButton(self):
print("Program terminated")
exit()
class MyApp(App):
def build(self):
return MyLayout()
def on_start(self):
threading.Thread(target=self.updateLabels).start() #thread
#Clock.schedule_once(self.updateLabels, 1)
def updateLabels(self, *args): #this function updates labels
#write serial for label 1
#read serial for label 1
#update label 1
#write serial for label 2
#read serial for label 2
#update label 2
#write serial for label 3
#read serial for label 3
#update label 3
Clock.schedule_interval(self.updateLabels, 2) #update labels every 2 seconds
if __name__ == '__main__':
try:
ser.open()
except Exception as e:
print("error opening serial port: ")
exit()
if ser.isOpen():
try:
ser.flushInput()
ser.flushOutput()
except Exception as e:
print("Error communication") + str(e)
else:
print("Error communicating")
MyApp().run()
Output 示例:
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Write Command: Button1
Write Command: Button2 #proceeds to lag after
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Write Command: Button2 #this button would have been pressed 30 sec ago
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Update Data: label1
Update Data: label2
Update Data: label3
Write Command: Button1 #piles up at the end after 3-5 mins unresponsive
Write Command: Button1
Write Command: Button2
Write Command: Button1
Write Command: Button1
Write Command: Button2
Program terminated #takes at least 15 sec for this to actually terminate program
我尝试使用线程以允许两个函数同时运行。 但是,它们似乎干扰了其他人。 我的目标是让按钮在程序运行时随时响应,但标签每 2 秒或更短时间(如果可能)连续更新一次。
您的update_labels()
方法应该在主线程上运行,而不是在另一个线程中运行,因为它正在修改 GUI。 一种解决方案是像这样修改on_start()
方法:
def on_start(self):
# threading.Thread(target=self.updateLabels).start() #thread
Clock.schedule_interval(self.updateLabels, 2)
这将每 2 秒在主线程上运行update_labels()
。 由于它处理调度,您可以消除任何使用Clock.schedule...
在实际的update_labels()
方法中。
如果您的update_labels()
方法的内部花费太多时间,这种方法将干扰您的应用程序的响应能力。 如果是这种情况,那么您将需要在运行耗时代码但Labels
未更新的另一个线程中运行不同的方法。 然后,该代码可以使用Clock.schedule_once()
来安排一个只更改Label
文本的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.