陷入了真实的循环......关于如何走出去的任何想法?

时间:2015-10-06 20:21:14

标签: python multithreading while-loop serial-port

编辑#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 Loop允许我从我的单元获得一整行串行数据。我需要一个完整的正确的线路,这是做到这一点的方式,但它每次都有障碍。我怎么能走出循环?

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()

4 个答案:

答案 0 :(得分:2)

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()

答案 1 :(得分:0)

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

答案 2 :(得分:0)

你的循环以

开头
 while True:

这将永远继续看这两个例子并注意差异

a=0 
while a<10:
   print a
   a = a+1

这将打印0 1 2 3 4 ... 9然后a增加到10.表达式求值为false并且循环退出。

现在:

a=1
while a>0:
   print a 
   a = a+1 

这将永远运行,因为总是大于0

回复您的评论:

使用last_recieved中的两行作为测试。

while last_received_count <2:
  .... 
  ....
    if '\n' in buffer:
       last_received, buffer = buffer.split('\n')[-2:]
       last_received_count = last_received_count+1

答案 3 :(得分:0)

如您所愿&#34;运行循环直到我将两行数据附加到'last_received'&#34;,您可以使用counter在{{1}内增加当if值等于2时,语句然后是break。这样的事情:

counter