Output am MCP23017 definieren

  • Hallo zusammen,

    zuerst etwas allgemeines zum Problem:


    Meine Hardware:

    -Raspberry Pi 3B+

    -MCP23017 als port expander

    -Relaykarte (Affiliate-Link)



    -alle verwendbaren 16 Pins am MCP23017 sollen grundsätzlich immer als output verwendet werden.


    Demnach definiere ich immer nach den Start des Raspi zuerst die Pins als output. Entweder über diesen Weg:

    Code
    1. i2cset -y 0 0x20 0x00 0x00

    oder bei Bedarf, für jeden Pin einzeln auch über diesen Weg (funktioniert beides).

    Code
    1. gpio -x mcp23017:100:0x20 mode 100 out

    Die Folge daraus ist, dass alle als output definierten Pins anschließend dafür sorgen, dass das jeweils angeschlossene Relais der Relaiskarte auf 1 schaltet.


    im Anschluss kann ich das am MCP23017 angeschlossene, entsprechende Relais über:

    Code
    1. gpio -x mcp23017:100:0x20 write 100 1
    Code
    1. gpio -x mcp23017:100:0x20 write 100 0

    beliebig oft an- bzw. ausschalten. Grundsätzlich eine gute Sache. Jetzt funktionieren aber die beiden letzten Befehle nur, wenn ich zuvor auch die Pins des MCP23017 wenigstens einmal nach start des Raspi als Ausgänge definiert habe.


    Das eigentliche Problem:

    Was ich wissen möchte, ob es eine Möglichkeit gibt, die Pins immer als Ausgänge zu definieren. D.h. auch wenn ich den Raspi ausschalte und vom Strom trenne, nach dem einschalten die Pins bereits als output definiert sind.

    Nochmal zur Vereinfachung: Es sollen quasi die Pins als output definiert werden, ohne das sich der Schaltzustand der Relais von 0 auf 1 ändert.


    Vorab, schonmal vielen Dank für die Hilfe :)

  • Hallo,


    was auf jeden Fall funktionieren wird ist, wenn du dir eine systemd Service Unit schreibst, welche beim Systemstart 1x ausgeführt wird und wiederum den Befehl / das Skript ausführt, dass alle Pins auf `out` setzt.


    Gruß, noisefloor

  • Es sollte ausreichend sein, wenn du in deinem Script eine __init__ Funktion schreibst

    und dann der Programmablauf folgt.

    Solange du dein den MCP nicht ansteuerst ist es relativ egal ist wie ob MCP konfiguriert ist


    wie gesagt, ich glaube nicht dass du das direkt beim Rpi Start definieren musst.

    es ist im Normalfall Sinnvoller das alles in einem Script zu lösen



    Es kann natürlich nen Unterschied machen, wenn du die Relais bei Boot direkt ein/bzw ausschalten willst

    Dann kannst du dir ein Script fertig machen,

    in dem du nur die Funktion __init__ ausführst und lässt das über cron regeln

    (das wäre mein Lösungsansatz)


    Code
    1. @reboot python /dein/pfad/zum/script/deinScript.py &

    damit wird dein python Script direkt nach dem boot/reboot ausgeführt

  • Hallo,


    Quote

    wie gesagt, ich glaube nicht dass du das direkt beim Rpi Start definieren musst.

    Muss nicht, aber wenn es immer so sein soll, wie der TE es sagt, dann ist es sinnvoller, weil's direkt automatisch gemacht wird.


    Quote

    in dem du nur die Funktion __init__ ausführst und lässt das über cron regeln

    Das ist aber im Vergleich zum Vorschlag von dreamshader oder mir extra umständlich. Zumal der Fall "poweroff" nicht abgedeckt ist.

    Abgesehen davon fehlt in deiner Crontab Zeile a) der absolute Pfad zum Python-Interpreter und b) ist das `&`am Ende überflüssig.


    Quote

    Es sollte ausreichend sein, wenn du in deinem Script eine __init__ Funktion schreibst

    Warum die beiden führenden und folgenden Underscores? Das ist hier sinnlos. Per Konvention nutzt man das für Methoden in Klassen, nicht für platte Funktionen. Da hast du wohl Durcheinander bzgl. Klassen und Funktionen.


    Dein Skript ist nicht lauffähig, die bekommst in Zeile 12 einen NameError. Mit dem oben gesagten solltes es dir aber leicht fallen, dass zu korrigieren.


    Gruß, noisefloor

    Edited once, last by noisefloor: Typo ().

  • Das ist aber im Vergleich zum Vorschlag von dreamshader oder mir extra umständlich. Zumal der Fall "poweroff" nicht abgedeckt ist.

    Abgesehen davon fehler in deiner Crontab Zeile a) der absolute Pfad zum Python-Interpreter und b) ist das `&`am Ende überflüssig.

    was genau ist da an dem Absoluten Pfad zum Script falsch? und ja das & ist überflüssig .. hab das aus meinen 'Notizen' aus meinen Crontabs falsch gepasted



    Warum die beiden führenden und folgenden Underscores? Das ist hier sinnlos. Per Konvention nutzt man das für Methoden in Klassen, nicht für platte Funktionen. Da hast du wohl Durcheinander bzgl. Klassen und Funktionen.

    Die Underscores .....das liegt an meinen schrägen Eselsbrücken in meinem Hirn und meiner eigenartigen Denkweise....

    Ja Sinnloss ist es.... Funktionieren tuts trotdem(;


    Danke dir. ich bin zuzwar mit Python/Linux schon recht gut vertraut, aber noch weit vom Pro entfernt.

    Da freu ich mich, wenn ich mal was dazulernen und bessere Lösungsansätze mir ansehen kann.

  • Hallo,


    Quote


    was genau ist da an dem Absoluten Pfad zum Script falsch

    Nichts. Habe ich auch nicht behauptet, dass das falsch ist. Les' nochmal, was ich geschrieben habe.


    Quote


    Ja Sinnloss ist es.... Funktionieren tuts trotdem

    Nein, tut's nicht - jedenfalls nicht in dem von dir gezeigen Code. Grund: siehe oben.


    Gruß, noisefloor

  • Nichts. Habe ich auch nicht behauptet, dass das falsch ist. Les' nochmal, was ich geschrieben habe.

    Dann meinst du den fehlenden Aboluten Pfad zum interpreter. ok

    aber der ist nicht unbedingt nötig



    Nein, tut's nicht - jedenfalls nicht in dem von dir gezeigen Code. Grund: siehe oben.

    wenn oben nochmal liest, wirst du merken,dass ich mich auf die underscores

    und nicht auf ein fehlerhaftes Script beziehe

  • Hallo,


    Quote

    aber der ist nicht unbedingt nötig

    Es gibt hier im Forum ca. 1 Mio Threads, warum Cronjobs und systemd Units nicht laufen. Grund Nr. 1: fehlende absolute Pfade.


    Sicherlich funktioniert vieles, wie auch die Underscores "irgendwann irgendwie dann doch so gerade noch". Das ist aber so kein Grund schlechten bis falsche Beispiele schön reden zu wollen. Es gibt zumn Raspi bergeweise veraltete / schlechte / falsche Codebeispiele und Tutorials. Da müssen wir hier im Forum wirklich nicht noch zu beitragen, dass die Anzahl weiter erhöht wird.


    Gruß, noisefloor

  • Ich bin deiner Meinung dass man schlechte oder falsche Beispiele nicht weiter verbreiten muss.

    Ich habe sauviele Foren gestöbert um Probleme unterschiedlicher Art Herr zu werden.


    Wenn man ein Problem für sich gelöst hat, dann benutzt man diese Lösung

    und wenn jemand anderes dieses Problem hat und man freundlich ist hilft man anderen bei der Problemlösung.


    Auch wenn sie schlecht und veraltet sind.


    Dem Lösungssuchenden ist doch nur wichtig dass es Funktioniert.

    besser natürlich wenn es gute und keine veralteten Beispiele sind.


    Nur woher sollst du als Lösungssuchender das wissen, wenn es überall veraltet/schlecht/ und falsch steht?


    Da wäre der folgerichtige Ansatz doch die Menschen darauf hinzuweisen, dass ihr Wissen veraltet ist.

    und im Sinne der konstruktiven Kritik gleich ein Aktuelles und richtiges Beispiel zu geben, damit der Lösungssuchende, sowie alle

    die dieses Forum stöbern evtl auch ohne einen Account zu haben genau wissen wie es geht, um dann das korrigierte Wissen zu verbreiten.


    Hat nur Vorteile, 1. fühlen sich weniger leute evtl angepisst, der Thread bleibt beim Thema und alle Wissen dann bescheid.

    und wenn das Thema nochmal woanders auftaucht kann jeder darauf verweisen.


    Fazit.

    Es wäre sehr freundlich wenn du dann mal einen Vollständig korrektes Beispiel zu meinem cron Eintrag bringst,

    denn ich weiss es ebend nicht besser, da ich es so falsch gelernt habe und mangels IT Menschen oder zumindest Menschen

    mit umfangreichen Wissen über IT etc. in meinem Privatem Umfeld kann ich es sonst auch nicht richtig lernen, wenn es

    keiner mir mal richtig zeigt.


    Ich kann verstehen wenn du da keine Lust zu hast.

    In diesem Falle würde ich nen neuen Thread machen mit Thema Cron und da können alle interressierten inklusive mir dann Rätzelraten

    was nun Richtig und gut ist, weil auch dort keiner ein richtiges Beispiel bringt.


    und so schließt sich der Kreis


    grüße Booxi

  • Das eigentliche Problem:

    Was ich wissen möchte, ob es eine Möglichkeit gibt, die Pins immer als Ausgänge zu definieren. D.h. auch wenn ich den Raspi ausschalte und vom Strom trenne, nach dem einschalten die Pins bereits als output definiert sind.

    Nochmal zur Vereinfachung: Es sollen quasi die Pins als output definiert werden, ohne das sich der Schaltzustand der Relais von 0 auf 1 ändert.

    Hallo Carusabag,


    zur Definition der Ausgänge hast Du hier viele Ideen bekommen, imho wird es jedoch so bleiben, dass die Relas erst mal (kurz) schalten - wenn Du nichts änderst. Alle mir bekannten Relaisplatinen sind low active, schalten also, wenn INx auf GND gezogen wird. Und genau das ist doch der Zustand beim Definieren der GPIO als Augang. Deshalb zieht ein Relais auf der Platine erstmal an. Abhilfe schafft, die Logik idalerweise in Hardware zu invertieren. Das geht ganz einfach durch die Verwendung eines Transistors bzw. des ULN2803, Beispiele gibts genug hier im Forum.


    Sollte ich mich geirrt haben und Dein Problem falsch identifiert, dann ignoriere den Beitrag einfach... (;


    Grüße, STF