Reputation: 407
Edit #1: Here is the working code, however I sometimes get a UnicodeDecodeError which halts the loop from continuing. Is there anyway to cause a break or pass in the loop when this occurs? I have tried changing the code to Try instead of If statements and its not working...
My issue is in the while True: statement...
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()
I have trying to get it so that my serial connection reads the last line of input every 5 seconds. However, I have seeded a While True loop inside a threading command and I cannot get out of the While True loop... its always once it is engaged.
The While True Loop allows me to get one complete line of serial data from my unit. I need a full proper line and this was the way to do it, but it snags every time. How can I get out of the 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()
Upvotes: 0
Views: 1496
Reputation: 81
The
while True:
function will never end and will never exit, you can use "break" to exit a loop. if this isn't what you want you will have to tell it when the while statement should be active ie:
While amountOfTimesToLoop < 0: do whatever
If you want to check for when things have been appended to your list you can do something like
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()
or if you aren't clearing the list you could something like
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()
Upvotes: 2
Reputation: 75
As you want to "run the loop until i have two lines of data appended to 'last_received'
", you can use a counter
which increments inside the if
statement and then break
when the counter
value is equals to 2. Something like this:
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
Upvotes: 0
Reputation: 407
Your loop begins with
while True:
This will always continue forever look at these two examples and note the differences
a=0
while a<10:
print a
a = a+1
This will print 0 1 2 3 4 ... 9 and then a is incremented to 10. the expression evaluates to false and the loop exits.
Now:
a=1
while a>0:
print a
a = a+1
This will run forever since a always greater than 0
Use the having two lines in last_recieved as the test then.
while last_received_count <2:
....
....
if '\n' in buffer:
last_received, buffer = buffer.split('\n')[-2:]
last_received_count = last_received_count+1
Upvotes: 0
Reputation: 2121
Use the break
keyword to exit any loop. It will exit whatever loop the break
is in.
Upvotes: 0