Eingang nur auswerten wenn mindestens fuer 5 sec ansteht

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
gwaag
User
Beiträge: 5
Registriert: Donnerstag 9. Mai 2019, 14:36

Donnerstag 9. Mai 2019, 15:03

Hallo,
ich moechte einen Input pfd.input_pins[0].value == 1: oder ==0 : folgendermasen abfragen:

Wenn der Eingang fuer mindestens 5 sec. ansteht (high od.1) mit subprocess.call ein script aufrufen, wenn der Eingang weniger als 5 sec. ansteht soll nichts passieren.
Wenn der Eingang fuer mindestens 5 sec. nicht ansteht (low od. 0) mit subprocess ein script ausfuehren, wenn der Eingang weniger als 5 sec. nicht ansteht, soll nichts passieren.

Ich kenne das von PLC programmieren, da geht sowas mit einem Timer_On. Habe Stunden lang im Internet gesucht, aber leider nichts passendes gefunden.
Der Eingang pfd.input_pins[0].value < 1: ist uebrigens von Pifacedigitalio.

Danke und Gruss
gwaag
__deets__
User
Beiträge: 5601
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 9. Mai 2019, 15:08

Ich würde das mit einem zustandsautomaten lösen. Wie an einem ähnlichen Problem hier illustriert: https://github.com/deets/brombeerquark/ ... mulator.py
gwaag
User
Beiträge: 5
Registriert: Donnerstag 9. Mai 2019, 14:36

Donnerstag 9. Mai 2019, 16:55

Hallo,
sorry ist mit zu kompliziert, bin Anfaenger, es muss doch eine einfachere Loesung geben.
Habe vor ein paar Tagen folgendes probiert, siehe unten:
Dieses script funktioniert wie es soll, leider aber nur vom Terminal aus. Wenn ich es in rc.local starte, sehe ich es nicht mit ps aux.
Wenn ich break und if run_prog: # auskommentiere, sehe ich es als gestartet, funktioniert aber so halt nicht mehr.
Loesung? oder anderen code?

#!/usr/bin/env python3

# LED PifaceTest

import pifacedigitalio
import time
from time import sleep


pfd = pifacedigitalio.PiFaceDigital()
# creates a PiFace Digital object

timeout = time.time() + 5.0

run_prog = True


while timeout > time.time():
if pfd.input_pins[0].value < 1:
run_prog = False
break
time.sleep(0.1)


if run_prog:
for x in range(10): # blink
pfd.leds[7].toggle()
sleep(0.1)
pfd.leds[7].toggle()
sleep(0.1)
Benutzeravatar
__blackjack__
User
Beiträge: 3352
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 9. Mai 2019, 22:07

@gwaag: Vielleicht ein Rechteproblem. Ich würde `rc.local` aber auch nicht mehr benutzen wenn es systemd auf dem System gibt. Schreib Dir eine Systemd-Unit dafür, dann kannst Du zum Beispiel auch die Standard- und die Fehlerausgabe protokollieren und da dann nachsehen ob es irgendwelche Ausgaben oder Ausnahmen beim starten/ablauf gegeben hat. Zudem kannst Du das dann auch einzeln starten und stoppen ohne immer den Rechner neustarten zu müssen.

Anmerkungen zum Code: Du importierst und benutzt `sleep()` direkt, aber auch `time` und benutzt `sleep()` über das `time`-Modul. Das ist verwirrend.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Haupprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Kommentare stehen *über* dem Code den sie kommentieren. Und sie sollten dem Leser einen Mehrwert über den Code geben. Faustregel: Nicht beschreiben *was* der Code macht, denn das steht da ja bereits als Code, sondern *warum* er das (so) macht – sofern das nicht offensichtlich ist.

So ein Eingabepin kann doch nur die Werte 0 und 1 annehmen, also ist ein Vergleich ``< 1`` ein bisschen komisch. Dann denkt man vielleicht das es auch ein analoger Wert wie 0.42 oder ein negativer sein könnte. Zudem sind 0 und 1 im boole'schen Kontext auch `False` und `True`, das heisst man braucht hier gar keinen vergleich, sondern ``not``.

Für Namen die man aus syntaktischen Gründen schreiben muss, die man aber gar nicht verwendet, hat sich der Name `_` etabliert. Dann weiss der Leser das es Absicht ist, das der Name nirgends verwendet wird.

In der ``for``-Schleife die 10× durchlaufen wird, steht zweimal identischer Code. Da kann man den Code in der Schleife nur *einmal* schreiben und dafür die Schleife 20× laufen lassen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
"""LED PifaceTest"""
import time 

import pifacedigitalio


def main():
    pfd = pifacedigitalio.PiFaceDigital()
    run_prog = True
    timeout = time.time() + 5.0
    while timeout > time.time():
        if not pfd.input_pins[0].value:
            run_prog = False
            break
        time.sleep(0.1)

    if run_prog:
        for _ in range(20):
            pfd.leds[7].toggle()
            time.sleep(0.1)


if __name__ == '__main__':
    main()
Für magische Zahlen wie die Nummer des Eingabepins und die LED definiert man sich üblicherweise Konstanten mit einem beschreibenden Namen.
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
__deets__
User
Beiträge: 5601
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 10. Mai 2019, 09:36

Der Code tut ja aber nicht, was der TE wirklich will.

@gwaag: wenn du keine Lust hast, dich mit der Programmierung in Python auseinander zu setzen, aber SPS kennst - dann ist vielleicht codesys etwas fuer dich. Kostet nur 50 fuer eine Lizenz.
gwaag
User
Beiträge: 5
Registriert: Donnerstag 9. Mai 2019, 14:36

Freitag 10. Mai 2019, 17:05

@blackjack,
vielen Dank fuer Deine Kommentare und Geduld, ich werde probieren mich in Zukunft zu verbessern.
Habe Dein script geladen und probiert.
Es funktioniert genau so wie es soll, aber leider nur wenn ich das script vom Termial starte. Obwohl es in rc.local eingetragen ist, wird es mit
ps aux nicht aufgelistet. Wenn ich es mit systemd service mache genau das gleiche, ich starte den service dann sehe ich ca. 10sec dass der service gestartet wurde(alles gruen) und wenn ich dann 10sec. spaeter wieder schaue ist er nicht mehr gruen, also gestoppet.
Mit welchen Befehl kann ich den systemd service fuer das script debuggen?? um zun sehen wo es haengt?

Wenn ich im script break und if run_prog: auskommentiere #, sehe ich das script in ps aux und auch in systemd ist alles auf gruen, aber natuerlich funktioniert das script nicht mehr.
gruss und danke
gwaag
__deets__
User
Beiträge: 5601
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 10. Mai 2019, 18:51

Da gibt es nix zu debuggen. Das Programm beendet sich regulär nach etwa 7 Sekunden (wenn run_prog wahr ist). Es tut halt nicht was du oben erklärt hast was es tun soll. Sonst ist es in Ordnung.
gwaag
User
Beiträge: 5
Registriert: Donnerstag 9. Mai 2019, 14:36

Freitag 10. Mai 2019, 20:34

Habe das alte original script nochmals geladen, das funktioniert einwandfrei, es zeigt in ps aux und systemd service korrekt an.
Warum gibt es dann das Problem dass das neue script nur vom Terminal aus gestartet funktioniert?
In das orignial script wurde ja jetzt nur diese " hold-time eingebaut, damit der Taster mindesten die 5 sec, gedrueckt sein muss damit es blinkt.
Wie wuerdest Du denn das machen, oder warum geht es nicht so wie gewollt, deets?

Hier das alte script:
gruss und danke
gwaag

Code: Alles auswählen

#!/usr/bin/env python3

#  Ist Alarm eingeschaltet blinkt Led 1 am Pi 10x

import pifacedigitalio
import time
from time import sleep

# definitions

pfd = pifacedigitalio.PiFaceDigital()     # creates a PiFace Digital object

#  start script

while True:
    sleep(0.1)

    if pfd.input_pins[0].value == 1:
        sleep(1)


        for x in range(10):   # blinken
            pfd.leds[7].toggle()
            sleep(0.5)
Benutzeravatar
__blackjack__
User
Beiträge: 3352
Registriert: Samstag 2. Juni 2018, 10:21

Freitag 10. Mai 2019, 20:51

@gwaag: Funktioniert das neue denn wirklich nicht? Das läuft ja im Gegensatz zum alten nicht endlos, es ist also ganz normal das es nicht mehr in der Prozessliste steht wenn es ganz normal am Ende angekommen ist.
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
__deets__
User
Beiträge: 5601
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 10. Mai 2019, 21:24

Natürlich funktioniert das neue. Ihm ist der Unterschied halt nicht klar, das es nicht endlos läuft.
gwaag
User
Beiträge: 5
Registriert: Donnerstag 9. Mai 2019, 14:36

Samstag 11. Mai 2019, 04:25

Danke fuer die Rueckmedlungen.
Das script laueft, wenn vom Terminal gestartet, jedes Mal, aber nur ein Mal.
Wie muss es dann aussehen damit es endlos läuft? bezw. immer wartet bis der Taster gedrueckt wird?
Danke und Gruss
gwaag
Benutzeravatar
__blackjack__
User
Beiträge: 3352
Registriert: Samstag 2. Juni 2018, 10:21

Samstag 11. Mai 2019, 07:54

@gwaag: Nichts für ungut, aber da ist jetzt ein Verweis auf ein Grundlagentutorial angebracht, da Du offenbar die beiden ja noch sehr einfachen Skripte nicht verstehst. In der Python-Dokumentation gibt es beispielsweise ein Tutorial.
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
Antworten