Blaulicht mit while True Schleife?

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen,

    ich bin ein Einsteiger und versuche ein Blaulicht für ein Spielzeug umzusetzen:

    Anforderung:

    Taster drücken, Blaulicht blinkt dauerhaft, Taster erneut drücken, Blaulicht aus. So weit so gut, ich hab erstmal mit dem blinkenden Teil angefangen, jedoch ohne die Taster, und erstmal nur mal im PI laufen lassen.

    Mein Problem ist die WhileTrue Schleife, sie läuft ja endlos. Wenn ich auf Programmende drücke, kann es sein, dass die LED noch leuchtet. Nun wäre es galant, dass, wenn Abbruch gedrückt wird, die LED vorher ausgeht. Ist das möglich? Wie verhält es sich bei einem Taster, kann es da sein, dass die LED beim jetzigen Code ebenfalls auf "an" stehenbleibt? Falls ja, würde mir ja auch ein Begrenzung der Schleifenzahl nicht unbedingt etwas bringen, falls der Taster vor Beenden der Schleifenzahl gedrückt würde. Ich hoffe, mich nicht allzu missverständlich ausgedrückt zu haben. MfG

  • Der Ansatz über die Schleife mit zwei Sleeps ist nicht besonders elegant. Man kann das hinfrickeln, aber die Sleeps lassen den Pi die meiste Zeit gar nichts machen. Und das ist ja nicht der Sinn der Sache.

    Du kannst das Blinken über einen Timerinterrupt machen. Dann läuft im Hintergrund ein Zähler und der löst in regelmäßigen Abständen eine Routine aus, die die LED ein- und ausschaltet. Ist aber eigentlich nicht das passende Thema für die erste Beschäftigung mit Programmierung.

    Eine andere Möglichkeit ist überschaubarer und tuts auch:

    Das ist nur Pseudocode... also musst du halt korrekt umsetzen.

    Das Blinken erfolgt durch wiederholtes "Auf-die-Uhr-schauen". Dazwischen ist in der Schleife genügend Zeit, den Taster zu erkennen und dann die LED auszuschalten.

    Das ist nur ein erster Ansatz. Du wirst wahrscheinlich merken, wenn du den Taster zu lange drückst, wird die LED gleich wieder ausgeschaltet.... da muss man noch etwas basteln. Es gibt da viele Variationsmöglichkeiten. Das ist nur mal ein Anstatz für dich zum Rumprobieren - keineswegs perfekt.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Lernen wird er damit nicht viel. Lambda-Funktion für Einsteiger... da gehts doch wieder mehr drum, dass der Autor Bewunderung ernten will...

    Versetzt euch doch mal in die Leute rein... Der Fragesteller weiß kaum, wie ne Schleife funktioniert.. und ihr kommt mit Bergen von Funktionen eine Library, die ihm zwar die Arbeit abnehmen, die Erkenntnis aber auch.

    Aber schön, wenn sich die Platzhirsche hier dann gegenseitig beweihräuchern.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Hallo nochmal und vielen Dank. Insbesondere die toggle- Funktion klingt sehr interessant, auch wenn ich diese im Detail noch nicht ganz aus dem Code entschlüsseln kann, aber das ist Übungsfrage, habe derzeit leider nur das PI- Einsteigerbuch, da wird einiges an Grundlagenwissen m.E. sogar übersprungen oder nur rudimentär angesprochen.

    Hatte mir in der Zwischenzeit ein Provisorium für Wechselblaulicht erstellt, auch wenn das eher die "Holzhackermethode" ist. Werde mich nochmal mit den if- Abfragen während der Schleife intensiver beschäftigen....

  • Wenn du mal einfach in Zeile 6 und 7 nachgesehen hättest, wäre dir die auskommentierte Funktion aufgefallen.

    Angepasster Code:

    Code
    def blinken():
       led_blau.blink(0.5, 0.5)
    
    knopf.when_pressed = blinken
    # keine runden Klammern, da die Funktion übergeben werden soll.
    # Mit runde Klammern würde der Rückgabewert der Funktion zugewiesen
    # wenn kein return vorkommt, fügt der Interpreter ein implizites `return None` hinzu
    # d.h. Funktionen ohne return liefern ein `None` zurück


    Der Grund, wieso ich stattdessen ein lambda verwendet habe: Damit der Anwender nicht 100 Zeilen im Code scrollen muss.

    Bei ~10 Zeilen Code ist das egal, egal ist das aber nicht mehr, wenn man viele einfache Callbacks hat, die nur einmal verwendet werden.

    Hat den Vorteil, dass der Anwender nicht so viel scrollen muss und direkt sehen kann, was der Callback machen soll.

    Callbacks, die wiederverwendet werden, sollten als normale Funktionen geschrieben werden.

    Callbacks, die komplexer sind und z.B. Exception-Handling beinhalten müssen, müssen sowieso als Funktionen geschrieben werden.

    Die Abneigung gegen lambda kommt daher, da die anonyme Funktion für Sachen missbraucht wird, was den Code unleserlich macht.

    lambda Anfängern generell vorzuenthalten ist der falsche Weg. Der richtige Weg ist es, die ganz einfachen Sachen zu zeigen.

    2 Mal editiert, zuletzt von RestlessMud46765 (12. Juni 2022 um 17:09)

  • Hallo,

    da wird einiges an Grundlagenwissen m.E. sogar übersprungen

    wenn du die Programmiersprache lernen willst, dann könntest du das offizielle Tutorial dazu durcharbeiten:

    https://docs.python.org/3/tutorial/

    Wenn du etwas für eine bestimmte Anzahl machen willst, dann brauchst du eigentlich nicht unbedingt eine Dauerschleife, sondern du könntest eine Schleife verwenden, die eine bestimmte Anzahl an Durchläufen hat. In dem Fall wäre das eine for-Schleife mit der Funktion 'range'. Dadurch musst du selbst auch keinen Zähler mehr einabuen:

    'range(20)' gibt in jedem Durchgang von 0 beginnend die Zahl erhöht um eins zurück, bis 20 Durchläufe um sind. Die Zahl wird an einen Namen gebunden. In meinem Beispiel ist der Name, der Unterstrich. Das verdeutlicht dem Leser, dass mit der Nummer im Code nichts weiter passiert. Will man im Code mit der Nummer aber auch noch was machen, dann ersetzt man den Unterstrich durch einen sprechenden Namen und kann ihn dann verwenden.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Hallo nochmal,

    es ist immer wieder interessant, wie viele "Wege nach Rom führen".

    @ Dennis89: Danke für den Tip mit dem offiziellen Tutorial. So etwas hatte ich schon gesucht, in der Fülle des Netzes jedoch nicht gefunden.

    Ich habe noch eine Frage:

    Der Code läuft jetzt über einen PI400, in Thonny erstellt und mit einigen Funktionen aus der GPIO Zero Bibliothek.

    Später soll er auf einem PI Pico laufen.

    Es scheint so zu sein, dass dort (Micor Phython) z. Teil andere Begrifflichkeiten, für dieselben Bibliotheks- Funktionen vorhanden sind oder ist das schlichtweg falsch? Falls das korrekt wäre, müsste ich diese Begrifflichkeiten ja später noch übersetzen.

    Vielen Dank für eure Hilfe.

  • Hallo,

    'gpiozero' ist nicht in MicroPython verfügbar. Hier musst du mit 'machine' arbeiten.

    https://docs.micropython.org/en/latest/rp2/…l#pins-and-gpio

    MicroPython basiert auf der Syntax von Paython (3.4 glaube ich), also die Sprache wie du sie gelernt hast kannst du anwenden, es sind nur nicht alle Funktionen verfügbar. Da musst du dich dann etwas durch die Doku suchen.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Zitat

    Später soll er auf einem PI Pico laufen.

    So etwas Einfaches wie gpiozero gibt es für Micropython noch nicht.

    Das muss man "zu Fuß" machen, kann aber z.B. machine.Timer nutzen, der periodisch oder einmal einen Callback aufruft.

    Und manchmal stimmt die Doku nicht oder es gibt Abweichungen zwischen den einzelnen Ports.

    Beim RP2040 scheint es z.B. keinen Hardware-Timer zu geben, beim ESP32 aber schon

    Dafür hat der ESP32 z.B. keinen PIO.


    Hier eine Übersicht, welche Features von CPython mittlerweile von MicroPython unterstützt werden:

    http://docs.micropython.org/en/latest/genrst/index.html

    Die f-strings wurden z.B. erst mit Python 3.6 eingeführt, werden aber von MicroPython unterstützt.

    Viele Module aus der CPython Standard Biliothek fehlen, können aber bei micropython-libs beschafft werden.

    Der Fokus liegt auf Speicherplatzverbrauch und Geschwindigkeit.

  • Hallo,

    Später soll er auf einem PI Pico laufen.

    Programmierung eines Computers (wie dem Raspi) und eines Mikrocontrollers (wie dem RP2040) ist halt zweierlei, i.d.R. auch beim Programmieransatz - auch, wenn mit Python vs. MicroPython erstmal eine scheinbare Schnittmenge besteht.

    Ein Microcontroller macht genau _eine_ Sache, nämlich das Programm abarbeiten. Das Programm läuft in einer Dauerschleife und hat die CPU des Controllers für sich alleine.

    Ein Computer macht X Sachen gleichzeitig und das Betriebssystem bestimmt, wann dein Programm wie viel Rechenzeit bekommt. D.h. hier will man das Programm i.d.R. _nicht_ in einem "busy loop" laufen lassen, weil es a) ggf. den gesamten Rechner ausbremst und b) dafür ggf. nicht genug Rechenzeit bekommt.

    Um die Grundlagen der Programmierung (mit Python) zu lernen ist IMHO ein Rechner schon besser / einfacher. Was aber nicht heißt, dass das, was du am Rechner programmierst, genau so auf dem Mikrocontroller läuft. Bei Mikrocontrollern kommt man i.d.R. auch nicht umhin, sich zumindest mal kurz mit den spezifischen Eigenschaften der Hardware und der CPU zu beschäftigen.

    Gruß, noisefloor

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!