Microcontroller Forum Hallo liebes Forum Ich bin relativ neu in diesem Bereich, habe mir jedoch bereits ein Wenig Know-How angeeignet, da ich ein Projekt realisieren möchte. In dem Projekt werden Servos und Schrittmotoren angesteuert und ein IR-Sensor ausgewertet. Nun ist der Ablauf sequenziell. Das heisst Schrittmotor dreht 45 Grad Servo1 dreht 90 Grad und wieder zurück Schrittmotor dreht wieder 45 Grad Servo2 dreht 90 Grad zurück und wiedervorwärts. Das Ganze mache ich mit Micropython und einem Raspberry Pico. Für die Bedienung, möchte ich einen Taster verwenden, der das Programm startet und so lange im Loop wiederholt, bis ich den Taster wieder drücke. Das Problem ist, dass ich den Taster genau dann drücken muss, wenn ich in der Sequenz am entsprechenden Punkt bin. Was ist hierfür die saubere Lösung? Ich möchte den Taster zu jedem Zeitpunkt drücken können und das Programm soll dann den Durchlauf noch fertig machen und anschliessend nicht mehr starten. Danke euch für euer Feedback und lieber Gruss Remo
-regelmässig den Taster abfragen (alle 20ms oder so) -"gedrückt" in einer Variablen merken -beim Neustart der Sequenz auf zwischenzeitlich gedrückten Taster reagieren So ganz grob. Die Feinheiten kommen noch.
Remo H. schrieb: > Was ist hierfür die saubere Lösung? Multitasking. > Ich möchte den Taster zu jedem Zeitpunkt drücken können und das Programm > soll dann den Durchlauf noch fertig machen und anschliessend nicht mehr > starten. Das ist leicht, siehe oben.
In MicroPython gibt es AsyncIO, ein kooperatives MT, polling ist da nicht nötig.
Remo H. schrieb: > Das Problem ist, dass ich den Taster genau dann drücken muss, wenn ich > in der Sequenz am entsprechenden Punkt bin. Warum diese Vorgabe, warum kannst du Ihn nicht jederzeit drücken? Und was ist der "entsprechende" Punkt? Remo H. schrieb: > Ich möchte den Taster zu jedem Zeitpunkt drücken können Das widerspricht der Aussage oben.
Für solche Sachen möchte ich dir schwerstens an Herz legen, mal ein Automatendiagramm bzw. Zustandsdiagramm aufzumalen. Dann wird dir auch klar, wie die Abläufe eigentlich sein sollen. Z.B. muss ja die Sequenz immer bis zum Ende laufen, bevor die Loop nach einem Tastendruck gestoppt werden soll. Der Tastendruck kann ja jederzeit, also auch mitten in der Ablaufsequenz erfolgen. Mit dem Diagramm wird dann auch klar, welche Zustände das System überhaupt haben kann.
Martin S. schrieb: > Remo H. schrieb: >> Das Problem ist, dass ich den Taster genau dann drücken muss, wenn ich >> in der Sequenz am entsprechenden Punkt bin. > > Warum diese Vorgabe, Das ist keine Vorgabe, sondern ein Problem seiner aktuellen Lösung.
Ich danke euch für eure Antworten! wie der Ablauf ist, ist mir eigentlich klar. Ich könnte in der Sequenz nach jedem Schritt den Taster prüfen, was ein Gebastel ist. Ich könnte auch einen Schalter statt einen Taster verwenden. Multitasking ist für mein Verständnis ebenfalls die saubere Lösung. Den Tipp mit AsyncIO werde ich Mal genauer anschauen. Ich glaube das ist das was ich gesucht habe. Multithreading habe ich Mal versucht, habe da aber nur 2 CPU-Kerne, die ich verwenden kann. Ich habe mich einfach gefragt, wie solche Tasterzustände im Normalfall oder in der Praxis abgefragt werden? Wird das jedes Mal mit Multitasking gelöst? Sobald ich das Projekt abgeschlossen habe, werde ich es dann gerne hier im Forum präsentieren.
Remo H. schrieb: > Ich habe mich einfach gefragt, wie solche Tasterzustände im Normalfall > oder in der Praxis abgefragt werden? Wird das jedes Mal mit Multitasking > gelöst? asyncio ist die bequemste Möglichkeit gerade für Anfänger, das ist kooperatives Multitasking auf einem Kern. Man kann auch einen Timer mit zB. 10ms Intervall und IRQ nutzen. Im IRQ kurz die Taste abfragen und Status in einem globalen Flag merken. Man kann auch PIO zur Abfrage nutzen und bei Tastendruck eine Info in die Queue senden. Das ist wirklich vollständig entkoppelt. Man kann auch…
Remo H. schrieb: > Ich danke euch für eure Antworten! > > wie der Ablauf ist, ist mir eigentlich klar. > Ich könnte in der Sequenz nach jedem Schritt den Taster prüfen, was ein > Gebastel ist. In der Tat. Aber mit dem richtigen Ansatz macht man das tatsächlich so, wenn gleich es anders beschrieben wird und dann eben KEIN Gebastel ist. > Ich könnte auch einen Schalter statt einen Taster > verwenden. Kann man. Man lernt dabei aber nichts. > Multithreading habe ich Mal versucht, habe da aber nur 2 CPU-Kerne, die > ich verwenden kann. :-) Der war gut! Heute braucht es schon einen ganzen CPU-Kern, um einen Taster abzufragen! > Ich habe mich einfach gefragt, wie solche Tasterzustände im Normalfall > oder in der Praxis abgefragt werden? Wird das jedes Mal mit Multitasking > gelöst? Scheint so!
Falk B. schrieb: > Das ist keine Vorgabe, sondern ein Problem seiner aktuellen Lösung. Na dann, okay. Remo H. schrieb: > Ich habe mich einfach gefragt, wie solche Tasterzustände im Normalfall > oder in der Praxis abgefragt werden? Wird das jedes Mal mit Multitasking > gelöst? Im fast einfachsten Fall in einem Timerinterrupt, man hat ja nicht immer und überall ein Betriebssystem mit Sceduler und Tasks etc...aber letztendlich wird auch der Sceduler aus einem Interrupt bedient... In 90% aller Fälle braucht man das alles aber nicht. Wenn man es so programmiert dass es nirgendwo Routinen gibt in der der Prozessor lange "hängen" bleibt, geht das in der Regel auch so. Aber besser ist es schon eine Timingmethode zu haben die Programmunabhängig funktioniert um dem ganzen eine realistische Struktur zu verleihen - z.B, beim Entprellen der Taste etc...
Remo H. schrieb: > Was ist hierfür die saubere Lösung? Eine Entprell-Lib nehmen, die im Timerinterrupt (z.B. Systick) alle Tasten entprellt und die Ereignisse (Flanke) für die Mainloop abspeichert.
Peter D. schrieb: > Eine Entprell-Lib nehmen, die im Timerinterrupt (z.B. Systick) Remo H. schrieb: > Das Ganze mache ich mit Micropython und einem Raspberry Pico.
1 | #!/usr/bin/python3
|
2 | |
3 | from machine import Timer |
4 | from time import sleep_ms |
5 | from rp2 import bootsel_button |
6 | |
7 | class G: |
8 | running = True |
9 | |
10 | def tmr_cb(timer): |
11 | G.running = False if bootsel_button() else G.running |
12 | |
13 | tmr = Timer(mode=Timer.PERIODIC, freq=100, callback=tmr_cb) |
14 | while G.running: |
15 | sleep_ms(1000) |
16 | print('running…') |
17 | tmr.deinit() |
:
Bearbeitet durch User
Die Aufgabe klingt sehr nach einem Zustandsautomaten, wo in jedem Zustand ein "Taster gedrückt" Ereignis ausgewertet werden sollte.
Pilot P. schrieb: > Z.B. muss ja die Sequenz immer bis zum Ende laufen, bevor die Loop nach > einem Tastendruck gestoppt werden soll. Der Tastendruck kann ja > jederzeit, also auch mitten in der Ablaufsequenz erfolgen. Das war der Sinn von H.Joachim S. schrieb: > -regelmässig den Taster abfragen (alle 20ms oder so) > -"gedrückt" in einer Variablen merken > -beim Neustart der Sequenz auf zwischenzeitlich gedrückten Taster > reagieren
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.