Forum: Mikrocontroller und Digitale Elektronik Mit Taster Programm starten/stoppen


von Remo H. (remo_h)


Lesenswert?

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

von H.Joachim S. (crazyhorse)


Lesenswert?

-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.

von Falk B. (falk)


Lesenswert?

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.

von J. S. (jojos)


Lesenswert?

In MicroPython gibt es AsyncIO, ein kooperatives MT, polling ist da 
nicht nötig.

von Martin S. (mmaddin)


Lesenswert?

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.

von Pilot P. (klatschnass)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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.

von Remo H. (remo_h)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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…

von Falk B. (falk)


Lesenswert?

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!

von Martin S. (mmaddin)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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
von Ali K. (teddy50)


Lesenswert?

Die Aufgabe klingt sehr nach einem Zustandsautomaten, wo in jedem 
Zustand ein "Taster gedrückt" Ereignis ausgewertet werden sollte.

von Rainer W. (rawi)


Lesenswert?

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
Noch kein Account? Hier anmelden.