Seite 1 von 1
Paralellanweisung in der Scheife
Verfasst: Dienstag 23. Dezember 2014, 16:47
von firstfacility
Hallo Forum,
ich schreibe nun hier das es meiner Meinung nach nichts mehr mit Tkinter zu tun hat. Falls das falsch sein sollte bitte verschieben.
Ich habe ein Problem mit einer Schleife zu dem ich eine weitere Anweisung brauch wären der Rest weiterläuft. Ich bin totaler Anfänger und ich hoffe, das ich nicht gleich mit meinem Code an die Wand gestellt werde. Ist ja schließlich Weihnachten,

.
Was ich bisher verstanden habe ist das die Anweisungen in einer Schleife nacheinander abgearbeitet werden. So habe ich ja meinen Code auch aufgebaut. Der läuft auch soweit ... na ja fast aber dazu später mehr.
Code: Alles auswählen
def callback():
count = 0
count2 = 0
while (count < 25):
print 'The count is:', count2
count = count + 1
count2 = count + 1
label["text"] = count
label.update()
delay = 10
steps = 80
forward(int(delay) / 1000.0, int(steps))
time.sleep(1)
GPIO.setup(9, GPIO.OUT)
time.sleep(1)
GPIO.setup(9, GPIO.IN)
time.sleep(5)
steps = 80
backwards(int(delay) / 1000.0, int(steps))
count2max = 20
if (count2 >= count2max):
count2 = 0
count2 = count +1
GPIO.setup(29, GPIO.OUT)
time.sleep(1)
GPIO.setup(29, GPIO.IN)
print "counter zurckgesetzt"
label = Label(master, text="0", fg="dark red", font = "Times 45")
label.grid(row=3, column=1)
Wie ihr sicher leicht erkennen könnt läuft dort ein Counter der den Hauptprozess mitzählt und an eine GUI ausgibt. Weiterhin wird ein Relais über GPIO zwischendurch geschaltet. Weiterhin soll alle 20 Zählungen ein weiterer Schalter bedient werden. Leider wird der zweite Counter nicht nach erreichen von 20 auf 0 gesetzt. Aber einmal wird das Relais angesteuert.
Aber nun zu meinem Hauptproblem, ich würde gern parallel zum Hauptprozess eine weitere Anwendung starten ohne den Hauptprozess zu unterbrechen. Und dort hört es nun auf ich habe überhaupt keine Idee wie ich das machen könnte. Aber vielleicht gibt es einen netten User der mir helfen kann. Aber bitte gaanz laangsam, wie ich schon sagte bin totaler Anfänger.
Schon mal besten dank für eure Hilfe.
Gruß
Frank
Re: Paralellanweisung in der Scheife
Verfasst: Dienstag 23. Dezember 2014, 17:04
von Sirius3
@firstfacility: count2 ist immer 1 größer als count. Dafür sorgst Du in Zeile 7 und 23. Die Klammern um Bedingungen sind überflüssig, genauso alle int-Aufrufe. Eine Variable auf eine Konstante Zahl zu setzen, um sie in der darauffolgenden Zeile zu verwenden, sieht ein bißchen komisch aus. Sollten das Konstanten sein, werden diese am besten am Anfang der Datei definiert.
Re: Paralellanweisung in der Scheife
Verfasst: Dienstag 23. Dezember 2014, 17:37
von BlackJack
@firstfacility: Man darf in Rückruffunktionen bei GUIs nichts machen was ”länger” dauert, also insbesondere keine Schleifen in denen mit `sleep()` sekundenlange Pausen entstehen. Die GUI ruft diese `callback()`-Funktion ja auf und solange die läuft kann die GUI-Hauptschleife nicht laufen und solange wird die GUI nicht aktualisiert und reagiert nicht auf den Benutzer.
Man muss solche Schleifen entweder auf Einzelaufrufe herunterbrechen und über die `after_idle()`-Methode auf Widgets, beziehungsweise wenn `time.sleep()` darin vorkommt, diese auch noch durch die `after()`-Methode ersetzen, oder man muss Threads über das `threading`-Modul verwenden um einen nebenläufigen Programmablauf zu erzeugen. Im letzteren Fall muss man drauf achten das die GUI nur aus dem Hauptthread in dem auch die GUI-Hauptschleife läuft verändert werden darf, sonst ist das Verhalten des Programms undefiniert und es kann zu komischem Verhalten bis hin zu harten Abstürzen kommen. Üblicherweise kommuniziert man zwischen den beiden Theads deshalb über eine `Queue.Queue` und testet auf der GUI-Seite mit `after()` regelmässig ob da Daten übermittelt wurden und verarbeitet diese entsprechend.
Die *zwei* Zählvariablen erscheinen mir übertrieben. Man könnte auch *eine* Verwenden und mit der Modulo-Operation prüfen ob die durch 20 teilbar ist und das als Bedingung verwenden.
Etwas zu schalten in dem man die Ein-/Ausgang-Eigenschaft eines Pins umkonfiguriert erscheint mir falsch. Wenn man etwas schalten will, dann konfiguriert man den jeweiligen Pin als Ausgang und legt dann entweder Strom an oder nicht.
Re: Paralellanweisung in der Scheife
Verfasst: Dienstag 23. Dezember 2014, 20:01
von firstfacility
@BlackJack
threading war das richtige Stichwort besten Dank dafür, wobei ich im Netz auf die schnelle nur Beschreibungen gefunden habe die echt bescheiden sind. Grade als Anfänger schwer zu verstehen. Aber es geht also läuft schon.
Das läuft auf einen Rapi, die GPIOs sind super empfindlich vn daher reicht es schon aus GPIO high oder low zu schalten. Keine gute Lösung, aber eine Lösung ich habe schon so einige Anwendungen umgesetzt und die laufen alle noch.
Die Schleifen in die Einzelaufrufe zu bringen kommt mal ganz oben auf meine TO DO-Liste für das nächste Jahr. Was ich aber gern noch machen würde wäre die Modulo-Operation. Ich habe leider nichts sinnvolles im Netz gefunden, zumindest habe ich es nicht verstanden. Dürfte ich dich bitten mir anhand meines Codes ein Beispiel zu geben ?
Danke schon mal und Gruß
Frank
Re: Paralellanweisung in der Scheife
Verfasst: Dienstag 23. Dezember 2014, 20:51
von BlackJack
@firstfacility: `threading` ist auch für Nicht-Anfänger nicht immer einfach. Nebenläufige Programmierung hat so ihre Tücken.
Ähm ich meinte ja du *solltest* die GPIOs auf high oder low schalten. Genau das machst Du ja *nicht*, sondern höchstens implizit. So ist das aber nicht gedacht, auch wenn das funktionieren mag. Das ist so ein bisschen so als würdest Du eine Lampe in einem Zimmer an- und ausschalten in dem Du die Sicherung für den Stromkreis rein- und rausdrehst, statt den Schalter von der Lampe zu benutzen. Das geht zwar, ist aber nicht der dafür vorgesehene Weg.
Ad Modulo: Das gibt den Rest einer Division. Und der ist nur dann 0 wenn die Division glatt aufgeht. Wenn Du in Deinem Code den Zähler Modulo 20 rechnest kommt da alle 20 Schleifendurchläufe 0 heraus.
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 18:19
von firstfacility
Ich habe die letzten Tage genutzt um die Dinge umzusetzen und nach viel Nachlesen bin ich auch fast soweit. Auch kann ich inzwischen rechnen unter python, geht eigentlich ganz einfach wenn ich nicht immer um die Ecke denken würde. Aber gut eine Frage bleibt noch:
Ich würde ....nein ich muss... einen Notschalter einbauen. Ich könnte nun Hardwareseitig diese Funktion umsetzten, finde ich aber nicht so toll da ich ja schon mal dabei bin. Nach einigen Nachlesen habe ich einiges gefunden wie ich mit einem Schalter Anwendungen stoppen bzw. beenden kann. Aber wie kann ich mein script in die Pause schicken.
Code: Alles auswählen
Gif1 = PhotoImage(file="/root/Schalter_Kopie.gif")
MyLabel2 = Label(master, image=Gif1)
MyLabel2.grid(row=4, column=0)
def Interrupt_event(pin):
global MyLabel1
if GPIO.input(27): # if 27 == 1
print("Rising edge detected on %s"%pin)
MyLabel1["text"] = "Notchalter ist aus"
else: # if 27 != 1
print("Falling edge detected on %s"%pin)
MyLabel1["text"] = "Notchalter ist an"
wait = GPIO.input(27)
# evtl raise SystemExit
GPIO.add_event_detect(27, GPIO.BOTH, callback=Interrupt_event)
MyLabel1 = Label(master, text="Notschalter ist aus")
MyLabel1.grid(row=4, column=0)
MyStatus = Label(master, text="Prozessstatus", bd=1, relief=SUNKEN, anchor=W, width=25, height=4, backgroun
d="yellow")
MyStatus.grid(row=4, column=1)
Wie Ihr erkennen könnte habe ich einen Interrupt der auf den GPIO lauscht und bekannt gibt wenn Notschalter gedrückt. Vorteil von einem Notschalter ist das er erst wieder entriegelt werden muss, also der Status beim GPIO bleibt. Die Ausgabe Tkinter läuft soweit aber der Rest noch ohne Funktion.
Also die Frage wäre wie kann ich mein Script anhalten, hätte jemand eine Idee ?
Gruß
Frank
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 19:17
von lackschuh
Hallo
Was bezweckt das "global MyLabel1"?
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 19:29
von firstfacility
auf der GUI wird ein Text eingeblendet ob der Schalter ein oder aus ist.
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 19:35
von BlackJack
@firstfacility: Das erklärt aber immer noch nicht das ``global``. Wozu soll das gut sein?
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 19:59
von firstfacility
der Interrupt ändert in Mylabel1 den Text von Der Notschalter ist aus zu Der Notschalter ist an. Das Würde er nicht machen wenn ich nicht Mylabel1 auf Global setzte. Wahrscheinlich gibt's noch 10 andere Wege aber ich sage nochmal das es meine ersten Gehversuche in Sachen Python sind.
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 20:16
von BlackJack
@firstfacility: Am Programmablauf würde sich genau *gar nichts* ändern wenn Du das ``global`` da raus nimmst. Das ist schlicht überflüssig.
Re: Paralellanweisung in der Scheife
Verfasst: Montag 29. Dezember 2014, 20:42
von firstfacility
ok, dann nehme ich das raus. Hätte noch jemand einen Tipp für den Notschalter ?
Re: Paralellanweisung in der Scheife
Verfasst: Donnerstag 1. Januar 2015, 23:21
von firstfacility
keiner eine Idee für mein Problem ??