Seite 3 von 4
					
				Re: Funktion beenden
				Verfasst: Freitag 10. März 2023, 17:12
				von __deets__
				Das ist doch grosser Quatsch. Wieso soll denn irgendwie ein Task aus dem NEC_16 werden? Das hast du doch vorher auch nicht gemacht. Ein simples
Code: Alles auswählen
ir = NEC_16 (Pin(16, Pin.IN), lambda val, addr, ext : callback(command_queue, val, addr, ext))
sollte reichen. Achtung, da ist ein ext drin, weil das der callback wohl braucht. Das habe ich uebersehen, aber hatte dein callback ja auch schon.. ein bisschen mitdenken ist schon erwuenscht.
Laut Code sollte aber auch das hier klappen:
Code: Alles auswählen
ir = NEC_16 (Pin(16, Pin.IN), callback, callback_queue)
weil zusaetzliche Argumente einfach weitergeleitet werden. Dann muss die Signatur des Callbacks so aussehen:
 
			 
			
					
				Re: Funktion beenden
				Verfasst: Freitag 10. März 2023, 21:58
				von egon11
				Ich habe jetzt das ganze nochmal ausführlich getestet. In der Callback-Funktion ist immer der 1. Parameter data, also die daten, der 2. ist die adresse und der 3. ist ctl (was auch immer das ist) queue ist dann als 4. parameter (durch print getestet).
Dann bin ich nochmal das Beispiel von __deets__ (2. Seite ganz oben) durchgegangen, das zeigte mir, das was dort in der Funktion callback bei dem code 'uasyncio.create_task(queue.put(val))' als Parameter bei 'queue.put' stehen kann was will, denn das kann man in der Funktion dispatcher per 'await queue.get()' ausgeben lassen, bzw wird übermittelt.
Soweit so gut, alles verstanden.  Nur genau das macht es in meinen Code nicht. Habe das nochmal geändert wie vorgeschlagen (vielen dank dafür), aber wenn ich das Programm starte, wird startet bei der Funktion dispatcher die while-Schleife nicht.
Hier nochmal der Code, ich denke mal es liegt an der Callback Methode.
Das Objekt queue wird aber am Anfang der Methode dispatcher als print ausgegeben 
 , also sollte das Prinzip ja funktionieren. Nur die while-Schleife im dispatcher startet nicht.
Code: Alles auswählen
def callback(data, addr, ctl,queue):
    if data > 0:  # NEC protocol sends repeat codes.
        print('Data {:05x} Addr {:04x}'.format(data, addr))
        uasyncio.create_task(queue.put(data))
    
async def dispatcher(queue):
    print(queue)
    task = None
    while True:
        command = await queue.get()
        print(command)
        print("dispatcher")
   
async def main():
    command_queue = Queue()
    ir = NEC_16 (Pin(16, Pin.IN), callback, command_queue)
    await dispatcher(command_queue)
    
if __name__ == '__main__':
    uasyncio.run(main())
 
			 
			
					
				Re: Funktion beenden
				Verfasst: Sonntag 12. März 2023, 11:24
				von __deets__
				Kann ich erstmal nach Studium des NEC_16 Codes so nicht erklaeren - meines Erachtens laeuft das alles nur in IRQs und Timern (die denke ich auch IRQs sind), und sollte dann *eigentlich* problemlos gehen. Die while-Schleife startet auch, das Problem ist eher, dass das queue.put nie durchgefuehrt wird, bzw. nicht die gewuenschten Ergebnisse hat. Denn ich vermute mal das print("Data...") findet statt?
Es kann sein, dass die IRQ/Timer Funktionalitaet da doch irgendwas komisches machen. Ggf. hilft im callback 
 
https://docs.micropython.org/en/latest/ ... n.schedule
einzusetzen, um dadurch dann die Daten in die Queue zu packen via create_task. Also so in etwa:
Code: Alles auswählen
def callback(data, addr, ctl,queue):
    if data > 0:  # NEC protocol sends repeat codes.
        print('Data {:05x} Addr {:04x}'.format(data, addr))
        micropython.schedule(lambda: uasyncio.create_task(queue.put(data)))
 
			 
			
					
				Re: Funktion beenden
				Verfasst: Montag 13. März 2023, 09:50
				von egon11
				Ja genau, print("Data...") findet statt.
Was mir als Fehler auf die Füße fällt ist, dass mir angezeigt wird, das micropython.schedule 2 Argumente erwartet wird, aber nur 1 gegeben ist.
Laut der Dokumentation sollte aber 1 Argument reichen 'micropython.schedule(func, arg)'.
Jetzt habe ich mal nach dem lambda-Argument einfach ein String angehängt, da wären wieder 3 Argumente gegeben, aber nur 2 würden akzeptiert werden.
			 
			
					
				Re: Funktion beenden
				Verfasst: Montag 13. März 2023, 10:05
				von __deets__
				Dann muss das lambda einfach ein Argument bekommen, das du ja auch ignorieren kannst.
			 
			
					
				Re: Funktion beenden
				Verfasst: Montag 13. März 2023, 10:11
				von egon11
				auch mir Argument(en) ist laut Ausgabe nur 1 gegeben.
			 
			
					
				Re: Funktion beenden
				Verfasst: Montag 13. März 2023, 10:18
				von __blackjack__
				Das Problem dürfte sein, dass `schedule()` *zwei* Argumente will, eine Funktion und ein Argument, und hier egal ob nun mit ``lambda`` oder nicht, nur *eins* übergeben wird, nämlich der Rückgabewert der Funktion die mit dem Argument aufgerufen wurde — statt dort beides zu übergeben, statt die Funktion schon aufzurufen.
			 
			
					
				Re: Funktion beenden
				Verfasst: Montag 13. März 2023, 10:33
				von __deets__
				Ah. Klar.  Beides natürlich. Ein dummy Argument beim Aufruf, und im lambda muss das angegeben werden, aber kann ignoriert werden.
			 
			
					
				Re: Funktion beenden
				Verfasst: Dienstag 14. März 2023, 07:55
				von egon11
				Das ganze habe ich in
Code: Alles auswählen
 micropython.schedule(lambda x:uasyncio.create_task(queue.put(data)),"y")
 geändert.
Es läuft ohne Fehler durch, nur die while-Schleife im dispatcher will nicht starten.
 
			 
			
					
				Re: Funktion beenden
				Verfasst: Dienstag 14. März 2023, 08:40
				von __deets__
				Dann ist da erstmal das Ende meiner Fahnenstange erreicht. Um das tiefgreifender zu analysieren, müsste ich das selbst auf einem Micro laufen lassen, und ggf. alles auf uasyncio umschreiben. Ob und wann ich dazu komme, kann ich nicht sagen. 
Eine Alternative, die aber nicht wirklich deiner Forderung nach einem Task zum abbrechen entspricht , sondern ein ganz anderes Vorgehen bedeutet: Bau einen superloop, der mittels verschiedener Zustandsmaschinen die Aufgabe erledigt. Das ist allerdings eher ätzend, uasyncio ist eigentlich genau das, was man da will. Aber wenn es nicht tut…
			 
			
					
				Re: Funktion beenden
				Verfasst: Dienstag 14. März 2023, 09:31
				von egon11
				OK trotzdem vielen dank für die Hilfe.
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 09:24
				von egon11
				Oder kann man das auch noch anders lösen?
Ziel ist: Beim Tastendruck der IR- Fernbedienung soll eine bestimmte Funktion ausgeführt werden, darunter sollen auch Funktionen sein, die eine "while True" Schleife haben (z.b. unendliche Laufleiste der Led's).
Meine nächste Überlegung wäre, in der "while True" -Schleife ein Wert zu überprüfen ob eine Taste gedrückt wurde.
Nur leider fällt mir nichts dazu ein wie und ob überhaupt man das realisieren kann.
Hat dazu jemand noch ein Tipp für mich?
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 10:17
				von __deets__
				Die Alternative habe ich ja skizziert. Um es ganz klar zu sagen: while True in den Funktionen geht nicht. Das Modell funktioniert nur mit Tasks, weil die cancelbar sind. Eine Hauptschleife mit Zustandsmaschine hingegen geht. Schrieb ich ja schon.
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 10:23
				von egon11
				Wie meinst du das mit einer Hauptschleife mit Zustandsmaschine?
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 10:30
				von __deets__
				Eine Schleife & abhängig vom Zustand in verschiedene Funktionen springen, die aber natürlich schnell wiederkehren müssen. Ein verwandtes Stichwort ist superloop. Kannst du mal suchen.
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 11:02
				von __deets__
				Das ist ja am Ende nur algebraisch umgeformt, sozusagen: 
Code: Alles auswählen
def eins():
    while True:
        print("eins")
        sleep(0.5)
    
def zwei():
    while True:
        print("zwei")
        sleep(0.5)
Das war dein Code. Daraus wird (in Naeherung, und ungetestet)
Code: Alles auswählen
def eins():
    print("eins")
    
def zwei():
    print("zwei")
def hauptschleife():
     while True:
         modus = pruefe_ir_eingabe()
         if modus == 1:
              eins()
         elif modus == 2:
              zwei()
Du kannst pro Programm (ohne Scheduler wie asyncio oder threading) halt nur eine Hauptschleife haben.
 
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 15:00
				von Kebap
				Sieht ja so ähnlich aus wie mein Ansatz oben..
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 16:36
				von __deets__
				Voellig richtig, aber es ist ja auch nur die Notloesung. Man will einen solchen Scheduler eigentlich nicht selbst schreiben.
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 16:42
				von egon11
				Irgenwie ist das mit der Callback-Funktion alles triggi. Wenn ich darin eine While-True Schleife ausführen lasse um auf bestimmte Dinge zu reagieren dann läuft sie nicht weiter...
			 
			
					
				Re: Funktion beenden
				Verfasst: Mittwoch 15. März 2023, 16:50
				von __deets__
				Im callback darf man das *niemals* machen. Du darfst im callback nur die Information ueber den geaenderten Modus oder Werte an eine staendig laufende Hauptschleife schicken.