Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 陷入了一段真实的循环。。。有没有关于如何出去的想法?_Python_Multithreading_While Loop_Serial Port - Fatal编程技术网

Python 陷入了一段真实的循环。。。有没有关于如何出去的想法?

Python 陷入了一段真实的循环。。。有没有关于如何出去的想法?,python,multithreading,while-loop,serial-port,Python,Multithreading,While Loop,Serial Port,编辑#1:这是工作代码,但有时我会遇到UnicodeDecodeError,这会阻止循环继续。发生这种情况时,是否会导致循环中断或通过?我试着将代码改为Try而不是If语句,但它不起作用 我的问题是:声明 def SerialRead(dataReadEvent): delay1 = DT.datetime.now() dataReadEvent.set() #Serial Reading ser = serial.Se

编辑#1:这是工作代码,但有时我会遇到UnicodeDecodeError,这会阻止循环继续。发生这种情况时,是否会导致循环中断或通过?我试着将代码改为Try而不是If语句,但它不起作用

我的问题是:声明

def SerialRead(dataReadEvent):
    delay1 = DT.datetime.now()                
    dataReadEvent.set()


    #Serial Reading    
    ser = serial.Serial(port='COM4', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=None)   

    global last_received
    buffer = ''
    amountAppended = 0
    while True:
        buffer += ser.read(ser.inWaiting()).decode('ascii')
        if '\n' in buffer:
            last_received, buffer = buffer.split('\n')[-2:] 
            amountAppended += 1
        if amountAppended == 2:
            amountAppended =0
            break      
    else:
        ser.close()

    global plaintext1
    plaintext1 = last_received.replace(' ', ', ')    
    plaintext = plaintext1.replace('=', ', ')
    global listvalue
    listvalue = plaintext.split(", ")

    #Writing to csv
    outputfile = open(location, mode='a', newline='')
    outputWriter = csv.writer(outputfile)
    outputWriter.writerow([plaintext])
    outputfile.close()     

    delay2 = DT.datetime.now()
    differencetime = (delay2 - delay1).total_seconds()
    restart = (writedelay - differencetime)
    threading.Timer(restart, SerialRead, args=(dataReadEvent,)).start()    
我试图得到它,使我的串行连接读取最后一行输入每5秒。然而,我已经在线程命令中植入了一个While-True循环,我无法退出While-True循环。。。一旦订婚,它就永远是

While-True循环允许我从我的设备获取一行完整的串行数据。我需要一个完整的正确的线路,这是这样做的方式,但每次都会遇到障碍。我怎样才能摆脱这种循环

from PyQt4 import QtGui, QtCore
import sys
import masimo
import csv
import time
import datetime as DT
import threading
from threading import Thread
import serial
import os

os.chdir(r"C:\Users\SpO2\Desktop\Data")
time1 = time.strftime("%d %b %Y %H%M%S")
location = r'%s.csv' % time1
outputfile = open(location, mode='x', newline='')
outputWriter = csv.writer(outputfile)
outputWriter.writerow(["start"])
outputfile.close()
writedelay = int(5)
last_received = ''

class ExampleApp(QtGui.QMainWindow, masimo.Ui_MainWindow):            
    def __init__(self, event, parent=None):
        super(self.__class__, self).__init__()
        self.setupUi(self)

        self.dataWasReadEvent = event
        self.checkThreadTimer = QtCore.QTimer(self)
        self.checkThreadTimer.setInterval(500) #.5 seconds
        self.checkThreadTimer.timeout.connect(self.readListValues) 
        self.checkThreadTimer.start()

    def readListValues(self):
        if self.dataWasReadEvent.is_set():
                #Read your events from the list and update your fields
            self.SPO2text.setText(str(listvalue[5]))
            self.HRtext.setText(str(listvalue[7]))
            self.PItext.setText(str(listvalue[9]))
            self.timestamptext.setText(str(listvalue[1]))
            self.rawdata.setText(str(plaintext1))
            self.dataWasReadEvent.clear() #Clear the event set flag so that nothing happens the next time the timer times out

def SerialRead(dataReadEvent):
    delay1 = DT.datetime.now()                
    dataReadEvent.set()


    #Serial Reading    
    ser = serial.Serial(port='COM4', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=2)   

    global last_received
    buffer = ''
    while True:
        buffer += ser.read(ser.inWaiting()).decode('ascii')
        if '\n' in buffer:
            last_received, buffer = buffer.split('\n')[-2:] 
    else:
        ser.close()



    global plaintext1
    plaintext1 = last_received.replace(' ', ', ')    
    plaintext = plaintext1.replace('=', ', ')
    global listvalue
    listvalue = plaintext.split(", ")

    #Writing to csv
    outputfile = open(location, mode='a', newline='')
    outputWriter = csv.writer(outputfile)
    outputWriter.writerow([plaintext])
    outputfile.close()     

    delay2 = DT.datetime.now()
    differencetime = (delay2 - delay1).total_seconds()
    restart = (writedelay - differencetime)
    threading.Timer(restart, SerialRead, args=(dataReadEvent,)).start()    

def main(dataReadEvent):
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp(dataReadEvent)
    form.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    dataReadEvent = threading.Event()
    Thread(target = SerialRead, args=(dataReadEvent,) ).start()
    Thread(target = main, args=(dataReadEvent,) ).start()

使用
break
关键字退出任何循环。它将退出
中断
所处的任何循环。

您的循环以

 while True:
这将永远持续下去。看看这两个例子,注意它们的区别

a=0 
while a<10:
   print a
   a = a+1
这将永远运行,因为a始终大于0

针对你的评论: 使用最后收到的两行代码作为测试

while last_received_count <2:
  .... 
  ....
    if '\n' in buffer:
       last_received, buffer = buffer.split('\n')[-2:]
       last_received_count = last_received_count+1
当上次收到\u计数时

while True:
函数永远不会结束,也永远不会退出,您可以使用“break”退出循环。如果这不是您想要的,您必须告诉它while语句何时应处于活动状态,即:

While amountOfTimesToLoop < 0: do whatever
或者如果你没有清理清单,你可以这样做

while True:
    buffer += ser.read(ser.inWaiting()).decode('ascii')
    if '\n' in buffer:
        last_received, buffer = buffer.split('\n')[-2:] 
    if last_received.length == 2:
        break
else:
    ser.close()
amountAppended = 0
while True:
    buffer += ser.read(ser.inWaiting()).decode('ascii')
    if '\n' in buffer:
        last_received, buffer = buffer.split('\n')[-2:] 
        amountAppended += 1
    if amountAppended == 2:
        amountAppended = 0
        break
else:
    ser.close()
由于您希望“运行循环,直到我有两行数据附加到
'last_received'
”,您可以使用
计数器
,它在
if
语句中递增,然后在
计数器
值等于2时
中断
。大概是这样的:

counter = 1
while True:
   buffer += ser.read(ser.inWaiting()).decode('ascii')
       if '\n' in buffer:
           last_received, buffer = buffer.split('\n')[-2:] 
           if counter == 2:
               break
           counter += 1

@尼古拉斯·拉瓦内利如果没有更多关于这个问题的信息,很难说。如果您想运行循环,直到发生使该事件成为测试的事件,如果您想在缓冲区中出现某个事件后退出循环,那么可以使用该循环来定义test@Ajay我希望运行循环,直到有两行数据附加到“last_received”之后。这样我就知道如果我调用最后一个附加行,它就是一整行代码。在此之后,我希望循环退出,然后它会将最后一行完整的串行输入写入CSV,然后它会更新我GUI中的几个文本框…@NicholasRavanelli更新了我对你问题的评论OK。考虑到这一点,自最后一次接收到_以来,这是否只会循环一次,始终会附加2行?那么在接下来的5秒钟内,串行数据的读取将跳过?今晚晚些时候我会测试这些建议…@NicholasRavanelli抱歉,我没有阅读代码的其余部分,我想你会从那里删除它。我会用另一种方法更新答案,混合全局变量、线程,而带有GUI和类的循环似乎是disaster@NicholasRavanelli你说“它不起作用”是什么意思有没有办法将循环后的计数器重置为1?这样,每次间隔5秒,该循环将始终重置。当然!只需在断开循环之前重置计数器。您可以看到这里提到的第二个解决方案@Paradizigmania。
counter = 1
while True:
   buffer += ser.read(ser.inWaiting()).decode('ascii')
       if '\n' in buffer:
           last_received, buffer = buffer.split('\n')[-2:] 
           if counter == 2:
               break
           counter += 1