USB/Serial read erzeugt 100% CPU Last nach einigen Stunden..

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jaykay
User
Beiträge: 1
Registriert: Donnerstag 10. Mai 2012, 19:53

Hallo,

ich versuche die Daten meiner Heizung mit einem selbst geschrieben Pythonscript abzufragen, was auch gut läuft.
Ich hab nur das Problem das das Script irgendwan 100% CPU Last verursacht und keine Daten mehr analysiert.
Mir scheint es, das die while Schleife die die Daten vom USB Port ließt durchläuft ohne daten zu verarbeiten und d.h. die 100 % CPU Last erzeugt wird.
Habe schon einige Exceptions eingebaut und kommen nicht wirklich weiter :-(

Code: Alles auswählen

	ser = serial.Serial(SerialPort, 9600,)
	writePidFile()

	while 1:
		if ser.isOpen():
			read = ser.read()
			if binascii.b2a_hex(read) == "aa":
				if sync == 0:
					#"got first AA"
					state = 1
					continue
				elif sync == 1:
					#"got second AA"
					state = 3
					continue
			if binascii.b2a_hex(read) == "55":
				if sync == 0 and state == 1:
					#"got first 55"
					state = 2
					sync = 1
					continue
				elif sync == 1 and state == 3:
					#"got second 55. read done..."
					#ToDo check length ?!?
					process_data(data)
					state = 0
					sync = 0
					data = ""
					continue
			else:
				data = data + read
		
		else:
			print SerialPort," is not open!"
			log.critical(SerialPort + " is not open!")
			time.sleep(30)
			
except (serial.SerialException, serial.serialutil.SerialException),ex:
	print "serial.SerialException()", ex
	log.exception("serial.SerialException()")
	conn.close()
	ser.close()
	sys.exit(0)

except serial.SerialTimeoutException:   #for write timeouts only
	print "serial.SerialTimeoutException"
	log.exception("serial.SerialTimeoutException()")
	conn.close()
	ser.close()
	sys.exit(0)

except Exception, ex:
	log.exception("Something awful happened!")
	print "main: Something awful happened!",ex
Danke und Gruß Jay Kay
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Ich habe mir den Code jetzt nicht im Detail angeschaut, aber du solltest auf jeden Fall noch die benötigte Zeit zwischen zwei while-Durchläufen ins Log schreiben und welche Daten gelesen wurden. Auch "data" sieht etwas seltsam aus, da du es nirgends richtig verwendest. Willst du vielleicht immer die ersten beiden Zeichen von "data" testen und nicht "read"? Ein Zustandsdiagramm auf Papier könnte für dich auch hilfreich sein.

Noch ein paar allgemeine Anmerkungen zu deinem Code:
- Statt 0 und 1 solltest du False und True verwenden
- "ser" sagt nicht besonders viel über den Inhalt aus
- "read" ist ein schlechter Name, denn daran sind Daten gebunden und keine Funktion (was "read" impliziert)
- ``binascii.b2a_hex(read)`` musst du nur einmal aufrufen, beim zweiten Aufruf ist ein elif sinnvoll
- Nur den Namen der Fehlermeldung ins Log zu schreiben ist nicht besonders sinnvoll, von Interesse ist der Traceback, damit man auch weiß wo der Fehler aufgetreten ist
- "sys.exit(0)" gibt an, dass das Programm korrekt beendet wurde. In deinem Fall trifft das wohl nicht ganz zu ;-)
- Die ganzen close-Aufrufe lassen sich wahrscheinlich mit with-Statements vermeiden.
- Ich würde den States Namen geben, anders steigt man da irgendwann nicht mehr durch

Sebastian
Das Leben ist wie ein Tennisball.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

ToDo check length ?!?
Ja das solltest du tun :-D. Was ist wenn read nie wieder 55 wird weil du nur noch schrott empfängst, warum auch immer, dann wächst data ins unendliche.

Du könntest eine Variable hochzählen mit "data = data + read", denn die packetlänge die du in process_data() verarbeitest wird wohl eine defenierte Länge haben; und wenn nicht zumindest eine maximale Länge.

Vielleicht liegt der Fehler auch in precess_data().

PS:

Code: Alles auswählen

data = data + read
lässt sich doch schön als

Code: Alles auswählen

data += read
schreiben
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Kann es sein, dass Du im if ser.isOpen():-Zweig kein sleep hast? (schwierig zu erkennen mit der kaputt anmutenden Einrückung) Dann ist der if-Teil innerhalb Deiner Schleife busy, falls das Lesen vom Port nicht blockierend ist oder das Gerät fleißig Daten schickt.
Antworten