Ja genau, das mache ich auch in separaten Funktionen.
Das Problem ist wie komme ich mit 'pruefe_ir_eingabe()' an den Informationen ran welche Taste gedrückt wurde?
Funktion beenden
Das glaube ich nicht, dass du das in separaten Funktionen machst. Bitte zeige deinen Code.
Ein Weg ist eine collections.dequeue, die du im callback mit eingehenden Werten fuellst. ABER ACHTUNG: die Werte rauslesen darfst du nur mit einem kurzzeitig disableten IRQ, siehe https://docs.micropython.org/en/latest/ ... -functions
Ein Weg ist eine collections.dequeue, die du im callback mit eingehenden Werten fuellst. ABER ACHTUNG: die Werte rauslesen darfst du nur mit einem kurzzeitig disableten IRQ, siehe https://docs.micropython.org/en/latest/ ... -functions
Du denkst, du brauchst eine While-True Schleife, um bestimmte Ziele zu erreichen, und scheiterst dann daran.
Vielleicht sagst du einfach mal, was deine eigentlichen Ziele sind, denn vielleicht gibt es andere Wege dorthin.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
@ __deets__ Das mit dem collections.dequeue liest sich ja gut. Allerdings kann ich pyb nicht auf dem Pico installieren. Ich finde auch den source Code nicht.
@Kebap Ich möchte verschiedene Funktionen erstellen die ein WS2812b zum leuchten bringt. Das heißt einmal "statische Lichter", (einmal in den gewünschten Farben an und dann bleibt es so). Das habe ich ja hinbekommen.
Jetzt geht es mir aber um das fortlaufende, heißt z.b. endlos blinken. Beim Endlosblinken braucht man ja - soweit ich weiß - eine unendliche Schleife. Und die soll aber, wenn man etwas anderes drückt, diese abrechen und etwas anderes starten.
So ähnliches habe ich schon mal mit dem Arduino und deren C Programmiert. Da ging es mit loop().
Ich dachte so ähnliches kann man auch in Python machen.
Daher das ich mich besser in Python auskenne als in C dachte ich mir, ich mache das in Python.
@Kebap Ich möchte verschiedene Funktionen erstellen die ein WS2812b zum leuchten bringt. Das heißt einmal "statische Lichter", (einmal in den gewünschten Farben an und dann bleibt es so). Das habe ich ja hinbekommen.
Jetzt geht es mir aber um das fortlaufende, heißt z.b. endlos blinken. Beim Endlosblinken braucht man ja - soweit ich weiß - eine unendliche Schleife. Und die soll aber, wenn man etwas anderes drückt, diese abrechen und etwas anderes starten.
So ähnliches habe ich schon mal mit dem Arduino und deren C Programmiert. Da ging es mit loop().
Ich dachte so ähnliches kann man auch in Python machen.
Daher das ich mich besser in Python auskenne als in C dachte ich mir, ich mache das in Python.
Man braucht beim endlos-blinken keine endlose Schleife. Man kann das durchaus so machen, wie Kebab und ich das dargestellt haben: eine Hauptschleife, und die prueft den gerade aktiven Mode, und ruft eine Unterfunktion auf. Und die Unterfunktion zB prueft, wieviel Zeit vergangen ist, und schaltet entsprechend die Animation einen Schritt weiter. OHNE WHILE SCHLEIFE. Das geht schon alles. asyncio waere eleganter, eben weil es den "natuerlichen" Programmfluss moeglich macht. Aber geht ja nunmal nicht.
Und bei dem Arduino muss das so aehnlich ausgesehen haben, denn dessen loop kann auch keine Endlos-Schleife enthalten (oder implizit aufrufen), sonst kommen veraenderte Werte genauso wenig an.
Und bei dem Arduino muss das so aehnlich ausgesehen haben, denn dessen loop kann auch keine Endlos-Schleife enthalten (oder implizit aufrufen), sonst kommen veraenderte Werte genauso wenig an.
OK klinkt logisch, nur wie bekomme ich den aktiven Mode wenn ich das pyb Modul nicht bekomme?
Und mit damit die Unterfunktion einen schritt weiter schaltet, kann ich in der Hauptschleife (while True?) die Zeit geprüft werden ob ich die unterfunktion nochmal starte mit anderen Werten. So etwas?
Und mit damit die Unterfunktion einen schritt weiter schaltet, kann ich in der Hauptschleife (while True?) die Zeit geprüft werden ob ich die unterfunktion nochmal starte mit anderen Werten. So etwas?
Ich habe keine Ahnung von welchem pyb-Modul du redest.
Und warum willst du die Zeit in der Hautptschleife pruefen? Ich habe doch geschrieben, dass die Unterfunktion das tut. Was angeblich "logisch" ist.
Den Pico kannst du auch mit dem Arduino-Framework benutzen. Wenn du das damit schon hinbekommen hast, wuerde ich das benutzen, weil du offensichtlich doch nicht so wirklich besser in Python auskennst.
Und warum willst du die Zeit in der Hautptschleife pruefen? Ich habe doch geschrieben, dass die Unterfunktion das tut. Was angeblich "logisch" ist.
Den Pico kannst du auch mit dem Arduino-Framework benutzen. Wenn du das damit schon hinbekommen hast, wuerde ich das benutzen, weil du offensichtlich doch nicht so wirklich besser in Python auskennst.
Ah, jetzt erst gesehen, ich hatte das pyb-Modul selbst verlinkt. Mein Fehler, ich dachte das waere ein allgemeines Modul, fuer alle ports. Das rp2-Modul hat das leider nicht.
Hier https://docs.micropython.org/en/v1.15/r ... rules.html gibt es allgemeine Hinweise, unter anderem auch wieder schedule. Das kann also benutzt werden, um das einsortieren in eine dequeue zu machen, ohne dass es zum Konflikt mit der Hautpschleife kommt.
Hier https://docs.micropython.org/en/v1.15/r ... rules.html gibt es allgemeine Hinweise, unter anderem auch wieder schedule. Das kann also benutzt werden, um das einsortieren in eine dequeue zu machen, ohne dass es zum Konflikt mit der Hautpschleife kommt.
- DeaD_EyE
- User
- Beiträge: 1206
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Eine Vorgehensweise, die auch im Micropython-Forum angepriesen worden ist, ist die Nutzung von uasyncio.
Blinkende LED ist gar kein Problem. Das Problem wird sein, dass du wahrscheinlich noch nie etwas mit asyncio / uasyncio gemacht hast. Das ist nicht trivial.
ISR-Callbacks können z.B. eine Funktion aufrufen, die einen Task abbricht `task.cancel()`.
Um das vernünftig zu gestalten, wirst du auch mit Klassen arbeiten müssen.
Blinken geht auch mit Timer.
Hier noch eine vereinfachte Variante:
Den Timer habe ich mit der ID 0 initialisiert. Das ist dann ein HardwareTimer.
Wenn man die ID -1 nutzt, wird ein SoftwareTimer verwendet, von denen auch mehr zur Verfügung stehen, aber vom jeweiligen Mikrocontroller unterstützt werden müssen.
Der ESP32 kann das auf jeden Fall. Beim Testen ist mir dann noch aufgefallen, dass auch bei id -1 ein und derselbe Timer zurückgeliefert wird.
Entsprechend habe ich dann 2 SoftwareTimer mit ID -1 und -2 gestestet, woraus unterschiedliche Objekte resultieren.
Möglicherweise ist das aber noch ein Bug. Ich hätte erwartet, dass Timer(-1) immer einen neuen Timer zurückliefert und nicht den existierenden SoftwareTimer mit der ID -1.
Blinkende LED ist gar kein Problem. Das Problem wird sein, dass du wahrscheinlich noch nie etwas mit asyncio / uasyncio gemacht hast. Das ist nicht trivial.
ISR-Callbacks können z.B. eine Funktion aufrufen, die einen Task abbricht `task.cancel()`.
Um das vernünftig zu gestalten, wirst du auch mit Klassen arbeiten müssen.
Blinken geht auch mit Timer.
Code: Alles auswählen
from uasyncio import ThreadSafeFlag
from machine import Timer
from time import sleep
def blinker(pin, delay_ms, flag):
# die toggle funktion wird durch
# den Timer aufgerufen
def toggle(timer):
# der Timer wird der zu aufrufenden Funktion
# übergeben. Man kann ihn mit timer.init(...) neustarten
print("Toggle")
# Ohne LED getestet
# deswegen auskommentiert
# Pin 0 -> 1 oder 1 -> 0
# pin(not pin())
if flag.state:
# Wenn flag.state gesetzt ist, Funktion verlassen
# und den Timer nicht erneut starten
return
timer.init(mode=Timer.ONE_SHOT, period=delay_ms, callback=toggle)
Timer(0,mode=Timer.ONE_SHOT, period=delay_ms, callback=toggle)
flag = ThreadSafeFlag()
# hier noch einen Pin zuweisen.
# pin=None hatte ich zum Testen genutzt, da ich keine LED angeschlossen habe
blinker(pin=None, delay_ms=1_000, flag=flag)
sleep(5)
flag.set()
print("Blinken beendet")
Code: Alles auswählen
from machine import Timer
from time import sleep
def blinker(pin, delay_ms):
def toggle(timer):
print("Toggle")
# pin(not pin())
return Timer(0, mode=Timer.PERIODIC, period=delay_ms, callback=toggle)
# hier noch einen Pin zuweisen.
# pin=None hatte ich zum Testen genutzt, da ich keine LED angeschlossen habe
timer = blinker(pin=None, delay_ms=1_000)
sleep(10)
timer.deinit() # <- beendet den Timer
Wenn man die ID -1 nutzt, wird ein SoftwareTimer verwendet, von denen auch mehr zur Verfügung stehen, aber vom jeweiligen Mikrocontroller unterstützt werden müssen.
Der ESP32 kann das auf jeden Fall. Beim Testen ist mir dann noch aufgefallen, dass auch bei id -1 ein und derselbe Timer zurückgeliefert wird.
Entsprechend habe ich dann 2 SoftwareTimer mit ID -1 und -2 gestestet, woraus unterschiedliche Objekte resultieren.
Möglicherweise ist das aber noch ein Bug. Ich hätte erwartet, dass Timer(-1) immer einen neuen Timer zurückliefert und nicht den existierenden SoftwareTimer mit der ID -1.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
OK. Aber 2 Fehler bekomme ich wenn ich dies ausführe.
1. Fehler ist bei flag.state: und es funktioniert nur der Software Timer (-1)
Wenn ich Timer(0, ...) eingebe, dann kommt der Fehler
1. Fehler ist bei flag.state:
Code: Alles auswählen
AttributeError: 'ThreadSafeFlag' object has no attribute 'stat'
Wenn ich Timer(0, ...) eingebe, dann kommt der Fehler
Code: Alles auswählen
[ValueError: Timer doesn't exist/code]
Hallo,
naja ich kann auch kein 'stat' im Code finden.
Das mit dem Timer steht auch in der Doku: (Es geht ja um einen Pico?)
https://docs.micropython.org/en/latest/ ... tml#timers
Grüße
Dennis
naja ich kann auch kein 'stat' im Code finden.
Das mit dem Timer steht auch in der Doku: (Es geht ja um einen Pico?)
https://docs.micropython.org/en/latest/ ... tml#timers
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Ich habe nochmal folgenden Code erweitert:
Wenn ich die 1 auf der FB drücke ist data 69, die 2 ist 70 u.s.w.
Ich dachte mir wenn ich das Argument 'data' mit angebe und in der toggle-Funktion prüfe ob die gerade gedrückte Taste ungleich 70 (Taste 2) ist, dann sollte sie per return abbrechen.
Das tut sie nur, solange ich nicht die Taste 2 drücke, wenn ich als erstes paar mal die Taste 1 (69) drücke, dann bricht sie wie gewollt ab, aber sobald ich die 2 drücke dann wieder die 1 wird die Toggle Funktion nicht mehr abgebrochen bzw kehrt nicht zurück und die print-Ausgabe ist immer noch 70.
Hängt das mit der Callback-Methode zusammen?
Code: Alles auswählen
def callback(data, addr, ctrl):
global x
if data > 0: # NEC protocol sends repeat codes.
print('Data {:02x} Addr {:04x}'.format(data, addr))
blinker(pin=None, delay_ms=1_000, x=data)
def blinker(pin, delay_ms,x):
def toggle(timer):
print(x)
if x != 70:
print("return")
return
timer.init(mode=Timer.ONE_SHOT, period=delay_ms, callback=toggle)
Timer(-1,mode=Timer.ONE_SHOT, period=delay_ms, callback=toggle)
ir = NEC_16(Pin(16, Pin.IN), callback)
Ich dachte mir wenn ich das Argument 'data' mit angebe und in der toggle-Funktion prüfe ob die gerade gedrückte Taste ungleich 70 (Taste 2) ist, dann sollte sie per return abbrechen.
Das tut sie nur, solange ich nicht die Taste 2 drücke, wenn ich als erstes paar mal die Taste 1 (69) drücke, dann bricht sie wie gewollt ab, aber sobald ich die 2 drücke dann wieder die 1 wird die Toggle Funktion nicht mehr abgebrochen bzw kehrt nicht zurück und die print-Ausgabe ist immer noch 70.
Hängt das mit der Callback-Methode zusammen?
Es wurde wirklich schon oft hier gesagt: im callback darfst du nur signalisieren, oder mit schedule längeren/komplexen Code laufen lassen. Der Blinker Code ist so auch Quatsch, weil du andauernd neue Objekte erzeugst, statt eines immer wider zu verwenden. Das ist auch schlecht entworfen in der Beziehung, weil du es nicht von außen manipulieren kannst. Da muss ein ordentliches Objekt her, mit on/off oder toggle Methoden.