Guten Tag!
Ich entschuldige mich schon jetzt für diese grundlegende Frage, allerdings habe ich schon viel gesucht und nichts zu diesem Thema gefunden.
Ich möchte eine Funktion in meinem Python-Programm durch eine Eingabe - genauer gesagt durch das Drücken eines Tasters - unterbrechen, eine "Interrupt-Routine" abarbeiten und anschließend die vorhergehende Funktion fortsetzen. Da ich von der C-Programmierung komme, denke ich dabei sofort an Interrupts. Vergleichbares habe ich bereits erwähnt in der Pythonprogrammierung noch nicht gefunden.
Vielleicht kann mir da jemand helfen. Danke schon im voraus
Grüße
wiesam
Interruptroutine in Python
Wo geht denn sowas in C? Kenne ich nur von Microcontrollern. Unter normalen OSsen geht sowas jedenfalls nicht. Auch nicht in C.
Das Modul signal könnte für dich interessant sein. Ansonsten erläutere mal etwas genauer deine Problemstellung.
Das Modul signal könnte für dich interessant sein. Ansonsten erläutere mal etwas genauer deine Problemstellung.
Stimmt. Hab mich wohl zu ungenau ausgedrückt, ich kenne das auch nur von der µC-Programmierung in C. Da es sich hier um einen Roboter handelt, die vermutlich auch mit einem µC angesteuert wird, dachte ich, dass es da etwas ähnliches geben sollte.
Um ganz konkret zu werden, stell ich mal den betroffenen Code-Abschnitt herein.
Es handelt sich um obenstehendes Unterprogramm. Die Klammer mit den Punkten (...) ersetzt Teile des Codes, die meiner Meinung für die Frage nicht von Bedeutung sind (Variablendefinition, etc.). Die dType-Befehle sind Roboterbefehle (auch nicht so wichtig).
Um auf den Punkt zu kommen: ich will anders als bisher gelöst, die Abarbeitung der for-Schleife im Bereich der if-Anweisung mittels Taster unterbrechen, in ein Unterprogramm (Interrupt-Routine) springen und anschließend soll die for-Schleife im bisherigen Verlauf weiterlaufen. Dabei sollte der Tasterstatus schon während der dType-Befehle abgefragt und in eine Variable geschrieben werden und nicht wie bisher erst in der if-Anweisung.
Ich hoffe das war klar und verständlich ausgedrückt.
Um ganz konkret zu werden, stell ich mal den betroffenen Code-Abschnitt herein.
Code: Alles auswählen
def glue(xout, yout, zout, xin, yin, zin, r,c):
(...)
for x in range(2):
for y in range(9):
#jump fast to other gluing points
dType.SetPTPCommonParams(api, v_fast, a_fast, 1)
dType.SetPTPCmd(api, 0, xout+(x*x2)+xoff, yout+(y*cell)+yoff, zout+1, r, 1)
dType.SetPTPCommonParams(api, 20, a_fast, 1)
dType.SetPTPCmd(api, 0, xout+(x*x2)+xoff, yout+(y*cell)+yoff, zout, r, 1)
#gluing
#glue while first glue-rectangle
#stop gluing while second glue-rectangle
dType.SetIODO(api, 2, 0, 1)
dType.SetPTPCommonParams(api, v_glu, a_glu, 1)
dType.SetPTPCmd(api, 2 , xout+(x*x2)+xoff, yout-xy_arc+(y*cell)+yoff, zout+z_arc, r, 1)
dType.SetPTPCmd(api, 2 , xout-xy_arc+(x*x2)+xoff, yout+(y*cell)+yoff, zout+(2*z_arc), r, 1)
dType.SetPTPCmd(api, 2 , xout+(x*x2)+xoff, yout+xy_arc+(y*cell)+yoff, zout+(3*z_arc), r, 1)
dType.SetPTPCmd(api, 2 , xout+xy_arc+(x*x2)+xoff, yout+(y*cell)+yoff, zout+(4*z_arc), r, 1)
dType.SetIODO(api, 2, 1, 1)
dType.SetPTPCmd(api, 2 , xout+(x*x2)+xoff, yout-xy_arc+(y*cell)+yoff, zout+zup, r, 1)
dType.SetPTPCmd(api, 2 , xout-xy_arc+(x*x2)+xoff, yout+(y*cell)+yoff, zout+zup, r, 1)
dType.SetPTPCmd(api, 2 , xout+(x*x2)+xoff, yout+xy_arc+(y*cell)+yoff, zout+zup, r, 1)
dType.SetPTPCmd(api, 2 , xout+xy_arc+(x*x2)+xoff, yout+(y*cell)+yoff, zout+zup, r, 1)
dType.SetPTPCmd(api, 2 , xout+(x*x2)+xoff, yout-xy_arc+(y*cell)+yoff, zout+zup, r, 1)
if(dType.GetIODI(api, 17)[0]==0):
serv_exit=1
(...)
return serv_exit
Um auf den Punkt zu kommen: ich will anders als bisher gelöst, die Abarbeitung der for-Schleife im Bereich der if-Anweisung mittels Taster unterbrechen, in ein Unterprogramm (Interrupt-Routine) springen und anschließend soll die for-Schleife im bisherigen Verlauf weiterlaufen. Dabei sollte der Tasterstatus schon während der dType-Befehle abgefragt und in eine Variable geschrieben werden und nicht wie bisher erst in der if-Anweisung.
Ich hoffe das war klar und verständlich ausgedrückt.
Unterbrechen und wieder weiter laufen lassen geht nicht. Weder in Python, noch in irgendeiner anderen Sprache. Jedenfalls nicht so ohne weiteres. Wie schon erwaehnt, da kann ggf. das Modul "signal" helfen, denn das ist der einzige mir bekannte Mechanismus, mit dem unter Posixen und mit Einschraenkungen auch unter Windows so etwas programmiert werden kann. Allerdings loest das nicht das Problem, wie man dieses Signal abhaengig von dType.GetIODI ausloest.
Da du nicht ausfuehrst, was dType *genau* ist, kann man leider auch nicht verlaesslich eine alternative Herangehensweise empfehlen. Das einzige, was nach bisherigem Kenntnisstand gehen wuerde ist, jede Anweisung im Wechsel mit einer Abfrage aufzurufen. Dazu die if-Anweisung und alles was sie macht in eine Funktion packen, und dann nach dem Schema
arbeiten.
Wenn dType hingegen die Abfrage durch einen nebenlaeufigen Thread erlaubt, *dann* kann man etwas parallel ausfuehren lassen. Oder noch besser eine Ereignis-Behandlung bereit stellt. Aber wie schon gesagt, das kann man ohne genauere Kenntnis von dType nicht weiter ausfuehren.
Da du nicht ausfuehrst, was dType *genau* ist, kann man leider auch nicht verlaesslich eine alternative Herangehensweise empfehlen. Das einzige, was nach bisherigem Kenntnisstand gehen wuerde ist, jede Anweisung im Wechsel mit einer Abfrage aufzurufen. Dazu die if-Anweisung und alles was sie macht in eine Funktion packen, und dann nach dem Schema
Code: Alles auswählen
dType.SetPTPCommonParams(api, v_fast, a_fast, 1)
serv_exit = taster_abfrage(dType, api)
dType.SetPTPCmd(api, 0, xout+(x*x2)+xoff, yout+(y*cell)+yoff, zout+1, r, 1)
serv_exit = taster_abfrage(dType, api)
...
Wenn dType hingegen die Abfrage durch einen nebenlaeufigen Thread erlaubt, *dann* kann man etwas parallel ausfuehren lassen. Oder noch besser eine Ereignis-Behandlung bereit stellt. Aber wie schon gesagt, das kann man ohne genauere Kenntnis von dType nicht weiter ausfuehren.
Alles klar, dann wird das Modul "signal" nicht weiterhelfen, wenn ich es nicht abhängig von dType.GetIODI auslösen kann.
Alle Roboterbefehle in der dazugehörigen Entwicklungsumgebung beginnen mit dType. Wie genau diese Befehle arbeiten, weiß ich nicht und der Hersteller beschreibt diese auch nicht näher. Er beschreibt lediglich, dass z.B. dType.GetIODI(api, 17)[0] den IO-Status vom 17. digitalen Eingang auslest.
An die Variante von deinem Code dachte ich auch schon, allerdings wird serv_exit jedes mal überschrieben. Somit berücksichtigt die if-Abfrage nur die letzte Tasterabfrage.
Leider nein. Daran verzweifle ich eben, da der Roboter den Programmcode zyklisch, wie eine SPS abarbeitet und keine parllelen Befehle erlaubt.
Alle Roboterbefehle in der dazugehörigen Entwicklungsumgebung beginnen mit dType. Wie genau diese Befehle arbeiten, weiß ich nicht und der Hersteller beschreibt diese auch nicht näher. Er beschreibt lediglich, dass z.B. dType.GetIODI(api, 17)[0] den IO-Status vom 17. digitalen Eingang auslest.
An die Variante von deinem Code dachte ich auch schon, allerdings wird serv_exit jedes mal überschrieben. Somit berücksichtigt die if-Abfrage nur die letzte Tasterabfrage.
Leider nein. Daran verzweifle ich eben, da der Roboter den Programmcode zyklisch, wie eine SPS abarbeitet und keine parllelen Befehle erlaubt.
Wenn es darum geht serv_status high zu halten, wenn es das einmal war, dann geht natuerlich auch
Dann reicht ein einziges mal den Status auf True zu setzen, und serv_status bleibt so.
Code: Alles auswählen
serv_status = False
while True:
serv_status |= abfrage()
Funktioniert das ganze auch, wenn die Abfrage kein True bzw. False ausgibt, sondern stattdessen 0 und 1 also einen Zahlenwert vom Datentyp uint8_t? Wenn ja, wie halte ich serv_status auf 1 bzw. auf 0?
Und was genau macht der Operator |= ?
Und was genau macht der Operator |= ?