µPython Object-Klasse für eine 2 Pin DUO LED

  • Hallo,


    Ich versuche mir gerade eine Class in µPython für eine DUO LED zusammenzubasteln.
    Die Pins werden bei der Initiierung via einer LIST übergeben.
    Soweit funktiont das schon einmal sehr gut.
    Nun würde ich noch eine BLINK Funktion ergänzen. Leider fehlt mir hier jede Idee wie.
    Gibt es eine Möglichkeit das ganze ohne einen Thread zu machen ?
    Ich muss mir den zweiten Core für eine andere Sache freihalten. Bis jetzt ist es mir auch noch nicht gelungen das man neben dem Hauptprogramm selber mehrere Threads "parallel" starten und ausführen kann.


    Danke

    Steffen.

  • Hallo,


    Nun würde ich noch eine BLINK Funktion ergänzen. Leider fehlt mir hier jede Idee wie.

    fehlt dir die Idee, weil du so viele Sachen auf ein mal ausführen willst oder weil du nicht weist wie du dafür sorgen sollst, das ein Pin an der DUOLED aus ist und ein anderer an und sich das Spiel dann abwechselt?


    Wenn ersteres, dann wäre interessant was du da genau machen willst.


    Deine Klasse wie du sie hier gepostet hat macht für mich, ohne Hintergrundwissen, nicht wirklich Sinn. 'LED1_OFF' da wird alles ausgeschalten und 'self.on' wird false gesetzt, in 'LED2_OFF' das gleiche Spiel und in 'OFF' dann auch. Nur dass da 'self.on' nicht geändert wird. Das sind zwei Funktionen zu viel. 'OFF' würde reichen und der Funktion einfach den Statuswechsel der Flag hinzufügen.

    Ich verstehe auch nicht wieso erst alle LEDs ausgeschaltet werden und dann eins von beiden wieder an, da würde es reichen, eine einfach auszuschalten?

    Funktionen schreibt man übrigends klein_mit_unterstrich. Ich würde das auch als eine LED behandeln und die Pins vermutlich in einer Liste behalten und daraus die Werte setzen, ob da jetzt pin1 oder pin2 oder eine Liste(oder sonst eine sinnvolle Struktur) das beide beinhaltet, bringt meiner Meinung nach keinen wirklichen Vorteil. Naja das nur nebenbei.


    Grüße

    Dennis


    Edit: Stammt die Klasse aus einem Python2 Tutorial? 'Object' muss nicht mehr übergeben werden, es reicht class DUO_LED. Es sei denn da ist noch was bei dir, von dem ich nichts weis.

    “Ich benötige Informationen. Eine Meinung bilde ich mir selbst.”

  • Hallo,


    so das ist mein bisheriges Ergebnis:

    Bis auf den letzten Satz das die eine LED dann in der anderen Richtung leuchten soll, klappt das. Nur der letzte Satz / Zeile für nicht dazu, dass die LED in der gleichen Polarität eingeschaltet bleibt.
    Beide LEDs sind dann aus

    Steffen.

  • Ich würde es mit Timer machen, sofern kein uasyncio verwendet wird.

    Habe noch ganz vergessen, wieso keine Threads verwendet werden sollten.

    Der ESP32 kann soweit ich weiß nur 2 Threads starten. Das ist auch von Port zu Port unterschiedlich.


    Hier für Timer:

    Der Nachteil ist, dass der ESP32 keine virtuellen Timer unterstützt und man kann nicht Hardware-Timer mit gleicher ID verwenden.

    Hier habe ich z.B. Timer-ID 10 verwendet, um die rote LED 1000 ms später zu starten.


    Async-Code für uasyncio:


    Da auch Webserver und Co nebenläufig sein (asynchron), kann man diesen Code gut mixen.

    Der Nachteil ist, dass man dafür asyncio verstehen muss. Coroutinen entstehen, wenn man Funktionen aufruft, vor denen async def steht.

    Eine Coroutine kann mit asyncio.create_task(coroutine) im Hintergrund ausgeführt werden (nebenläufg).

    Mit dem Schlüsselwort await kann man innerhalb einer Coroutine auf eine andere Coroutine warten.


    Hier geht es zur Doku: https://docs.micropython.org/en/latest/library/uasyncio.html

  • Hallo DeaD_EyE,


    Danke erst einmal für diese tollen Beispiele.

    Wie du richtig erkannt oder vermutet hast soll auch noch ein WEB-Server aktiv werden.
    Das heißt nun wenn ich das richtig verstanden habe, muss ich das dann mit diesem uasyncio machen ?
    Noch habe ich keinen Ansatz wie ich das alles miteinander verknüpfen kann.
    Das eigentliche Programm, dann im Abschluss soll einen auf dem ESP32 im Flash gespeicherten Text, = Text-Datei entweder über Tastendruck auf dem Board, oder via dieses Web-Servers als fortlaufender "Lauftext" dargestellt werden, und an jeder x beliebigen Stelle wieder gestoppt werden können. Mit dem Stopp, erfolgt ein interenes Reset, so das beim nächsten Start der Text wieder von vorne angezeigt werden soll. Aber soweit bin ich noch lange nicht.

    Steffen.

  • Hallo

    Das war der Stand den heute, bevor ich deinen DeaD_EyE Message gelesen hatte. Hier ist wohl noch ein entweder Ausführungsfehler , oder es ist ein Hardware Phänomen, dass bei CrossBlink, die erste Farbe einfach mal nur extrem jurz aufblitzt, dann aber regulär weiter macht. Das geht einige Durchläufe gut, dann wird wieder und immer nur die erste Farbe fast verschuckt.

    Steffen.

  • Hallo,


    eigentlich verwendet man die _thread Klasse nicht, die ist für den internen Gebrauch, wie durch den führenden Unterstrich gekennzeichnet. Jedenfalls in CPython. In Micropython ist die _thread Klasse als (sehr) experimentell gekennzeichnet... und wie oben schon angemerkt wurde ist die Anzahl der Threads beim ESP32 wohl limitiert, weswegen Threading nicht der Weg sein dürfte. Zumal du, wenn der ESP32 wirklich mit Micropython nur 2 Threads kann, nicht hinkommst, weil den Programm der 1. Thread ist, das Blinken der 2. - und für den Webserver bräuchtest du einen 3. Thread.


    Wenn du mehrere Sachen gleichzeitig machen willst musst du dich zwangsläufig mit nebenläufiger Programmierung beschäftigen. Also allgemein Threads, Multiprocessing oder asyncio, was sich bei Micropython dann effektiv auf asyncio beschränkt.


    Was IMHO der komplexeste Ansatz ist, weil das Programm nicht mehr linear durchläuft, was es schwieriger macht, sich das alles vorzustellen. Oder anders: asyncio ist nicht unbedingt ein Thema für Einsteiger oder fortgeschrittene Einsteiger. Was halt noch dazu kommt ist, dass man mit Micropython den Webserver selber relativ "low level" implenentieren muss, was eine zusätzlich Komplexitätsschicht einzieht.


    Das geht sicherlich alles, wenn du genug Zeit und Motivation hast, das alle zu lernen. Wobei das als 1. Kontakt mit asyncio schon ziemlich harter Stoff ist.


    Gruß, noisefloor

  • Dieser Webserver ist nicht ganz so low-level:

    https://github.com/jczic/MicroWebSrv2




    Soweit ich weiß, sind die Threads immer noch experimentell. Sie werden aber teilweise in Bibliotheken genutzt.



    Etwas leichtgewichtiger ist dieser Webserver: https://github.com/belyalov/tinyweb

  • Hallo

    eigentlich verwendet man die _thread Klasse nicht, die ist für den internen Gebrauch, wie durch den führenden Unterstrich gekennzeichnet. Jedenfalls in CPython. In Micropython ist die _thread Klasse als (sehr) experimentell gekennzeichnet... und wie oben schon angemerkt wurde ist die Anzahl der Threads beim ESP32 wohl limitiert, weswegen Threading nicht der Weg sein dürfte. Zumal du, wenn der ESP32 wirklich mit Micropython nur 2 Threads kann, nicht hinkommst, weil den Programm der 1. Thread ist, das Blinken der 2. - und für den Webserver bräuchtest du einen 3. Thread.

    Nun bin ich erst einmal total verwirrt.
    Ausgehend von deinem letzten Satz, das Hauptprogramm welches die, ich nenne es mal SUB-Threads startet wäre ein eigener Thread. Ok, kann sein - weiß ich nicht besser oder anderes.
    Jetzt habe ich in meinem Testprogramm 2 LEDs jeweils über eine eigene Klassenzuweisung, beide LEDs sind DUO_LED - Objekte. Diese können miteinander und vollständig unanhängig von einander vor sich hinblinken. Also wären das nochmal 2 Sub-Threads !? Nun habe ich spasseshalber mal noch I2C LCD 16x2 Display angeschlossen, auf welchem die interne Zeit dargestellt werden soll. Das ganze im Hauptprogrammteil mit einer For -Schleife ausgeführt, dass diese Darstellung zeitlich begrenzt wird, bevor ich die beiden LEDs wieder mit anderen Konfigurationseinstellungen bespiele. Damit, wenn deine Aussage stimmt, kann das ESP32 sofern der Hauptprogrammteil als Thread anzusehen ist, mit 3 Threads, davon 2 SUB Threads umgehen. Dazu habe ich noch die Version auf 1.19.1 vom 2022-06-18 aufgespielt.

    Jetzt noch eine Verständnisfrage an DeaD_EyE.
    Ich hatte in dem Link auf #5 eine andere Methode für eine Webdarstellung verwiesen. Das wie aus dem Tutorial funktioniert das auch soweit. Was ist nun der Unterschied auch bezüglich des von dir in #8 genannten Webservers, wenn du schon selber schreibst, dem ESP32 geht bei Zeiten der RAM aus ?
    Ich brauche ca. 2000 Char / Zeichen um den schlußendlich darzustellenden Text auf dem Display anzeigen zu können. Diesen, jetzt auch wieder Standalone, lese ich am Anfangs aus einer Datei ein, bereinige ihn von Umlauten und habe einen schönen langen STRING. Diese Größe muss ich somit von meinem RAM abrechnen, oder er muss frei bleiben. Wie bekomme ich überhaupt heraus, wie viel freien RAM ich überhaupt noch zur Verfügung habe.


    Danke euch beiden.
    Jetzt muss ich wieder was für meine Brötchen machen. Vielleicht sehe ich heute Abend nochmal rein.

    :danke_ATDE:

    Steffen.

  • Ich hatte in dem Link auf #5 eine andere Methode für eine Webdarstellung verwiesen. Das wie aus dem Tutorial funktioniert das auch soweit. Was ist nun der Unterschied auch bezüglich des von dir in #8 genannten Webservers, wenn du schon selber schreibst, dem ESP32 geht bei Zeiten der RAM aus ?


    Das aus #5 ist eine eigene Implementierung mit Funktionen. Da hat man natürlich größte Flexibilität, muss aber alles selbst machen.

    Bei #8 sind fertige Frameworks verlinkt. Dort ist der meiste Low-Level-Code versteckt. Unter anderem kann MicroWebSrv2 HTML-Templates verarbeiten.

    Falls du den verwenden solltest, kannst du ohnehin nicht mit Threads arbeiten (einer wird von MicroWebSrv2 verwendet). Den zweiten kleineren Webserver habe ich bis jetzt noch nicht getestet. Der RAM geht ihm aus, wenn man nicht die Stack-Größe verkleinert (SetEmbeddedConfig).


    Ich brauche ca. 2000 Char / Zeichen um den schlußendlich darzustellenden Text auf dem Display anzeigen zu können. Diesen, jetzt auch wieder Standalone, lese ich am Anfangs aus einer Datei ein, bereinige ihn von Umlauten und habe einen schönen langen STRING. Diese Größe muss ich somit von meinem RAM abrechnen, oder er muss frei bleiben.

    Ja, genau das ist größte Problem. Ich habe nicht in den gesamten Code gesehen, kann mir aber gut vorstellen, dass z.B. die Templates bei MicroWebSrv2 iterativ verarbeitet werden. D.h. es wird immer nur ein Teil geschickt und dann der nächste usw...


    Für den Test habe ich einfach dieses Template genommen: https://github.com/jczic/Micro…lob/master/www/index.html

    1720 Zeichen lang. Die index.html beinhaltet keine Objekte, die durch Micropython nachträglich eingefügt werden.

    Das war auf einem ESP32 WROOM, also der ohne SPIRAM. Die mit SPIRAM haben 4 oder 8 MiB. Es gibt aber auch welche mit mehr (teuer).


    Hier ein Template mit Variablen: https://github.com/jczic/Micro…ob/master/www/test.pyhtml

    Hier sind die Möglichkeiten der Templating-Engine beschrieben (ist von jinja2 abgeleitet): https://github.com/jczic/MicroWebSrv2#pyhtmltemplate-mod



    Wie bekomme ich überhaupt heraus, wie viel freien RAM ich überhaupt noch zur Verfügung habe.

    https://docs.micropython.org/e…brary/gc.html#gc.mem_free

    Code
    import gc
    
    
    print(gc.mem_free())
  • Hallo,


    Quote

    ..., mit 3 Threads, davon 2 SUB Threads umgehen.

    Bitte nichts erfinden. Es gibt kein "sub Threads". Es gibt Threads. Punkt. Wenn ein Thread aus einem anderen Thread heraus gestartet wird ist es ein Thread. Punkt.
    Ob der ESP32 wirklich nur 2 Threads kann habe ich nicht überprüft - aber ich habe da Vertrauen in die Aussage von DeaD_EyE:)


    https://github.com/belyalov/tinyweb setzt auch auf asyncio und da ist in der Doku auch gesagt (siehe Erklärung zur `run` Methode), dass sich andere Tasks in den Eventloop von asycnio, den die run-Methode startet, ziemlich einfach einbinden lassen.


    Musst du eigentlich einen Mikrocontroller nehmen? Das Brett, was du bohren willst, ist schon ziemlich dick. Das wäre z.B. mit einem Raspi Pi Zero W um Längen einfacher.


    Gruß, noisefloor

  • Hallo zusammen,


    seit wann braucht man zum Setzen eines GPIO einen Thread???


    Ich würde das ganze Projekt als State Machine programmieren. In der Endlosschleife bleibt genug Zeit, mit welchem Server auch immer zu kommunizieren.


    Jeder Zustand löst eine andere Aktion aus, die immer nur darin besteht, einen GPIO in dem einen Zustand mal ein und in einem anderen Zustand mal auszuschalten oder einen Textausschnitt irgendwo hinzuschreiben. Es sind der Phantasie (= Anzahl der Zustände) keinerlei Grenzen gesetzt.


    Dazu braucht man auch keine Klassen oder externe Libraries - oder sich damit auseinanderzusetzen.



    Beste Grüsse


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Ob der ESP32 wirklich nur 2 Threads kann habe ich nicht überprüft - aber ich habe da Vertrauen in die Aussage von DeaD_EyE :)

    Genau andersherum :D

    Gut, dass ich nochmal getestet habe. Bei so vielen Controllern kommt man manchmal durcheinander.


    Die ESP können mehr als einen zusätzlichen Thread. Das Hauptprogramm läuft ja bereits in einem Thread.

    Jeder Thread verbraucht Speicher. Deswegen kann der ESP32 mit SPIRAM (4 MiB habe ich) auch mehr Threads starten.

    Dennoch, die Threads sind nicht unbedingt eine gute Lösung für Nebenläufigkeit.


    Die RP2040 können nur einen weiteren Thread starten.



    Quote from ESP32 module (spiram) with ESP32

    Auf dem ESP32 module (spiram) with ESP32 sind nur 17 Threads möglich


    Quote from ESP32 module with ESP32

    Auf dem ESP32 module with ESP32 sind nur 6 Threads möglich


    Quote from Raspberry Pi Pico with RP2040

    Auf dem Raspberry Pi Pico with RP2040 sind nur 1 Threads möglich


    Quote from Raspberry Pi Pico W with RP2040

    Auf dem Raspberry Pi Pico W with RP2040 sind nur 1 Threads möglich

  • Ich würde das ganze Projekt als State Machine programmieren. In der Endlosschleife bleibt genug Zeit, mit welchem Server auch immer zu kommunizieren.

    Dann bitte Beispiele für Micropython posten, aber bevor du das machst, hier eine Aussage von einem der Entwickler: https://forum.micropython.org/viewtopic.php?p=69390#p69390



    Aber auf die State Machine bin ich sehr gespannt.

    Hint: Sockets müssen non-blocking sein und select.select muss verwendet werden.

  • Hallo,


    Quote

    seit wann braucht man zum Setzen eines GPIO einen Thread???

    Nee, natürlich nicht. Es geht hier auch um's Blinken - was man halt mit Micropython selber implementieren muss. Auf dem Raspi in Kombination mit dem gpiozero Modul gibt es dafür eine Methode (die AFAIK eine Thread dafür startet :) ).
    Bei Micropython ist dafür das besagte uasyncio eine gute Wahl (ohne zusätzliche Threds), weil dass, was der TE vorhat, IO-Bound ist. Und asyncio ist ja schon eine Abstraktionsschicht auf mittlerem Level, die die low-level Implementierung darunter verbirgt.
    Man kann das sicher auch anders machen und tiefer ansetzen. Bzw. mit anderen Sprache muss man ggf. tiefer ansetzen. Aber du weißt ja, die Python Fasnboys stehen voll aus High-Level APIs und Implementierung :)


    Gruß, noisefloor

  • Aber du weißt ja, die Python Fasnboys stehen voll aus High-Level APIs und Implementierung

    Genau deswegen verwenden wir doch Python :)


    Ich habe mich z.B. zuerst mich mit den High-Level-APIs beschäftigt und dann mit den Low-Level-APIS weitergemacht.

    So habe ich einmal die komplette Abstraktion durch. Egel wie herum man das macht, es hilft jedenfalls C und Python besser zu verstehen.

  • Hallo in die Runde,

    Musst du eigentlich einen Mikrocontroller nehmen? Das Brett, was du bohren willst, ist schon ziemlich dick. Das wäre z.B. mit einem Raspi Pi Zero W um Längen einfacher.

    Er ist da, und ich kann das Brett auch dünner machen ;)
    Ja diese Duo-Leds wltte ich nur beim Einschalten einsetzen um eine visualisierung zu ermöglichen, bis das System hochgefahren ist und sich mit dem voreingestellten WLAN Router verbunden hat, Dann wird eigentlich weder der PWM- noch der Blink Modus bemötigt.
    Also ließe sich das ganze in Verbindung mit dem darzustellenden Lauftext, auf die Taster Abfrage und die Interaktion mit der Webseite auf dem eigenen WEB-Server beschränken.


    Ich würde das ganze Projekt als State Machine programmieren.

    Gut gehen wir mal davon aus das sich das so umsetzen lassen würde.
    Die WLAN Verbindung ist hergestellt. Das wären dann wohl die Startbedingungen.
    Damit müsste als Aufgaben folgendes stehen bleiben ?
    - Webzugriff 2 Button + ein Schiebschalter. Der Schiebeschalter differnziert zwischen einmaligem Durchlauf und einer Endlosschleife in der Textdarstellung auf dem Display.
    - Der WEB-Start-Button wie auch ein Druck auf den physikalischen Taster würde die Darstellung starten.

    - hier jetzt die Besonderheit, es gibt nur einen physikalischen Start-Stopp-Taster.
    - Der Web-Stopp-Button wie auch die erneute Tasterbetätigung würden die Darstellung anhalten, das Display löschen, und die Darstellungsposition / Cursorposition im Anzeigetext auf den Anfang setzen.
    - Zudem müsste über diese Webseite dargestellt / angezeigt werden ob gerade eine Darstellung aktiv ist.
    - Hier auch wieder die Besonderheit, der Schieberegler auf der Webseite darf nur aktiv sein, wenn gerade keine Textdarstellung stattfindet.
    - Und zum Schluß noch der SETUP Modus, via ADC Abfrage eines Potis mit Displaydarstellung, welche Lauftextgeschwindigkeit bzw Fortschaltzeit vorgewählt werden kann.

    Wie soll man das in eine State Machine umsetzen, wenn du sagst es gibt so viel Leerlaufzeit ?

    Steffen.

  • Hallo,


    Quote

    Webzugriff 2 Button + ein Schiebschalter.

    Schiebeschalter = ein virtueller Slider auf Webseite, richtig? Muss die Hardware auf dem ESP32 "live" auf den Slider reagieren können, z.B. um Text auf dem Display live vor- und zurück scrollen zu können?


    Gruß, noisefloor

  • Hallo,

    Schiebeschalter = ein virtueller Slider auf Webseite, richtig? Muss die Hardware auf dem ESP32 "live" auf den Slider reagieren können, z.B. um Text auf dem Display live vor- und zurück scrollen zu können?

    Ich hatte das zwar schon ausgefhrt aber hier noch einmal im Detail, was sich auf dem "bisschen" Webseite abbspielen soll.

    Wenn das System gestartet ist, also auch diese Webseite abgerufen werden kann, ist der Startzustand:
    2 Butten, eine rfür Start einer für Stopp. Eine kleine Statusmeldungszeile wo steht das gerade nichts passiert ;) ZB Stopp oder so etwas.
    Dazu noch eine Schieberegeler der je nach Stellung rechts oder links die Meldung weite rgibt, dass der Text nur einmal dargestellt werden soll, und dann die Wiedergabe der Displaydarstellung automatisch beendet wird. Die andere Seite heist, der Text soll als Endlosschleife durchlaufen.

    Wenn du die Darstellung egal in welchen der Beiden Modi gestartet ist soll das in der Statuszeile erscheinen, und der Schieberegler, wie nennt man das ausgegraut werden, also funktionslos sein.
    Nur wenn das System sich in Status Stopp oder Angehalten befindet, soll auch der Schieberegler aktiv werden. Mit der Darstellungsrichtung hat der überhaupt nichts zu tun.
    Ob nun auch noch der jeweilig aktive Button auch ausgegraut wird ist eigentlich nur schmückendes Beiwerk aber nicht wirklich wichtig. Wenn die Darstellung schon läuft, dann ändert ein erneuter Druck / Bedienung des PlayButtons auf der Webseite auch nicht. Diese informationsrückmeldung kann sozusagen ignoriert werden. Genauso wenn das System mit keiner Darstellung beschäftigt isthat der Stopp Button auf der Web-Seite auch keine Funktion. Wie schon gesagt, ob man das noch mit unter-vergrauen deutlich macht, wäre schmückendes Beiwerk, was aber nicht wirklich notwendig wäre.

    Steffen.

  • Hallo,


    beantwortet nicht so richtig die eigentlich Frage, aber egal. Wo ich drauf hinaus will: wenn du serverseitig "live" auf den Schieberegler reagieren willst (also wenn das "on change" Event des Reglers feuert und du durch das Event einen Request an den Server sendest (z.B. via fetch-API, dann solltest du jetzt mal testen, also bevor du tiefer in die Umsetzung einsteigst, ob der Server überhaupt so schnell die Requests sinnvoll verarbeiten kann. Wenn du nur die Endlagen brauchst und nichts dazwischen, dann würde ich eher einen Radiobutton oder eine Checkbox nehmen, mit der du zwischen "Endlos ja/nein" hin- und her schalten kannst.


    Gruß, noisefloor