Seite 1 von 1

Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 04:03
von Dexter
Hi und Hallo,

ich bin noch relativ neu in der Pythonwelt. Habe jetzt nach sehr vielem herumprobieren mich doch entschlossen hier einmal nachzufragen. Folgendes Problem:
Ich habe mir dieses klitzkleine Script gebaut:

Code: Alles auswählen

#!/usr/bin/env python2.7  
 
import RPi.GPIO as GPIO  
GPIO.setmode(GPIO.BCM)  

while True:
   # GPIO 23 set up as input. It is pulled up to stop false signals  
   GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
  
   print "Make sure you have the camera connected so that when a signal comes"  
   print "it will connect GPIO port 23 (pin 16) to GND (pin 6)\n"  
   #raw_input("Press Enter when ready\n>")  
  
   print "Waiting for voltage drop on port 23\n"  
   # program is waiting for falling edge 

   try:  
       GPIO.wait_for_edge(23, GPIO.FALLING)  
	   if GPIO.IN == True:
          f = open('interrupt', 'w')
          f.write('Voltage drop detected, getting GPS-Time\n') 
		  #f.flush()
          f.close()

   except KeyboardInterrupt:  
       GPIO.cleanup()       # clean up GPIO on CTRL+C exit  
   GPIO.cleanup()           # clean up GPIO on normal exit 
Es liest einen Spannungsabfall einer an PIN 23 (RaPi GPIO) angeschlossenen Elektronik aus. Der Spannungsabfall wird auch wie gewünscht erkannt. Nur hat sich das Programm nach dem ersten Durchlauf immer beendet. Deswegen die infinte Schleife zu Beginn des Codes. Jetzt kann ich wie gewünscht immer wieder den Interrupt auslösen. Weiter unten will ich dann das (erstmal testweise) die Zeile "Voltage drop detected, getting GPS-Time" in ein Textfile geschrieben wird. Allerdings wird nur eine eizige Zeile in das Textfile geschrieben und nicht wie gewünscht die Anzahl an Zeilen, die der Anzahl Interrupts entspricht. Ich habe alle möglichen Schleifenkonstruktionen, Abfragen mit allen möglichen Varaiblen ausprobiert. Komme aber nicht auf ein zufriedenstellendes Ergebnis!

Vielleicht kann mir einer von euch einen Denkanstoss geben?

ps.: Der Code ist mit Sicherheit nicht schön, aber er funktioniert im Kern. Bin ja noch blutiger Anfänger :P

Grüße
Dexter

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 04:13
von Dexter
Okay Epic Fail!

Die Datei wird natürlich immer wieder überschrieben, da sie innerhalb der while Schleife erstellt wird. Habe das erstellen der Datei über die While schleife verschoben. Nun funzt es!

Edit: Dafür funktioniert mein weiteres vorgehen nicht. Ich habe nun den Code:

Code: Alles auswählen

#!/usr/bin/env python2.7  
 
import RPi.GPIO as GPIO  
GPIO.setmode(GPIO.BCM)  

f = open('interrupt.txt', 'w')
f2 = open('gps.txt', 'r')

while True:
   # GPIO 23 set up as input. It is pulled up to stop false signals  
   GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
  
   print "Make sure you have the camera connected so that when a signal comes"  
   print "it will connect GPIO port 23 (pin 16) to GND (pin 6)\n"  
   #raw_input("Press Enter when ready\n>")  
  
   print "Waiting for voltage drop on port 23\n"  
   # program is waiting for falling edge 

   try:  
       GPIO.wait_for_edge(23, GPIO.FALLING)  
	   if GPIO.IN == True:
          f.write('Voltage drop detected, getting GPS-Time\n')
          f.flush()
	   
   except KeyboardInterrupt:  
       GPIO.cleanup()       # clean up GPIO on CTRL+C exit  
   GPIO.cleanup()           # clean up GPIO on normal exit 
Nun möchte ich aber mit f.write() nicht mehr den einen Satz schreiben, sondern eine einzelne Zeile, die ich aus einem anderen Textdokument lesen möchte. Das habe ich über diesen Code versucht, bekomme aber irgendwie unergründliche Syntax Errors:

Code: Alles auswählen

# Datei file einlesen
def readfile(file):
	f = codecs.open(file, 'r', 'utf-8')
	lines = list()
	try:
		for line in f:
			lines.append(line.strip())
	finally:
		f.close()
	return lines

# Den Inhalt von data in file schreiben
def writefile(file, data):
	f = codecs.open(file, 'w', 'utf-8')
	for line in data:
		f.write(line)
		f.write('\n')
	f.close()


Das habe ich in meinen Code in die if-Schleife eingefügt, komme jedoch nichtmal zum auslesen, da ich indent und Syntax Fehler bekomme. Diese kann ich aber patu nicht entdecken.

Gibt es vielleicht eine einfachere Möglichkeit eine Zeile aus einem txt auszulesen und diese bei jedem Interrupt in ein anderes txt zu schreiben?

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 06:35
von p90
Hm zwei Fragen:
1. Dein GPIO Setup und Cleanup ist in der Schleife, soll das wirklich mit jeder Schleife ausgeführt werden?
2. Solltest du "with" zum öffnen der Datei benutzen. Du flushsd zwar aber trotzdem.

[EDIT]
Geht das in die Richtung was du machen willst?

Code: Alles auswählen

#!/usr/bin/env python2.7  

import RPi.GPIO as GPIO  
GPIO.setmode(GPIO.BCM)  

# Datei file einlesen
def readfile(file_path):
    with codecs.open(file_path, 'r', 'utf-8') as file:
        return file.readlines()

# Den Inhalt von data in file schreiben
def writefile(file_path, data):
    with codecs.open(file_path, 'a', 'utf-8') as file:
        #using a for append, if w, the file will only containg
        #the last written line
        file.writelines(data)
        #data must be some kind of sequence like a list

while True:
    # GPIO 23 set up as input. It is pulled up to stop false signals  
    GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
    print "Make sure you have the camera connected so that when a signal comes"  
    print "it will connect GPIO port 23 (pin 16) to GND (pin 6)\n"  
    #raw_input("Press Enter when ready\n>")  
    print "Waiting for voltage drop on port 23\n"  
    # program is waiting for falling edge
    try:
        GPIO.wait_for_edge(23, GPIO.FALLING)  
        if GPIO.IN == True:
            #interrupt.write('Voltage drop detected, getting GPS-Time\n')
            #interrupt.flush()
            #read gps.txt and append content to interrupt.txt
            writefile("interrupt.txt", readfile("gps.txt"))
    finally:
        GPIO.cleanup() # always clean GPIO

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 08:09
von Hyperion
Oha... Dein ``readfile`` ließe sich viel hübscher so ausdrücken:

Code: Alles auswählen

def readfile(filename):
    with codecs.open(filename, 'r', 'utf-8') as f:
        return [line.strip() for line in f]
Im übrigen solltest Du nicht ``file`` als Namen verwenden. Erstens überschreibst Du damit ein Builtin und zweitens passt der Name nicht zum Objekt dahinter: Du übergibst eben *kein* File-Objekt, sondern einen *Dateinamen*!

Und bitte verwende doch vier Leerzeichen als Einrückung - wie es PEP8 vorsieht.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 08:58
von Dexter
@p90 Das sieht schon sehr gut aus. Auch wenn ich den Code genauer studieren und zu einigen der Bausteinen in die Beschriebungen gucken muss um komplett durchzusteigen. Aber ich will es ja schließlich auch lernen und nicht nur einen vorgekauten Code verwenden. Danke aber auf jeden Fall schonmal. Kann es leider am Montag erst testen, aber werde mich dann wieder melden.

@Hyperion Ich verwende nicht "file" in meinem Programm. Das habe ich lediglich zum einfacheren lesen des Codes dort eingefügt. :wink:

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Freitag 10. Januar 2014, 10:12
von Hyperion
Dexter hat geschrieben: @Hyperion Ich verwende nicht "file" in meinem Programm. Das habe ich lediglich zum einfacheren lesen des Codes dort eingefügt. :wink:
Ersteres ist gut, letzteres nicht, denn ``filename`` hätte sich eben einfacher gelesen, da man nicht auf die falsche Fährte gelockt wird.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Montag 13. Januar 2014, 02:45
von Dexter
P90, das Skript funktioniert soweit super, außer das ich noch codecs importieren musste :P
Es tun sich aber immer neue Probleme auf...Ich möchte jedes mal wenn eine der Zeilen geschrieben wird, die entsprechende Zeilennummer davor geschrieben wird. Am besten sollte das in der ersten Spalte stehen und das was aus der anderen Datei geholt wurde in die zweite. Bekomme das allerdings nicht hin und google spuckt absolut nichts in die Richtung aus.
Ich meine es kann ja nicht so schwer sein eine extra Spalte einzufügen und in diese eine fortlaufende Zahl einzufügen. Gibt es da vielleicht eine extra Funktion?

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Montag 13. Januar 2014, 06:15
von Dexter
Da ich meinen Beitrag anscheinend nicht editieren kann...
Hab es hinbekommen, jetzt sieht die Datei schön aus! Aber meine nächste Frage kommt bestimmt bald, wenn ihr nichts dagegen habt. :P

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Montag 13. Januar 2014, 08:33
von Hyperion
Dexter hat geschrieben: Ich meine es kann ja nicht so schwer sein eine extra Spalte einzufügen und in diese eine fortlaufende Zahl einzufügen. Gibt es da vielleicht eine extra Funktion?
Auch wenn Du es vermutlich schon gelöst hast: ``enumerate`` ist die Funktion, die Du suchst (gesucht hast) ;-)

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Dienstag 14. Januar 2014, 22:01
von carsten171263
in Zeile 20 mußt Du statt f = open('interrupt', 'w') folgendes eintragen: f = open('interrupt', 'a'). Das a hinten steht für auf deutsch anfügen (append).

cu, Carsten

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 05:17
von Dexter
Du meinst wohl Zeile 6?!

Ich habe heute nochmal meinen Quelltext ausgeführt. Er hat vor zwei Tagen einwandfrei funktioniert, jetzt hingegen habe ich angeblich einen Syntaxfehler wo keiner ist. Ich habe absolut nichts verändert und trotzdem soll auf einmal ein Syntax Fehler da sein...

Außerdem noch eine andere Frage. Ich habe es jetzt geschafft mit dem anderen Programm die Systemzeit des Raspberry automatisch immer auf die aktuell empfangene GPS-Zeit zu setzen. Diese möchte ich nun in das Textfile schreiben, anstatt diese Zeit aus der anderen Textdatei zu holen. Bekomme es allerdings (mal wieder) nicht hin.

Die Zeit in Millisekunden seit dem 01.01.1970 hole ich mir so:

Code: Alles auswählen

import datetime from datetime
dt = datetime.now()
dt.microsecond
print dt
Diese würde ich nun gerne in das interrupt.txt schreiben. Bekomme aber keine Ausgabe, wenn ich das versuche...

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 09:26
von BlackJack
@Dexter: Was versuchst Du denn um das in eine Datei zu schreiben? Wobei Du da auch gar nicht die Millisekunden ausgibst sondern das `datetime`-Objekt. Und dann sind Mikrosekunden etwas anderes als Millisekunden und die Mikrosekunden die Du so von `dt` abfragst ist auch wirklich nur der Mikrosekundenanteil an der aktuellen Zeit, also das was übrig bleibt wenn man Stunden, Minuten, und Sekunden abzieht, und nicht etwa die Mikrosekunden seit 1970. Da möchtest Du vielleicht lieber ohne irgendwelche Umwege die Sekunden seit „the Epoch” mit `time.time()` auslesen und mit 1000 multiplizieren.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 09:42
von Dexter
Das hatte ich vorher schon so, also:

Code: Alles auswählen

import time
milliseconds = int(round(time.time()*1000))
print milliseconds
Da erhalte ich dann, wie du schon sagtest die Mellisekunden seit epoch. Allerdings muss ich dass dann ja wieder alles umrechnen, um auf ein Datum im gewünschten Format zu kommen. Wohingegen mir datetime direkt das richtige Format gibt. Und du bist dir sicher, dass dabei die Millisekunden einfach weggelassen werden? Das ergibt doch keinen Sinn. Wenn dann sind die Millisekunden einfach in den Mikrosekunden enthalten, was ja völlig egal ist, da die Genauigkeit so nur noch steigt.

ps.: Diese Zeit soll ganz simpel untereinander in eine Textdatei geschrieben werden, sobald ein Event eintritt.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 12:27
von cofi
Einfach mal testen:

Code: Alles auswählen

In [9]: import datetime

In [10]: datetime.datetime.now().microsecond
Out[10]: 836896

In [11]: import time

In [12]: time.time()
Out[12]: 1389784605.812602
Jetzt ist [10] > 1000, das koennen also nicht nur die Mikrosekunden sein sondern auch noch die Millisekunden. Vergleichen wir das aber mit [11] dann wird auch deutlich, dass es auf keinen in Richtung Epoch geht.

Was BlackJack meinte ist nicht, dass es nicht die Mikrosekunden und die Millisekunden sind, sondern dass es _nicht_ die Darstellung der Zeit in Mikrosekunden sind - und schon gar nicht seit Epoch, denn dafuer machen nur Sekunden Sinn.
Soll heissen, mit datetime musst du selbst noch die Sekunden, Minuten, Tage, ...., Jahre zusammenzaehlen und die Differenz zu Epoch bilden, wenn du das richtige Ergebnis haben willst.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 12:45
von Dexter
Okay, vielleicht reden wir aneinander vorbei. Ich habe ein Programm, welches die GPS-Zeit von einem GPS 50 mal die Sekunde bekommt. Diese GPS-Zeit wird von dem Programm als Systemzeit gesetzt.
Das Python-Script hier, soll sich nur diese Zeit holen und im gewünschten Format in eine Textdatei speichern, sobald das Event an der GPIO Pins meines Pi's kommt.
Und genau das passiert, wenn ich datetime.now() verwende. Ich bekomme genau die Zeit, die ich auch so in der oberen Linken Ecke meines Desktops sehe, außer das hinten noch milli und mikrosekunden dran sind. Also die Genauigkeit höher ist, als die "normale" Systemzeit.

Oder habe ich jetzt irgendwas immer noch nicht verstanden und sehe das Problem nicht? Für mich ist im Moment das einzige Problem, diese ausgelesene Zeit in eine Textdatei zu schreiben.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 12:49
von BlackJack
@Dexter: Du hast aber erst nach den Millisekunden seit Epoch gefragt. Anscheinend brauchst Du die gar nicht. Wenn Dir die Standard-Zeichenkettendarstellung von `datetime`-Objekten zusagt, dann wandel das Objekt einfach in eine Zeichenkette und schreib die dann in eine Datei. Wenn Du die Formatierung der Zeit selber beeinflussen willst, dann verwende zur Umwandlung die `strftime()`-Methode.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 12:56
von Dexter
Das tut mir leid, dann habe ich mich vorher zu undeutlich ausgedrückt. Bei mir funktioniert eben dieses schreiben der Zeit in eine txt nicht. Einfach so schreiben mit fh.write() klappt super. Nur bekomme ich das nicht in die Schleife eingebaut, damit es jedes mal geschrieben wird, sobald ein Event eintritt. Irgendwas mache ich da falsch, ich kann morgen (bei euch mitten in der Nacht) mal den Code posten, mit dem ich das versucht habe. Habe ich gerade keinen Zugriff drauf, da der nur aufm Pi liegt.
Das Readfile kann ich jetzt ja wegnehmen, da ich vorher keine txt mehr zum lesen öffnen muss...

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 14:16
von /me
Dexter hat geschrieben:Bei mir funktioniert eben dieses schreiben der Zeit in eine txt nicht. Einfach so schreiben mit fh.write() klappt super. Nur bekomme ich das nicht in die Schleife eingebaut, damit es jedes mal geschrieben wird, sobald ein Event eintritt.
Der folgende Code schreibt bei mir problemlos die ganze Datei voll.

Code: Alles auswählen

with open(filename, 'w') as fh:
    while True:
        fh.write('{}\n'.format(datetime.datetime.today()))
        fh.flush()
Das flush ist nur dafür da, um beim manuellen Abbruch der Schleife wirklich alle Daten bereits geschrieben zu haben.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Mittwoch 15. Januar 2014, 15:32
von cofi
Alternativ kann man auch das oeffnen der Datei (dann im schon angesprochenen "append" Modus) in die Schleife ziehen.

Code: Alles auswählen

while True
    with open(filename, 'a') as fh:
        fh.write('{}\n'.format(datetime.datetime.today()))
Das wuerde ich aber nur bei einer Schleife bevorzugen, die tatsaechlich mehr tut als nur die einzelne Zeile zu schreiben.

Re: Speichern in Datei innerhalb von Endlosschleife

Verfasst: Donnerstag 16. Januar 2014, 05:05
von Dexter
Vielen Dank an alle, die mir geholfen haben. Funktioniert jetzt alles soweit wie ich mir das vorstelle!

Viele Grüße,
Dexter