Hallo Leute,
für ein Uni Projekt muss ich über einen Raspberry eine Relaiskarte ansteuern. Das klappt bisher auch schon ganz gut. Das Problem war nun, nachdem ich die GUI erstellt hatte, dass ich nicht weiss, wie ich ggf. mehrere Relais unterschiedlich lange ansteuern kann.
Theoretisch gibt es 12 Relais und diese sollen alle unterschiedlich lange angeschaltet bleiben, aber alle gleichzeitig starten.
Zur veranschaulichung habe ich hier mal einen Screenshot der GUI:
Also im Endeffekt sollen in der Anwendung die jeweiligen Ventile gecheckt werden, dann die entsprechende Zeit der einzelnen Ventile gesetzt werden und danach alle gleichzeitig durch den Startbutton für die gesetzte Zeit geöffnet werden. Wenn ich das mit einer Schleife probiere, dann wartet der Raspberry so lange, bis die time.sleep abgelaufen ist und macht danach mit dem nächsten Ventil weiter - so wie es eben nicht sein soll. Fällt euch vielleicht etwas dazu ein?
Danke im Vorraus
GPIO: Ventile parallel und unterschiedlich lange ansteuern
GUIs darf man nicht blockieren. Sondern muss mit Timern arbeiten. Da du nicht verraetst welches Toolkit du benutzt kann man nur raten - mit tkinter ist es die after-Methode, und mit Qt Qtimer. Wird hier alles oft und ausfuehlich diskutiert, such mal danach.
Hallo,
meine Ventile öffnen sich nun mit der after Methode! Alle gleichzeitig, bzw. mit 10ms verzögerung, was aber nicht weiter schlimm ist.
Wenn ich die after Methode richtig verstanden habe, dann sollte ein Ventil in meinem Code nach 4 Sekunden geschlossen werden (zweitletzte Codezeile/main.after(4000, GPIO.output(pinList[1], GPIO.HIGH))):
Offenbar habe ich die Methode aber doch nicht durchdrungen, da das Ventil nicht nach 4 Sekunden schließt, sondern nach gefühlt 10 ms.
Natrüclich werde ich da noch eine Schleife herumbauen, damit ich die Ventile/Relais einzeln konfigurieren kann. Zunächst möchte ich das eben mit nur einem testen.
Habt ihr vielleicht einen Anreiz wie es wirklich funktioniert? Danke im Voraus!
meine Ventile öffnen sich nun mit der after Methode! Alle gleichzeitig, bzw. mit 10ms verzögerung, was aber nicht weiter schlimm ist.
Wenn ich die after Methode richtig verstanden habe, dann sollte ein Ventil in meinem Code nach 4 Sekunden geschlossen werden (zweitletzte Codezeile/main.after(4000, GPIO.output(pinList[1], GPIO.HIGH))):
Code: Alles auswählen
def start(): #Function to start the Valves
print("Start")
pinList=[]
if bigUpperValve1.get()==1:
pinList.append(2)
if bigUpperValve2.get()==1:
pinList.append(3)
if bigUpperValve3.get()==1:
pinList.append(4)
if smallUpperValve1.get()==1:
pinList.append(17)
if smallUpperValve2.get()==1:
pinList.append(27)
if smallUpperValve3.get()==1:
pinList.append(22)
print ("Auf")
#st = bigUpperValve1Input.get()
#stFloat = int(st)
#st2 = bigUpperValve2Input.get()
#stFloat2 = int(st2)
#timeList = [stFloat, stFloat2]
for j in range(len(pinList)):
main.after(10, GPIO.output(pinList[j], GPIO.LOW))
j=j+1
main.after(4000, GPIO.output(pinList[1], GPIO.HIGH))
print ("Zu")
Natrüclich werde ich da noch eine Schleife herumbauen, damit ich die Ventile/Relais einzeln konfigurieren kann. Zunächst möchte ich das eben mit nur einem testen.
Habt ihr vielleicht einen Anreiz wie es wirklich funktioniert? Danke im Voraus!
Dein Verstaendnisproblem besteht darin, das du after mit einem CALLABLE versorgen musst. Also zB einer Funktion oder Methode. Und die soll aufgerufen werden, wenn der Timer abgelaufen ist. Was du stattdessen tust ist, einfach als zweites Argument einen Ausdruck anzugeben, der gleich ausgefuehrt wird. Und dessen Rueckgabewert dann an after uebergeben wird. Was im Zweifel None ist, und darum im Grunde gar nichts tut.
Ein Weg das zu aendern sind lambdas:
Und dann noch ein paar Anmerkungen: das inkrementieren von j ist ueberfluessig und wirkungslos. Streich also die Zeile. Dein Code enthaelt ausserdem deutlich zu viele magische Zahlen. Definier dir auf Modulebene Konstanten dafuer:
Der Vergleich mit 1 in deinen ganzen if-Ausdruecken ist aller Wahrscheinlichkeit nach unnoetig. Python betrachtet leere Werte und 0 als False, und den Rest als True. Ein einfaches
reicht.
Ein Weg das zu aendern sind lambdas:
Code: Alles auswählen
main.after(10, lambda j=j: GPIO.output(pinList[j], GPIO.LOW))
Code: Alles auswählen
LUFTSCHLEUSE_ZUR_HOELLE=23
Code: Alles auswählen
if smallUpperValve1.get():
pinList.append(17)
@DodgeRand: wenn die 10ms Verzögerung nicht schlimm ist, bzw. eigentlich nicht gewollt ist, warum benutzt Du dann überhaupt `after`? Und wenn Du 4 Ventile gleichzeitig schaltest, arum machst Du das in 4 getrennten `after`-Aufrufen?
Über einen Index zu iterieren, ist umständlich, weil man mit for direkt über die Elemente der Liste gehen kann.
Die if-Kette am Anfang solltest Du auch am besten über eine Datenstruktur abbilden. Funktionen sollten alles, was sie brauchen über ihre Argumente bekommen:
Über einen Index zu iterieren, ist umständlich, weil man mit for direkt über die Elemente der Liste gehen kann.
Die if-Kette am Anfang solltest Du auch am besten über eine Datenstruktur abbilden. Funktionen sollten alles, was sie brauchen über ihre Argumente bekommen:
Code: Alles auswählen
# beim Initialisieren, irgendwo im Code den Du nicht zeigst:
valves = {
2: big_upper_valve1,
3: big_upper_valve2,
4: big_upper_valve3,
17: small_upper_valve1,
27: small_upper_valve2,
22: small_upper_valve3,
}
def start(main, valves):
""" Function to start the Valves """
print("Start")
pins = []
for pin, valve in valves.items():
if valve.get() == 1:
pins.append(pin)
print ("Auf")
for pin in pins:
GPIO.output(pin, GPIO.LOW)
main.after(4000, lambda: GPIO.output(pins[1], GPIO.HIGH))
- __blackjack__
- User
- Beiträge: 13111
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Die `start()` liesse sich noch deutlich kürzen:
Code: Alles auswählen
def start(main, valves):
"""Start the valves."""
print('Start')
pins = [pin for pin, valve in valves.items() if valve.get() == 1]
print ('Auf')
GPIO.output(pins, GPIO.LOW)
main.after(4000, lambda: GPIO.output(pins, GPIO.HIGH))
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Abend,
sieht super aus Leute! Danke für die viele Unterstützung
Kenne mich leider noch nicht so gut in Python aus, daher wollte ich erstmal alles hart codiert testen. Freut mich aber, dass es auch wesentlich dynamischer geht und werde die letzten Vorschläge auch ausprobieren! Melde mich wenn alles läuft.
Danke nochmal und einen schönen restlichen Feiertag!
sieht super aus Leute! Danke für die viele Unterstützung
Kenne mich leider noch nicht so gut in Python aus, daher wollte ich erstmal alles hart codiert testen. Freut mich aber, dass es auch wesentlich dynamischer geht und werde die letzten Vorschläge auch ausprobieren! Melde mich wenn alles läuft.
Danke nochmal und einen schönen restlichen Feiertag!