Seite 1 von 2
Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 14:52
von Regret
Hi Leute,
ich arbeite gerade an einem Teststand als Bachelorarbeit. Zur Zeit wird beim Kalibrieren die Referenztemperatur vom Display des geeichten Messgeräts abgelesen. Da das Gerät auch eine RS232 Schnittstelle hat, wollte ich mir es etwas einfacher machen. Also hab ich folgendes versucht:
Code: Alles auswählen
import time
import serial
port = serial.Serial("/dev/ttyS0", 115200, timeout=0.2)
RefTemp = open("RefTemp.dat", "w")
RefTemp.close()
while True:
RefTemp = open("RefTemp.dat", "w")
newline = port.readline()
RefTemp.write(str("newline;time.ctime();\n"))
RefTemp.close()
print newline
Nachdem der Port geöffnet ist, soll eine .dat Datei mit dem Namen "RefTemp" erstellt werden. Das funktioniert soweit auch, aber:
Weder im Terminal, noch in der Textdatei stehen dann die vom Gerät über die RS232 übertragenen Daten. Wenn ich den Port jedoch mit "Screen" auslese, gibt er mir die gewünschten Werte aus. Also am Port selbst kann es nicht liegen. Ich bin absoluter Python-Neuling, mach ich was oben falsch?
Viele Grüße
EDIT: newline = newline[13:20] hab ich noch in die while-Schleife hinzugefügt, da das Format des RS232 Signals so ist:
01:29:59 00: +022.050 °C P304 ist und ich nur die Zeichen 13-20 (+022.050) brauche.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 17:00
von BlackJack
@Regret: Du erwartest offenbar das auf magische Weise nicht der Inhalt der literalen Zeichenkette geschrieben wird, sondern das Python da irgendwie rät das es da etwas durch etwas anderes ersetzen soll. Wenn Du die Zeichenkette 'newline;time.ctime();\n' in die Datei schreibst, dann wird eben genau diese Zeichenkette in die Datei geschrieben. Wenn Du aus dem Wert der an den Namen `newline` gebunden ist und der aktuellen Zeit als Zeichenkette eine neue Zeichenkette zusammensetzen möchtest, dann musst Du *das* machen. Zum Beispiel mit der `format()`-Methode auf Zeichenketten.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 20:11
von Regret
Naja eigentlich wollte ich das nur mal ausprobieren. Ich war mir da schon unsicher ob das klappt, aber soweit kams ja leider garnicht.
Natürlich hast du aber Recht. Das werd ich morgen direkt ändern.
Wenn ich jetzt aber wie folgt erst einmal das aufschreiben der Werte sein lasse, funktioniert es leider auch nicht.
Code: Alles auswählen
import time
import serial
port = serial.Serial("/dev/ttyS0", 115200, timeout=0.2)
while True:
newline = port.readline()
print newline
Nach meinem Verständnis öffnet ich ja mit pyserial den Port und lese mit port.readline() in der Schleife immer eine Zeile aus die ich direkt ausgebe oder? Also im Endeffekt mach ich ja das gleiche wie mit "Screen". Ich versteh nur nicht, wieso ich in Screen tatsächlich dann was ausgegeben bekomme und bei dem Python Skript nicht
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 20:19
von BlackJack
@Regret: Was heisst ”funktioniert nicht”? Und wie macht man so etwas mit ``screen``?
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 22:17
von Regret
Naja mit
werden eben ähnlich wie wenn man PuttY auf die serielle Schnittstelle anwendet die Signale im Terminal ausgegeben. In meinem Fall weiß ich daher ja, dass mein Signal als "01:29:59 00: +022.050 °C P304" ausgegeben wird. Die Frage ist eben nur wieso ich im Terminal die Ausgabe sehe wenn ich Screen nutze, bei Python hingegen aber nur leere Zeilen ausgegeben werden.
Mit funktioniert nicht meinte ich diese Zeile: RefTemp.write(str("newline;time.ctime();\n"))
Ich wollte die eigentlich mal testen, aber leider kam ich ja auf Grund fehlender Ausgabe noch nicht dazu. Aber wenn du sagst, dass es sowieso nicht so funktioniert, werd ich das morgen nochmal überarbeiten.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 22:20
von DasIch
Kann es sein dass kein \n sondern ein \r ausgegeben wird?
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Montag 23. Mai 2016, 22:56
von harryberlin
ungetestet
was soll dieses ständige open/close der datei in der schleife?
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 08:02
von Regret
@harryberlin: Naja ich hatte eben gestern gelesen, dass ich nach dem Bearbeiten das Dokument wieder schließen muss. Also wär es sinnvoller das Dokument vor der Schleife zu öffnen und geöffnet zu lassen? Aber vielen Dank schonmal für die Hilfe. Sobald ich das Problem mit dem Signaleingang gelöst habe, werd ich das anpassen.
@DasIch: Ich dachte bisher \n seht für eine "newline" im Dokument. Was wäre dann \r? Ich wollte damit bezwecken, dass der Messwert, etc. in eine Zeile geschrieben wird und dann in die neue Zeile gesprungen wird. Eigentlich hätte ich es einfach ausprobiert um zu sehen ob es wirklich tut was ich möchte, aber der Output der RS232 wird ja schon garnicht angezeigt.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 08:33
von Regret
Nachtrag:
Damit ihr wisst was ich mit "Screen" meine. Ich hab wie oben erwähnt den Befehl genutzt um Screen mit der Seriellen Schnittstelle zu connecten und jedes mal wenn ich dann "s" drücke erscheint die Ausgabezeile wie auf dem Bild zu sehen, also Zeitstempel des Gerätes und Messtemperatur.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 08:36
von Sirius3
@Regret: es geht um den Input. Wie liefert Dein Gerät die Daten. Mit '\r' oder mit '\n' abgeschlossen. Beides ist möglich, aber nur '\n' funktioniert mit readline. Um zu testen, ob überhaupt etwas von der Schnittstelle kommt, solltest Du mal mit `port.read()` einzelne Bytes lesen und ausgeben.
Wenn Du die Datei parallel von einem anderen Programm lesen möchtest, ist es schon ratsam, die Datei immer wieder zu schließen, damit auch alle Daten geschrieben werden.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 08:46
von Regret
Hallo Sirius3,
danke für deine Antwort.
Ich hab gerade mal folgendes probiert:
Code: Alles auswählen
import time
import serial
port = serial.Serial("/dev/ttyS0", 115200, timeout=1)
while 1:
x = port.read()
print x
Leider besteht das Problem weiterhin, im Terminal spring ich zwar von Zeile zu Zeile als ob er was ausgibt, aber die Zeilen sind leer.

Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 08:51
von BlackJack
@Regret: Es kommt halt auf die Definition von „nach dem Bearbeiten“ an. Falls zwischen den Schreibvorgängen nicht längere Zeiträume liegen, würde man die Datei wohl eher erst nach der Schleife schliessen. Und dann am besten durch die ``with``-Anweisung oder in einem ``finally``-Block, weil bei dieser Schleife ja nicht ganz auszuschliessen ist, dass sie durch eine Ausnahme abgebrochen wird (E/A-Fehler, Zeitüberschreitung, Benutzer drück STRG+C, …). Wobei Du das schon richtig gemacht hast falls Du *wirklich* immer nur *eine* Zeile in der Datei stehen haben möchtest. Falls alle gelesenen Zeilen in der Datei landen sollten, dann ist der Dateimodus an der Stelle falsch, denn 'w' löscht eventuell schon vorhandenen Inhalt beim Öffnen der Datei.
'\r' ist ein Wagenrücklauf. Und das *Du* '\n' in die Datei schreibst ist schon okay, es ging eher darum was als Zeilenende über die serielle Schnittstelle kommt. `readline()` wartet nämlich auf '\n'. Wenn das nicht kommt, kann man lange warten. Da ein `Serial`-Objekt von `io.RawIOBase`, sollte man da mit einem `BufferedReader` und einem `TextIOWrapper` etwas ausrichten können. (An der Stelle fängt es an ein wenig „javaesque“ zu werden.

)
Wo hast Du in Deinem Programm denn das 's' eingebaut? Wenn man das zur Gegenseite senden muss, dann musst Du das natürlich auch in Deinem Programm machen.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 09:10
von Regret
Hallo BlackJack,
also im Prinzip wollte ich eine Textdabei die am Schluss mal pro Sekunde eine Textzeile hinzufügen soll. Bei der Kalibrierung der Temperaturfühler nimmt das Programm pro Sekunde einen Messwert auf, genau das wollte ich dann eben mit dem geeichten Temperaturfühler mit der Referenztemperatur auch machen um einen vergleichbaren Zeitstempel bzw. Abstand zwischen den Messwerten zu erreichen.
Das s hab ich garnicht in das Programm eingebaut, ich hab nur zufällig rausgefunden das ich im Terminal die Zeile ausgegeben bekomme wenn ich s drücke während "Screen" auf die Serielle Schnittstelle zugreift. Die Frage ist eben ob das an Screen oder dem Messgerät liegt. Also ob Screen eben nur die Zeile ausgibt mit s oder das Messgerät einfach nur auf "s" die Zeile antwortet.
Nochmal zu Python: Ich dachte ich könnte mit "w" einfach in die nächste Zeile schreiben. Also das mein Textdokument etwa so aussieht:
22,359 10:07:21 24052016
22,358 10:07:22 24052016
22,359 10:07:23 24052016
22,359 10:07:24 24052016
22,359 10:07:25 24052016
22,358 10:07:26 24052016
22,359 10:07:27 24052016
.
.
.
Aber so programmiertechnisch würde ich das denke ich schon hinbekommen, wenn es dann mal funktioniert den Messwert überhaupt irgendwie in das Textdokument zu schreiben. Aber anscheinend ist das Problem ja schon, dass ich es nicht hinkriege die Zeile des Messgeräts mit Python überhaupt einzulesen um dann quasi Formatierung, Zeitstempel, etc. anzupassen. Ich weiß eigentlich nur wie das Signal aussieht, weil ich eben mit Screen die Serielle Stelle separat zu Python ausgelesen habe.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 09:18
von Sirius3
Solangsam wird das Bild klarer. Wenn Du die Datei immer weiter füllen willst, dann solltest Du sie nur einmal vor der Schleife öffnen und dann nur immer eine neue Zeile schreiben. Wenn das Messgerät ein 's\n' oder 's\r\n' erwartet, dann solltest Du das auch senden.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 11:14
von BlackJack
Ungetestet und davon ausgehend das die Zeilenenden mit einem '\n' kodiert werden:
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import time
from serial import Serial
def main():
try:
with Serial('/dev/ttyS0', 115200, timeout=0.2) as connection:
with open('RefTemp.dat', 'w') as out_file:
while True:
connection.write('s\n')
connection.flush()
line = next(connection)
if not line.endswith('\n'):
raise ValueError('Oooh, we are in trouble Scotty.')
out_file.write('{0};{1};\n'.format(line.rstrip(), time.ctime()))
time.sleep(1)
except KeyboardInterrupt:
pass # Allow the user to stop the program with CTRL+C.
if __name__ == '__main__':
main()
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 16:31
von Regret
@Sirius3: So also langsam wird das Bild für mich selbst auch ein bisschen klarer. Ich wusste nicht, dass das Messgerät den Messwert nicht nur auf "Anfrage" sendet. Also generell kannte und kenne ich mich leider noch nicht mit seriellen Schnittstellen aus.
@BlackJack: Ich hab den Code probiert. Leider hat das auch nicht geklappt. Nach starten des Skripts wurde die Datei zwar erstellt aber sie war leer und auch im Terminal wurd nix angezeigt.
ABER:
Ich hab aus deinem Script jetzt einfach mal den Befehl übernommen das an die Schnittstelle "s" geschickt wird mit der Zeile
und siehe da: Ich seh zumindest mal im Terminal genau das was ich wollte:
Ich werd jetzt noch versuchen das ganze in die Textdatei einzupflegen und mich in dem Fall das es funktioniert oder eben nicht nochmal hier melden

Schonmal danke soweit an alle!
EDIT:
Jetzt klappt es schonmal mit den Einträgen in die Textdatei. Leider noch ein bisschen wirr:
;Tue May 24 17:44:56 2016;
;Tue May 24 17:44:56 2016;
+022.807;Tue May 24 17:44:56 2016;
;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
+022.806;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
+022.806;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
;Tue May 24 17:44:57 2016;
+022.806;Tue May 24 17:44:57 2016;
Code: Alles auswählen
import time
import serial
port = serial.Serial("/dev/ttyS0", 115200, timeout=1) #oeffnet den serial port S0
RefTemp = open("RefTemp.dat", "w") #erstellt eine .dat-Datei im Modus "write"
RefTemp.close() #schliesst die .dat-Datei
try:
RefTemp = open("RefTemp.dat", "w")
while True:
port.write('s\n')
newline = port.readline()
newline = newline[13:21]
RefTemp.write('%s;%s;\n' % (newline, time.ctime()))
print newline
except KeyboardInterrupt:
pass
RefTemp.close()
Grund dafür ist wohl die Zeile:
Aber wenn ich eins der %s; lösche oder das , time.ctime() dann funktioniert das Skript nicht mehr.
Edit vom Edit?:
Wenn ich
Code: Alles auswählen
RefTemp.write('{0};{1};\n'.format(newline.rstrip(), time.ctime()))
nutze bekomm ich das gleiche Textdokument ausgegeben.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 16:59
von kbr
Regret hat geschrieben:Grund dafür ist wohl die Zeile:
RefTemp.write('%s;%s;\n' % (newline, time.ctime()))
Das ist gewiss nicht der Grund. Eher wohl das fehlende "time.sleep()", das Du nicht eingebaut hast. Womöglich braucht das Messgerät etwas Zeit, bis die nächsten Daten verfügbar sind.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 18:44
von Regret
@ kbr: das ist natürlich ein guter Einwand. Ich werd es morgen wenn ich wieder bei der Arbeit bin mal mit einem time.sleep() probieren.
EDIT: Wie ist das denn eigentlich? Wenn ich beispielsweise eine sleeptime von 1sek angebe. Hab ich dann die Zeit die der Rechner braucht um die Schleife abzuarbeiten + 1Sekunde oder immer genau eine Sekunde zwischen den Messwertaufzeichnungen? Also ich mein die Zeit zum Durchlaufen der Schleife ist wohl im ersten Blick vernachlässigbar, aber wenn ich jetzt beispielsweise über eine Stunde aufnehme würde sich ja der Zeitstempel zwischen dem ersten und dem letzten Messwert um die Rechenzeit * 3600 verschieben oder?
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 19:18
von BlackJack
@Regret: Zu dem `sleep()` kommt natürlich noch die Rechenzeit die der Rest der Schleife verbraucht dazu. Und dazu kommt auch noch das `sleep()` nicht genau ist, das kann mehr oder auch weniger Zeit verschlafen als man angibt. Es wird bei einer Stunde Laufzeit also sich aufaddierende Ungenauigkeiten geben. Selbst wenn Du berechnest wie viel Zeit gewartet werden muss bis zur nächsten Sekunde, wird das nicht genau sein. Zum einen weil Python als Bytecode interpretierende Hochsprache da rein spielt, zum anderen weil ein normales Betriebssystem keine harten Zusagen machen kann wie ein Echtzeitbetriebssystem. Wenn das also ”wirklich” Abstände von einer Sekunde sein sollen müsstest Du den `sleep()`-Wert entsprechend berechnen. Oder etwas wie das `sched`-Modul aus der Standardbibliothek zur Hilfe nehmen.
Re: Temperaturmesswerte über RS232 einlesen
Verfasst: Dienstag 24. Mai 2016, 20:04
von Regret
@Blackjack: Okay dann schau ich morgen mal wenn ich dazu komme, dass die Textdatei nach meinen Vorstellungen formatiert ist und fang einfach mal mit dem Kalibrieren an. Wenn ich wirklich merklich in der Zeitspanne abtriffte behalt ich mal das 'sched'-Modul im Hinterkopf. Schonmal vielen Dank!
PS: Danke an alle trotz der vielen Anfängerfragen. Da ich mir die Python Programmierung mehr oder weniger neben meiner eigentlichen Arbeit versuche anzueignen blieb leider nicht sehr viel Zeit um mich wirklich mal eine vernünftige Zeit dran zu setzen. Ihr habt mir sehr geholfen
