Zeitgesteuertes Relais

  • Hallo liebe Raspberry-Community,


    nachdem ich jahrelang den Raspberry nur für langweilige Dinge, wie Mediacenter etc. verwendet hatte, möchte ich nun ein Hardwareprojekt umsetzten.


    Es soll zu einer bestimmten Uhrzeit ein Relais für 1.5 Sekunden lang getriggert werden.

    Klingt einfach, trotzdem habe ich es nicht hinbekommen. Versuche jetzt seit 2 Stunden mit verschiedensten Ansätzen das Ganze zum

    laufen zu bekommen. Ich bin offensichtlich ein blutiger Anfänger, der dringend Hilfe von ein paar Experten braucht :/


    Wenn ich meinen Code ausführe wird das Relais getriggert, geht jedoch nicht mehr aus...

    Hier ist mein Code:


    Danke im Vorraus für Eure Hilfe!

  • Benutz einen cronjob. Und das Skript nur zum schalten des Relais.

  • Was ist das genau für ein Relais ?

    Eventuell ein „Low Level Trigger“ ?

    Ja, es ist ein Low Level Trigger, ich habe das aber streng nach Anleitung angeschlossen. 3V auf VCC, GND auf GND und IN auf den GPIO (in dem Fall GPIO 4).

    An sich funktioniert es ja, dieser Code funktioniert:

    Wenn ich den Code starte, schaltet das Relais für 1.5 Sekunden zu und geht dann wieder auf, genau wie gewünscht.

    Erst, wenn ich versuche die Zeit abzugleichen, treten Probleme auf.


    Benutz einen cronjob. Und das Skript nur zum schalten des Relais.

    Kannst du mir das genauer erklären, habe gelesen, dass es wohl sehr Resourcenintensiv ist, von einem Skript ein anders aufzurufen...

  • Hallo,

    Kannst du mir das genauer erklären

    Cronjob


    Weitere Links um ein Programm automatisch und zeitgesteuert zu starten:

    https://www.splendid-internet.…-timer-units-mit-systemd/


    https://wiki.archlinux.de/title/Systemd/Timers


    https://opensource.com/article/20/7/systemd-timers


    Damit kannst du deinen funktionierenden Code zu einer bestimmten Zeit ausführen.

    Du nutzt bei deinen importen 'as', das benutzt man um Module die importiert wurden einen anderen Namen zu geben. Du nennst GPIO zu GPIO um. Es müsste dann eher so aussehen from RPi import GPIO as NeuerName oder ebene einfach from RPi import GPIO.

    Allerdings könntest du anstelle von GPIO' auch das aktuellere gpiozero verwenden, eventuell ist das auch für zukünftige Projekte nützlich.

    'datetime' importierst du, nutzt es aber nicht. Dann ist es nicht sinnvoll Warnungen zu unterdrücken, das ist so etwas ähnliches wie wenn du Warnleuchten im Auto mit einem Tape überklebst. Mit einem 'GPIO.cleanup()' am Ende des Codes ist die unterdrückte Warnung meistens zu beheben, auch hier wieder der Hinweis auf 'gpiozero'.

    Konstanten wie dein 'Relay_PIN' schreibt man in Python komplett groß RELAY_PIN

    Sollten mal umfangreichere Programme geschrieben werden, solltest du die Codes mit Funktionen und gegebenenfalls Klassen strukturieren.


    Grüße

    Dennis


    Edit: Versuche mal dieses Skript und lass es mit den oben gezeigten Links automatisch starten. Das Programm muss, wie alle anderen dann auch, ausführbar gemacht werden. Siehe Befehl chmod +x

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

    Edited 3 times, last by Dennis89: '.' gegen ',' im Code getauscht ().

  • Kannst du mir das genauer erklären, habe gelesen, dass es wohl sehr Resourcenintensiv ist, von einem Skript ein anders aufzurufen...

    In diesem Fall deutlich weniger Ressourcen intensiv als deine eigene Implementierung eines weiteren schedulers. Und robuster. Und funktioniert.

  • Die bisherigen Antworten sind alle richtig und sinnvoll. Ich bin auch eher ein Anfänger, wobei ich glaube das Problem in deinem ursprünglichen Code erkannt zu haben.


    Du legst Variablen fest (currhour, currminute) ohne dass diese auch aktiv abgefragt werden. Ich würde noch vor der while-Schleife eine Funktion mit def() schreiben in der diese Werte nicht nur definiert sondern mittels return auch zurückgegeben werden. In der Schleife rufst du dann laufend die Funktion auf (nennen wir sie beispielsweise "Zeit"), indem du zu Beginn "Zeit()" (ohne Anführungsstriche) einfügst.


    LG Christoph

  • Hallo,


    Du legst Variablen fest (currhour, currminute) ohne dass diese auch aktiv abgefragt werden

    Kannst du bitte genauer erklären was du meinst ?


    Direkt in der 'while'-Schleife, nach der Wertzuweiseung von 'currhour' und 'currminute' werden diese Werte mit 'tarrgethour' und 'targetminute' verglichen und das bei jedem Schleifendurchlauf pausenlos, bis die 'if'-Bedingung wahr ist.

    Code
    if currhour == targethour and currminute == targetminute:


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Die bisherigen Antworten sind alle richtig und sinnvoll. Ich bin auch eher ein Anfänger, wobei ich glaube das Problem in deinem ursprünglichen Code erkannt zu haben.


    Du legst Variablen fest (currhour, currminute) ohne dass diese auch aktiv abgefragt werden. Ich würde noch vor der while-Schleife eine Funktion mit def() schreiben in der diese Werte nicht nur definiert sondern mittels return auch zurückgegeben werden. In der Schleife rufst du dann laufend die Funktion auf (nennen wir sie beispielsweise "Zeit"), indem du zu Beginn "Zeit()" (ohne Anführungsstriche) einfügst.


    LG Christoph

    Die Werte werden jeden Schleifendurchlauf erhoben, und in der if-Klausel abgefragt. Das Problem liegt hier in einer zu groß bemessenen Wartezeit, so das das Risiko besteht, dass man den gewünschten Zeitpunkt erst gar nicht trifft. Wenn man die wiederum verkleinert, trifft man ihn mehrfach. Man müsste darum herum arbeiten, oder eben gleich einen der zeitbasierten Dienste benutzen.

  • Rein von der Logik her:

    Code: Pesudocode
    time.sleep(1)
    if aktuelle_zeit > geplantes_ereignis:
        ...
        gpio_toggle()
        geplantes_ereignis = zukunft


    Dann ist auch die Zeit zwischen den Aufrufen egal und bei einer zu starken Verzögerung wird das Ereignis verzögert ausgeführt.

    Entweder das geplante Ereignis nachträglich ausführen oder verwerfen.


    Am einfachsten wäre ein Cronjob.

  • Die Werte werden jeden Schleifendurchlauf erhoben, und in der if-Klausel abgefragt. Das Problem liegt hier in einer zu groß bemessenen Wartezeit, so das das Risiko besteht, dass man den gewünschten Zeitpunkt erst gar nicht trifft. Wenn man die wiederum verkleinert, trifft man ihn mehrfach. Man müsste darum herum arbeiten, oder eben gleich einen der zeitbasierten Dienste benutzen.

    Dem habe ich nichts mehr hinzuzufügen :whistling: ; ich war der Ansicht, dass die if-Klausel nicht ausreicht um currhour, currminute auch laufend zu aktualisieren.


    LG C

  • Danke für Eure Rückmeldungen,

    habe mich jetzt in das Thema crontab etwas eingelesen und es funktioniert - teilweise-

    Ich möchte das Relais zeitgesteuert, aber wenns sein muss auch mit einem Knopf betätigen können.

    Für beides habe ich Skripte, die unabhängig voneinander auch gut funktionieren.

    Wenn ich eines davon in den Crontab reinpacke funktioniert es auch, aber sobald ich beide drinnen habe, funktioniert keines mehr...


    Vielleicht sehen die Profis hier irgendwelche offensichtlichen Fehler und können mir weiterhelfen:

    (Mein crontab)

    LG Simsi

  • Der User pi sollte in der Gruppe GPIO sein. Dann kann man ohne sudo die GPIOs als User pi steuern.


    Die Gruppenzugehörigkeit kann man mit diesem Befehl anzeigen.

    Code
    id


    Und falls der User pi nicht auch in der Gruppe GPIO ist, kann man den User dieser Gruppe hinzufügen.

    Code
    sudo usermod -G gpio -a pi
    # -a für append, anhängen
    # -G liste zusätzlicher Gruppen

    Edited once, last by DeaD_EyE: Die Gruppe GPIO wird kleingeschrieben ==> gpio ().

  • Der User pi sollte in der Gruppe GPIO sein. Dann kann man ohne sudo die GPIOs als User pi steuern.


    Die Gruppenzugehörigkeit kann man mit diesem Befehl anzeigen.

    Code
    id


    Und falls der User pi nicht auch in der Gruppe GPIO ist, kann man den User dieser Gruppe hinzufügen.

    Code
    sudo usermod -G GPIO -a pi
    # -a für append, anhängen
    # -G liste zusätzlicher Gruppen

    Habe das sudo aus dem crontab rausgeschmissen, jetzt funktioniert der Schalter zwar, aber das zeitgesteuerte Skript wird anscheinend nicht aufgerufen.


    btw bekomme ich bei deinem Command

    Code
    sudo usermod -G GPIO -a pi

    den Fehler

    Code
    usermod: Gruppe »GPIO« existiert nicht.
  • Es ist immer schlecht mit solchen Verschiebungen des zu erreichenden Ziels um die Ecke zu kommen, nachdem schon Energie in eine Lösung gesteckt wurde, die das Problem offensichtlich nicht wirklich ausreichend abdeckt.


    Was ist das Gesamtziel hier? Solange das nicht klarer Umrissen ist, werde ich zumindest hier keine Ansätze mehr vorschlagen, weil das für die Katz ist.

    • Official Post

    Die Gruppe gpio wird klein geschrieben, aber egal, denn pi ist bereits in dieser Gruppe.


    Verwende python3 statt python in der Crontab!


    Du lässt Dir doch Ausgaben in Textdateien schreiben, warum nicht auch die Fehler, indem Du an das Ende der Zeilen noch 2>&1 setzt? Also

    Code
    @reboot sudo python3 /home/pi/schalter.py > schalter_log.txt 2>&1
  • Bin jetzt komplett überfordert. Anscheinend liegt es nicht am crontab sondern tatsächlich am Code, der das Relais schalten soll. Der Schalter Code funktioniert:

    mein "testminimal", welcher eigentlich die ganze Zeit funktionierte, geht jetzt nicht mehr:

    Blicke jetzt gar nicht mehr durch :(

  • geht jetzt nicht mehr:

    Bitte mir Fehlermeldung oder wenn keine vorhanden, beschreibe was nicht mehr geht, wie sich die Bauteile verhalten, passiert einfach gar nichts?


    Ich habe bis jetzt noch nicht allzuviele Bauteile über die GPIO-Leiste gesteuert und wenn dann immer mit 'gpiozero' (siehe mein Beispiel oben)

    Kann es vielleicht daran liegen, dass du dein erstes "Schalter"-Skript aufrufst, den GPIO-Pin ein Setup zuweist und diesen steuerst, aber am Ende vom Programm die GPIO-Leiste nicht aufräumst und dein zweiter Code stolpert so zusagen über die Unordnung?


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Ich denke das könnte das Problem sein, im einen Skript prüfe ich ständig, ob der Schalter gedrückt wird. Das zweite Skript geht dann nichts mehr, da es ja die selbe Leitung ansteuern würde. Gibt es eine Möglichkeit im crontab bestimmte Funktionen aus einem Skript auszuführen?