Seite 1 von 1

Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 07:09
von wiesam
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

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 08:57
von __deets__
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.

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 13:44
von wiesam
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.

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

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 14:10
von __deets__
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

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

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 14:37
von wiesam
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.

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 14:39
von __deets__
Wenn es darum geht serv_status high zu halten, wenn es das einmal war, dann geht natuerlich auch

Code: Alles auswählen

serv_status = False
while True:
     serv_status |= abfrage()
Dann reicht ein einziges mal den Status auf True zu setzen, und serv_status bleibt so.

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 15:04
von wiesam
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 |= ?

Re: Interruptroutine in Python

Verfasst: Dienstag 2. Oktober 2018, 15:21
von __deets__
Ja und

x |= y <=> x = x | y

Und warum das geht kannst du dir mit Stift und Papier mal klar machen fuer verschiedene Werte y.

Re: Interruptroutine in Python

Verfasst: Mittwoch 3. Oktober 2018, 11:27
von wiesam
Klingt alles logisch und funktioniert.
Jetzt sollte der Roboter nur noch eine höhere Rechenleistung haben, damit er auch den IO-Port richtig und in Echtzeit erkennt...

Re: Interruptroutine in Python

Verfasst: Mittwoch 3. Oktober 2018, 13:16
von __deets__
Das sollte eigentlich (roboterseitig) eigentlich kein Problem darstellen. Gibt es dafuer keine Dokumentation, in der man sowas mal nachschauen kann?