Fehlermeldung in Python (GPIO in use)

  • Hallo zusammen ...

    ... mein erster Beitrag bei Euch ... und schon direkt die Anfrage nach Hilfe :)


    Leider hat die Nutzung der SuFu im Forum noch keine Klärung gebracht.


    Zu mir ... :

    Ich bin Informatiker, 58, alter Linuxer und beschäftige mich seit kurzem mit dem Raspberry (4B) und Python auf Beginner-Level. Ich bin da im Netz auf diverse Anfänger-Tutorials gestoßen die einen step-by-step durch die Anfänge führen ... ihr kennt die Links sicher in und auswendig.

    Begonnen habe ich mit dem Klassiker "LED on/off". Das ursprüngliche Script läuft auch absolut perfekt durch ... und - so wie der Spaß eben mit den kleinen Erfolgen kommt - habe ich das Script auf drei LEDs erweitert und dann mit einigen Snippets aus dem Netz erweitert.


    Das Problem ... :

    Auch meine Erweiterung zeigte - nach einigen anfänglichen Fehlern, die Kraft Netzrecherche behoben werden konnten - Erfolge ... alles lief gut durch. Nur wird mir zum Ende eine Fehlermeldung gezeigt, die ich nicht nachvollziehen kann. Außerdem wird auf eine Zeile in einer offiziellen Datei verwiesen, die ja eigentlich fehlerfrei sein müsste, aber wohl durch mein Script ein Interpretationsproblem hat. Und ... das - wie gesagt - verstehe ich nicht.

    Mein "Patchwork"-Script:


    Und hier die Fehlermeldung:

    Ich benutze auf dem Raspberry https://thonny.org/Thonny ... der mir als IDE für Python-Anfänger empfohlen wurde und bis jetzt auch sehr hilfreich war. (Falls bessere Vorschläge verfügbar sind ... ich bin da ganz Ohr).


    Ich habe die Datei, auf die Python in seiner Fehlermeldung referenziert, mal angehängt (ich wollte sie, wegen ihres Umfanges, nicht auch noch einfügen).

    Meine Fragen sind:

    Warum tritt die Fehlermeldung auf?
    Der GPIO (17) ist doch korrekt addressiert und wird auch wieder abgeschaltet ... die Ansprache der LEDs funktioniert auch.

    Was sagt die Fehlermeldung im zweiten Teil (also dem Verweis auf die Zeilen in der _init_.py) aus und ... warum tritt auch diese auf?

    Und ... wie kann ich sie (beide) verhindern? :)

    Vorab schon mal Danke für die Hilfe ...

    Gruß

    Stefan

  • Nimm die Zuweisungen

    Code
    led17 = gpiozero.LED(17)

    und die anderen (Zeile 10,18,26 , 42,43,44) aus der while Schleife und setzte die vor das while True in Zeile 6.

    Mit dieser Anweisung deklariert du den Pin als Ausgang für LEDs (vereinfacht gesagt), , da der Pin aber schon als Ausgang deklaiert ist vom voherigen Durchlauf , gibts die Fehlermeldung.

  • Hi Bertthias ...

    Hab ich umgesetzt (wenn ich Dich richtig verstanden habe):


    Und trotzdem kommt die Fehlermeldung:

    Entweder habe ich Deinen Vorschlag falsch verstanden (und umgesetzt) ... oder DAS ... war's dann nich *g

    Greetz
    Stefan

    Alter Linuxer, Raspi- und Python-Newbie mit hoher Netzaffinität ... und immer bereit, was Neues zu probieren und zu lernen.

    • Official Post

    Ein möglicher Ansatz: Du befindest Dich in einer Schleife, demnach ist das Ende der Schleife auch der Anfang.


    In Zeile 56 öffnest Du LEDBoard(), schließt das aber nicht wieder, bevor Du LED() in Zeile 10 öffnest. Beide Zeilen sind auf das Skript in Beitrag #1 bezogen.

  • Ich hab in der Zwischenzeit (und jetzt ist mein Essen wieder kalt *g) das Script in Abschnitten in ein neues kopiert und den ersten Abschnitt mal laufen lassen ....:



    Deine Annahme war richtig.

    Das Statement "led17.close()" hat die Fehlermeldung hervorgerufen. Da ich am Ende die Variable schließe (so meine Erklärung), die Deklaration aber vor der Schleife kommt, kann er mit der nachfolgenden Bedingung "on" nichts anfangen ...

    Als ich die "close"-Anweisungen auskommentiert hatte, lief dieser Teil des Scripts einwandfrei durch ...

    Alter Linuxer, Raspi- und Python-Newbie mit hoher Netzaffinität ... und immer bereit, was Neues zu probieren und zu lernen.

  • Hallo Stefan ,

    Zeile 8 und Zeile 11 in Beitrag#3 sprechen beiden denselben Ausgangs Pin an.

    Das steht in der Fehlermeldung Zeile 4 & 5 , der Rest der Meldung sind Folgemeldungen.

    Du kannst nicht einen AusgangsPin mit zwei verschieden Fuktionen belegen ohne diese vorher zu schliesen.


    Du musst auch bei Listing 1 aus Beitrag#1 nach Zeile 57 alle LEDs wieder mit Close schliesen.

  • Hallo,


    zum Thema 'close' findet man in der Doku diese Beschreibung:

    Shut down the device and release all associated resources (such as GPIO pins).

    This method is idempotent (can be called on an already closed device without any side-effects). It is primarily intended for interactive use at the command line. It disables the device and releases its pin(s) for use by another device.

    You can attempt to do this simply by deleting an object, but unless you’ve cleaned up all references to the object this may not work (even if you’ve cleaned up all references, there’s still no guarantee the garbage collector will actually delete the object at that point). By contrast, the close method provides a means of ensuring that the object is shut down.

    For example, if you have a breadboard with a buzzer connected to pin 16, but then wish to attach an LED instead:


    Ich kann mir auf die Schnelle keinen sinnvollen Einsatz dafür vorstellen. Ich habe die LED an einem Pin angeschlossen und während des Programmablaufs schließe ich an den Pin auch nichts anderes an. Wie beschrieben, zum "spielen" oder experimentieren kann es hilfreich sein.


    Grüße

    Dennis

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

  • So ....


    ... offensichtlich muss man erst mal was essen, damit alles klappt.


    Der neue - und nun fehlerfreie - Code:

    Das Problem war wirklich, dass ich einmal die Deklaration außerhalb der Schleife legte ... und damit im zweiten Durchlauf (nach den "close()"-Bedingungen) Python nicht mehr wusste, was eine led ist.

    Ich habe nun also die Deklaration an den Anfang gelegt und - auch hier dem Ratschlag folgend - nach den "close()"-Bedingungen der ersten Deklaration die zweite (mit dem Powermanagement) folgen lassen, bevor der Dimm-Prozess begann.


    Ergebnis:

    Die LEDs schalten jetzt in der Reihenfolge ... rot --> gelb --> grün --> alle aus ... und dimmen danach zusammen von 0 --> 100 auf.


    Nach dem ersten Durchlauf stellte ich fest, das der zweite Durchlauf nicht mit der Aufblinken der roten LED begann (wie er programmgemäß sollte und wie auch der erste begann), sondern mit der gelben. Ich bin dann das Script in Einzelschritten im Debugmodus durchgelaufen und konnte keinen Fehler feststellen. (Anfängerfehler: Ich hätte den Schleifenzähler vorher von 100 auf 10 setzen sollen ... X/ )


    Ich dachte mir, das die Anweisung "pwmledred.close()" wohl noch nicht korrekt abgearbeitet wurde (es kam aber auch keine Fehlermeldung) und verpasste dem Script am Ende eine Denkpause von einer Sekunde.

    Jetzt startet das Script auch korrekt mit der roten LED und läuft durch bis zum Sankt Nimmerleins-Tag.

    Danke für Eure Tipps und Anregungen.

    Greetz

    Stefan


    P.S. hyle : Ich werde im nächsten Schritt Deinen Hinweis mit dem pauschalen close testen ... hier war es mir sehr lehrreich, alle Schritte im einzelnen zu begreifen.

    Alter Linuxer, Raspi- und Python-Newbie mit hoher Netzaffinität ... und immer bereit, was Neues zu probieren und zu lernen.

  • Hallo,Dennis

    Ich kann mir auf die Schnelle keinen sinnvollen Einsatz dafür vorstellen. Ich habe die LED an einem Pin angeschlossen und während des Programmablaufs schließe ich an den Pin auch nichts anderes an. Wie beschrieben, zum "spielen" oder experimentieren kann es hilfreich sein.

    Grüße

    Dennis


    Genau in der Phase bin ich noch ... ich probiere, teste und versuche Python mit praktischer Anwendung zu lernen.


    Die Gpiozero-Dokumentation habe ich mir auch gebookmarked (und daraus auch das Grundgerüst meines Ursprungscripts übernommen). Sehr hilfreich und anspornend.


    Grüße

    Stefan

    Alter Linuxer, Raspi- und Python-Newbie mit hoher Netzaffinität ... und immer bereit, was Neues zu probieren und zu lernen.

  • Isegrimm_666 Noch Anmerkungen zum Code: Man sollte weder Code noch Daten wiederholen. Die Pin-Nummern stehen beispielsweise mehrfach im Quelltext, sowohl im Code als auch in einem Kommentar. Wenn man die mal ändern will/muss, dann muss man sie mehrfach ändern und dabei besteht die Gefahr, dass man nicht alle vorkommen erwischt oder nicht alle gleichartig ändert.


    Im ersten Teil steht im Grunde dreimal der gleiche Code, nur mit einer anderen LED. Das kann man mit einer Schleife ohne die Code-Kopien schreiben.


    Die LED/PWMLED Objekte sind „context manager“, dass heisst man kann die mit der ``with``-Anweisung verwenden um den Lebenszyklus etwas sicherer zu steuern.


    Alles zusammen kann dann so aussehen (ungetestet):

    Allerdings ist es überhaupt nicht nötig die gleichen Pin-Nummern hier in verschiedene Objekte zu verpacken, weil `PWMLED`\s auch `on()`- und `off()`-Methoden kennen. Ungetestet:

    “If debugging is the process of removing software bugs, then programming must be the process of putting them in.” — Edsger Dijkstra