Hallo, ich möchte ein Programm bauen, welches bei bestimmten Ereignissen eine Funktion auslöst, die jeweilige Funktion soll per while-True-Schleife so lange gehen bis ein anderes Ereignis auftritt. das Ereignis ist eine Fernbedienung.
Jetzt weiß ich aber nicht, wie ich dann so eine Funktion mit Endlosschleife beenden kann.
Könnte mir jemand einen Tipp geben?
Grüße
Funktion beenden
Mal ähnlich allgemein gehalten wie deine Frage:
Innerhalb der Endlosschleife prüfst du, ob das Ereignis aufgetreten ist, und beendest die Schleife dann, bzw. reagierst auf das Ereignis, bevor du sie wieder startest.
Innerhalb der Endlosschleife prüfst du, ob das Ereignis aufgetreten ist, und beendest die Schleife dann, bzw. reagierst auf das Ereignis, bevor du sie wieder startest.
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.
- __blackjack__
- User
- Beiträge: 13116
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@egon11: Eine Endlosschleife kann man mit ``break``, ``return``, oder einer Ausnahme verlassen. ``return`` nur falls sich die Schleife innerhalb einer Funktion oder Methode befindet. Und dann wäre da noch ``yield`` womit man eine (Generator-)Funktion/Methode anhalten kann, und sich an anderer Stelle entscheiden kann ob man sie irgendwann noch mal weiterlaufen lässt oder nicht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Das ist event-basierte Programmierung: Du hast eine Hauptschleife die Events erkennt und eventuell auch Status-Informationen speichert. Anhand dessen rufst du aus der Hauptschleife immer die Funktion auf, die zum aktuellen Status passt. Du lagerst also die Endlosschleife aus der Funktion aus.
Dennoch wäre ein Beispiel in Code recht hilfreich, um das allgemeine Prinzip abzubilden.
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.
Also es geht um eine event-basierte-Schleife.
Genau gesagt geht es um den folgenden Teil:
Die Methode ist event-basiert.
Nun möchte ich, je nachdem welche Taste gedrückt wurde folgende Methode aufrufen, um sie bei der nächsten Taste die gedrückt wurde wieder anzuhalten.
Genau gesagt geht es um den folgenden Teil:
Code: Alles auswählen
import time
from machine import Pin
from ir_rx import NEC_16
from time import sleep
wert = {0x45:"1", 0x46:"2"}
def callback(data, addr, ctrl):
if data > 0: # NEC protocol sends repeat codes.
#print('Data {:05x} Addr {:04x}'.format(data, addr))
# print(ir_data)#
# print("huhu")
if wert[data] == "1":
eins()
if wert[data] == "2":
zwei()
ir = NEC_16(Pin(16, Pin.IN), callback)
def eins():
while True:
print("eins")
sleep(0.5)
def zwei():
while True:
print("zwei")
sleep(0.5)
Nun möchte ich, je nachdem welche Taste gedrückt wurde folgende Methode aufrufen, um sie bei der nächsten Taste die gedrückt wurde wieder anzuhalten.
- __blackjack__
- User
- Beiträge: 13116
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Das geht so gar nicht, weil der `callback` ziemlich sicher nur kurz etwas tun darf, und nicht in einer Endlosschleife enden darf.
Das Beispiel könnte man so ausdrücken (ungetestet):
Das Beispiel könnte man so ausdrücken (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
from queue import Empty, Queue
from ir_rx import NEC_16
from machine import Pin
DATA_TO_TEXT = {0x45: "eins", 0x46: "zwei"}
def callback(queue, data, _addr, _ctrl):
if data > 0: # NEC protocol sends repeat codes.
queue.put(DATA_TO_TEXT[data])
def main():
queue = Queue()
_ir = NEC_16(Pin(16, Pin.IN), partial(callback, queue))
text = None
while True:
if text is not None:
print(text)
try:
text = queue.get(timeout=0.5)
except Empty:
pass # Intentionally ignored.
if __name__ == "__main__":
main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Micropython kennt asyncio für solche Zwecke. Eine englische Einführung findet sich zB hier: https://github.com/peterhinch/micropyth ... UTORIAL.md
Kann man sicher mit Deepl auf Deutsch ausreichend gut übersetzen.
Kann man sicher mit Deepl auf Deutsch ausreichend gut übersetzen.
Das hier zb ist ein ziemlich nahes Beispiel: https://github.com/peterhinch/micropyth ... ncellation
Wenn du mit Events arbeitest, dann kannst du kein Sleep benutzen, weil sonst das ganze Programm anhält.
Die Hauptschleife darf aber nicht anhalten, sondern muss kontinuierlich prüfen, ob neue Events aufgetreten sind.
Die Hauptschleife darf aber nicht anhalten, sondern muss kontinuierlich prüfen, ob neue Events aufgetreten sind.
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.
Jetzt habe ich folgen (funktionierenden) Code
Sie macht erstmal genau das, was sie soll.
Jetzt muss ich noch in der Methode start() einbauen, welche Methode gerade ausgeführt wird oder nicht. Wenn ich das überprüft habe muss ich jene erstmal beenden und dann eine andere starten.
Wenn ich dann aber in der Methode start() `await asyncio.sleep(3)` und ` task2.cancel()` weg lasse, dann werden die Methoden nur 1x ausgeführt.
Das heißt, ich muss es irgendwie schaffen, dass sie dauerhaft laufen, bis man wider etwas drückt, dann die laufende Methode beenden und eine andere startet.
Code: Alles auswählen
wert = {0x45:"1", 0x46:"2"}
async def test1():
while True:
print("methode 1 zum ausfuhren")
await asyncio.sleep(1)
async def test2():
while True:
print("methode 2 zum ausfuhren")
await asyncio.sleep(1)
async def start(x):
print("übergebener Wert " + x)
if x == "1":
task1 = asyncio.create_task(test1())
await asyncio.sleep(3)
print("beenden")
task1.cancel()
if x == "2":
task2 = asyncio.create_task(test2())
await asyncio.sleep(3)
print("beenden")
task2.cancel()
def callback(data, addr, ctrl):
if data > 0: # NEC protocol sends repeat codes.
print('Data {:05x} Addr {:04x}'.format(data, addr))
print(wert[data])
asyncio.run(start(wert[data]))
if __name__ == "__main__":
ir = NEC_16(Pin(16, Pin.IN), callback)
Jetzt muss ich noch in der Methode start() einbauen, welche Methode gerade ausgeführt wird oder nicht. Wenn ich das überprüft habe muss ich jene erstmal beenden und dann eine andere starten.
Wenn ich dann aber in der Methode start() `await asyncio.sleep(3)` und ` task2.cancel()` weg lasse, dann werden die Methoden nur 1x ausgeführt.
Das heißt, ich muss es irgendwie schaffen, dass sie dauerhaft laufen, bis man wider etwas drückt, dann die laufende Methode beenden und eine andere startet.
Ich würde da nicht async benutzen. Wie wäre es denn so?
Code: Alles auswählen
def task_1():
print("methode 1 zum ausfuhren")
def task_2():
print("methode 2 zum ausfuhren")
def start(x):
print("übergebener Wert " + x)
if x == "1":
current_task = task_1
if x == "2":
current_task = task_2
current_task()
sleep(0.5)
x = neues_x_bestimmen()
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.