Python Skript und Timedrift?

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hi,

    Ich habe ein Pythonskript mit dem ich die seriellen Daten lese, die von einem Ceilometer kommen. Dieses ist per RS232 an einen serial-to-usb converter angebunden und dann mit dem Pi verbunden. Das auslesen mittels des Skriptes funktioniert einwandfrei, mit einer kleinen Einschraenkung.

    In den gelesenen Daten zeigt sich nach einiger Zeit eine Timedrift. Das Skript schreibt jeden ankommenden serial stream in eine Textdatei. Vor jeden serial string holt es sich die Zeit und das Datum von der Systemzeit und schreibt diese davor.
    Sagen wir der erste string hat den Timestamp "29.02.2016 11:30:25" und der naechste "29.02.2016 11:30:40". Soweit so gut, das passt alles, da die Daten alle 15 Sekunden gesendet werden.
    Nur nach 24 Stunden durchgaengigen lesen der Daten, sehen die Timestamps so aus: "01.03.2016 11:30:22" und der naechste "01.03.2016 11:30:37". Obwohl die Sekunden genau den gleichen Wert haben sollte wie zuvor.

    Mein erster verdacht war, das der Pi aus irgend einem Grund die Internetverbindung verliert und somit die Zeit langsam driftet, da die software clock im Pi einfach zu ungenau ist. Allerdings habe ich dies in den letzten 24 Stunden gecheckt. Der pi war ununterbrochen online und muesste somit auch die Zeit immer neu gesetzt haben. Ich habe extra rdate genutzt, da dem ntp deamon nicht ganz vertraut habe.

    Nach diesem Test habe ich nun den Verdacht, das es am Skript selber liegt. Ist es moeglich das dieses die Timedrift verursacht? Waeren es nur ein paar milisekunden, ware das ja kein Problem, aber ueber 24 Stunden waren es etwas mehr als drei Sekunden.

    Hier das Skript:

    Koennte das Skript aus irgend einem Grund fuer diese Verschiebung sorgen?

    Danke und viele Gruesse,
    BallerNacken

    Einmal editiert, zuletzt von BallerNacken (1. März 2016 um 13:04)

  • Dein Code ist diplomatisch ausgedrückt nicht ansatzweise das Gelbe vom Ei. Das ``datetime`` Modul erzeugt ein spezieller Datentyp nächtlich ``datetime``. Verwende es anstelle deinem String zu Integer usw. Gebastel. Auch achte darauf, dass es keine Code-Wiederholung gibt. Ich sehe hier 100x ``datetime.now().strftime`` zugewiesen an wirre Variablennamen. Der Code sollte lesbar sein, womit wir bei PEP8 - dem Duden dieser Sprache - sind. Halte dich bitte daran. Auch sollte auf Modulebene nur Konstanten, Klassen und/oder Funktionen stehen. Auch öffnest du Dateien ohne diese wieder zu schließen. Dafür gibt es in Python einen eigenen Ausdruck namens ``with``. Dieser Ausdruck kümmert sich u.a. auch um ein sauberes Schließen wieder.

    Dein Programm verzögert sich äquivalent zur verstrichenen Zeit, da das Vergleichen, Abfragen, Schreiben etc. auch seine "Zeit" in Anspruch nimmt. Der unsaubere Code tut sicherlich das Übrige noch dazu ;)

    Anbei mal ein Grundgerüst:

    Edit:
    Was ich noch vergessen habe zu erwähnen: Funktionen sollten nur eine Kernaufgabe haben. Also zB etwas vergleichen, berechnen, eine Datei erstellen usw. aber nicht wie bei dir x-unabhängige Sachen wie in deiner `` createCeilFile`` Funktion.

  • Ja da gebe ich dir natuerlich recht. Da ich immer noch recht neu bin in dem Bereich und es so grundsaetzlich funktioniert, hatte ich es ersteinmal bei dem Code so belassen.

    Ich schliesse die Datei doch mit ``fid.close`` am Ende des Scriptes. Vorher soll die Datei ja gar nicht geschlossen werden, da sie stuendliche Files aufzeichnet.

    Ich werde mal versuchen alles neu aufzubauen und mich da an deinem Grundgeruest zu orientieren.

    Danke,
    BallerNacken

    Edit:

    okay habe mein skript jetzt umgebaut. Bekomme keine Fehlermeldungen, allerdings auch keinen Output. Bin mir aber nicht sicher was ich alles falsch gemacht habe:


    Einmal editiert, zuletzt von BallerNacken (1. März 2016 um 17:54)

  • Ich habe mittels

    Code
    start=datetime.datetime.now()
    #hier ist der code bis fid.writelines(["-"+time_now2,"\n",tdata,"\n"])
    print datetime.datetime.now()-start

    bei meinem alten Skript mal die Drift versucht zu messen. Dabei faellt auf das diese negativ ist. Bei jedem Durchlauf habe ich einige Mikrosekunden weniger. In nur etwa 45 Minuten hat sich die Zeit um etwa 0,7 Sekunden verschoben...

    Das neue Skript ist zwar soweit fertig, liefert allerdings weder Fehlermeldung noch output.

    Viele Gruesse,
    BallerNacken

  • Naja, eigentlich hast du mein Vorschlag gar nicht umgesetzt. Die ganzen ``get_current_time`` Funktionen sind sinnfrei. Eine reicht. Hier nochmal ein Beispiel, was ich eigentlich meinte:

  • Ich habe es ehrlich versucht. Meine jetzige lauffaehige Version sieht auch noch ein wenig anders aus, aber immernoch mit mehreren "get time" Funktionen. Ich brauche die Zeit in unterschiedlichen Formaten und da habe ich mit nur einer time Funktion und Aufruf dieser mit anschliessendem Formatieren Fehlermeldungen bekommen.

    Trotzdem danke ich fuer die Hinweise in Syntax und Aufbau eines Programmes. Werde in Zukunft versuchen das Programm noch demenstprechend zu veraendern. Im Moment muss es aber ersteinmal so gehen.
    Zumal ich den eigenltichen Grund fuer die rueckwaerts wandernde Zeit gefunden habe: sleep()

    Der Befehl ist zu ungenau und wird haeufig einige Mikrosekunden frueher ausgefuhert als er sollte.

  • Hallo,

    Zitat

    Der Befehl ist zu ungenau und wird haeufig einige Mikrosekunden frueher ausgefuhert als er sollte.


    Darauf, _wann_ ein Befehl ausgeführt wird, hast du so wie so keine Einfluss. Das entscheidet alleine der Kernel des Betriebssystems, d.h. der Teil dem Python-Interpreter halt Rechenzeit zu.

    Aufgrund des relativ hohen Takts des Prozessors werden die Befehle zwar in der Regel "zeitnah" ausgeführt, aber eben nicht "auf den Punkt" - wie du ja selber fest gestellt hast. Für "harte" Echtzeitanforderungen gibt es auch speziellere Linux-Kernel, die darauf ausgerichtet sind.

    Außerdem ist bei dir noch I/O im Spiel, der den Programmfluss grundsätzlich auch blockieren kann, weil halt gewartet wird, bis alles geschrieben ist.

    Gruß, noisefloor

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!