Schleife in vorhandenes Skript erstellen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

Hast jemand noch einen Tip, daß nach 60 Durchgängen das dann geschrieben wird, aber der counter trotzdem weiterzählt?
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Frage verstehe ich nicht. Was ist `das´? Und warum `trotzdem`?
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

Der Vater des Gedanken ist folgender. Um die Schreibvorgänge auf der SDCard niedrig zu halten und weil es auch nicht notwendig ist, wäre es prima, wenn das LOG-File die Uhrzeit und die fortlaufende Nummer nicht sofort, sondern nach 60 Einträgen erst schreibt, dann aber trotzdem weiterzählt und nicht bei Null wieder beginnt.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Der interne Puffer wird bei flush geschrieben. Du darfst also flush nicht jedesmal aufrufen, sondern nur dann, wenn Du das willst.
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

Da wäre es doch gut, sowas mit i=i+1 und dann if i= 60 dann flush, oder?
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum willst Du noch ein `i`, Du hast doch schon counter?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der richtige Weg für sowas ist das logging Modul zu verwenden und sich einen eigenen LogHandler zu schreiben, der entsprechend verzögernd schreibt. Statt das eigene Programm an allen möglichen Ecken mit dieser Überlegung zu überziehen.

Oder das System so aufsetzen, dass es ins RAM loggt.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: Bisher ist das ja nur *eine* mögliche Ecke. Zudem, soweit ich sehe, sind das ja Messdaten die geschrieben werden und keine log-Daten.
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

Sirius3 hat geschrieben: Donnerstag 15. Oktober 2020, 09:56 Warum willst Du noch ein `i`, Du hast doch schon counter?
Der counter ist für das fortlaufende schreiben.
Das i wäre um bis zu 60 zu zählen um dann i wieder auf Null zu setzen, wenn die 60 erreicht ist und von vorne anzufangen und auch zu schreiben.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@krischeu1: Ja aber der `counter` läuft doch auch immer von 0 bis 59 und fängt dann von vorne an. Warum willst Du jetzt ein `i` das in der gleichen Schleife genau die gleichen Werte annimmt?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

krischeu1 hat geschrieben: Donnerstag 15. Oktober 2020, 10:26
Sirius3 hat geschrieben: Donnerstag 15. Oktober 2020, 09:56 Warum willst Du noch ein `i`, Du hast doch schon counter?
Der counter ist für das fortlaufende schreiben.
Das i wäre um bis zu 60 zu zählen um dann i wieder auf Null zu setzen, wenn die 60 erreicht ist und von vorne anzufangen und auch zu schreiben.
man könnte wahrscheinlich auch testen ob counter teilbar durch ein vielfaches von 60 wäre und dann schreiben lassen ....
Aber das ist wahrscheinlich sehr aufwändig. Dafür braucht man halt das i nicht und ein zurück setzten ist auch nicht nötig.
Benutzeravatar
sparrow
User
Beiträge: 4198
Registriert: Freitag 17. April 2009, 10:28

@krischeu1: Du solltest deinen Variablen dringend vernünftige Namen geben und diese 01-suffix loswerden. "sensor01" ist kein Sensor sondern eine Ausgabedatei. Und die sollte auch so heißen. Also so etwas wie "outfile" oder "logfile" - aber sicher nicht sensor.
"ticks" sind für mich auch keine Ticks sondern seconds.

liste01 braucht kein 01 und zaehler01 ist kein zaehler sondern eine zahl.
Aber eigentlich ist diese Liste völlig überflüssig. Du schreibst da ja einfach nur alle Zahlen von 0 bis 59 rein um über die zu iterieren. Und zwar immer wieder. An sich ist das schon unnötig und Sirius3 hat dir gestern gezeigt, dass man mit itertools.count über eine fortlaufende, aufsteigende Reihe von Zahlen iterieren kann. Also das, was du in der Log-Datei haben willst.

Also: Vernünftige Namen vergeben, itertools.count verwenden, gucken ob die Rückgabe von itertools.count durch 60 teilbar ist und dann flushen wenn das der Fall ist.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

@krischeu1: Teilbarkeit zu prüfen ist nicht aufwändig: counter % 60 == 0.
krischeu1
User
Beiträge: 19
Registriert: Freitag 2. Oktober 2020, 09:52

So funktioniert es nun einwandfrei ....
Vielen Dank an alle besonders Sirius3

Code: Alles auswählen

from RPi import GPIO
import time
from queue import Queue
from functools import partial 
from itertools import count

RECEIVER_PIN = 23
OUTPUT_FILENAME = "/home/pi/Documents/sensors/sensor01_tageswert.txt"

def callback(queue, channel):
    queue.put(time.time())

def main():
    try:
        queue = Queue()
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(RECEIVER_PIN, GPIO.IN)
        GPIO.add_event_detect(RECEIVER_PIN, GPIO.FALLING, callback=partial(callback, queue), bouncetime=500)
        with open(OUTPUT_FILENAME, "a+") as sensor01:
            for counter in count(1):
             ticks = queue.get()
             print("Sensor1: Lichtschranke wurde unterbrochen")
             sensor01.write(f"{ticks}, {counter}\n")
             if counter % 5 == 0:
                 print ("FLUSH")
                 sensor01.flush()
             
    finally:
        GPIO.cleanup()

if __name__ == '__main__':
    main()
Antworten