Pi4 als Schiessampelsteuerung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

Hallo zusammen.
Bin jetzt schon eine Weile dran ein Programm zu schreiben, dass eine Schiessampel nach der World Archery durchführen kann.
Leider habe ich im Moment einige Probleme damit:

Die GPIO. Eingänge, die ich über Taster mit 10K Pullup Widerständen angeschlossen habe, kann ich zwar mit folgendem Skript abrufen, jedoch klappt der Startbefehl im eigentlichen Programm nicht.

Code: Alles auswählen

#!/usr/bin/python3
from RPi import GPIO
from os import system, name
import time
import sys

GPIO.setmode(GPIO.BCM)   #Art der Pin-Nummerierung

GPIO.setup(20, GPIO.IN)   #NOT
GPIO.setup(16, GPIO.IN)   #LICHT
GPIO.setup(12, GPIO.IN)   #TREFFER
GPIO.setup(25, GPIO.IN)   #FERTIG
GPIO.setup(24, GPIO.IN)   #STECHEN
GPIO.setup(23, GPIO.IN)   #MANN
GPIO.setup(18, GPIO.IN)   #4MIN
GPIO.setup(26, GPIO.IN)   #2MIN

try:
	while True:   # Endlosschleife, mit Strg-C beenden
		input1 = GPIO.input(20)
		print("NOT: " + str(input1))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input2 = GPIO.input(16)
		print("LICHT: " + str(input2))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input3 = GPIO.input(12)
		print("TREFFER: " + str(input3))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input4 = GPIO.input(25)
		print("FERTIG: " + str(input4))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input5 = GPIO.input(24)
		print("STECHEN: " + str(input5))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input6 = GPIO.input(23)
		print("MANN: " + str(input6))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input7 = GPIO.input(18)
		print("4MIN: " + str(input7))   #Ausgabe auf Bildschirm
		time.sleep (0.1)   #kurze Pause
		input8 = GPIO.input(26)
		print("2MIN: " + str(input8))   #Ausgabe auf Bildschirm
		time.sleep (2.0)   #kurze Pause
		system('clear')
except KeyboardInterrupt:
        GPIO.cleanup()
Ebenfalls funktioniert bei der Wait_for_stop funktion, über die Tastatur, der Übersprung in der umschalten Funktion nicht.
Ich würde gern haben, dass wenn während der grün Phase s gedrückt wird, die Ampel auf rot geht, andernfalls die gelb Phase ausgeführt wird und auch hier mit dem Tastendruck dies abgrebrochen werden kann.
Sowohl die Augangsrelais als auch die Taster habe ich Low aktiv.
Anbei der Code. Bin um jede Hilfe und jeden Link dankbar.

Code: Alles auswählen

#!/usr/bin/python3.7

from RPi import GPIO
from os import system, name
import time
import sys
import termios
import tty

ROT = 17
GELB = 27
GRUEN = 22
HUPE = 13
AB = 5
CD = 6
LED = 21
RES = 19
STARTA = 26
STARTB = 18
MANN = 23
STECHEN = 24
FERTIG = 25
TREFFER = 12
LICHT = 16
NOT = 20
flag = False

def inkey(timeout=None):
    fd=sys.stdin.fileno()
    remember_attributes=termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    attributes = termios.tcgetattr(fd)
    if timeout is not None:
        attributes[-1][termios.VMIN] = 0
        attributes[-1][termios.VTIME] = timeout
    termios.tcsetattr(fd,termios.TCSADRAIN, attributes)
    character=sys.stdin.read(1)
    termios.tcsetattr(fd,termios.TCSADRAIN, remember_attributes)
    return character

def initialize():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(ROT, GPIO.OUT) #rot
    GPIO.setup(GELB, GPIO.OUT) #gelb
    GPIO.setup(GRUEN, GPIO.OUT) #gruen
    GPIO.setup(HUPE, GPIO.OUT) #HUPE
    GPIO.setup(AB, GPIO.OUT) #AB
    GPIO.setup(CD, GPIO.OUT) #CD
    GPIO.setup(LED, GPIO.OUT) #LED-Strahler
    GPIO.setup(RES, GPIO.OUT) #Reserve
    GPIO.setup(STARTA, GPIO.IN) #Start 2 Min.
    GPIO.setup(STARTB, GPIO.IN) #Start 4 Min.
    GPIO.setup(MANN, GPIO.IN) #Mannschaft
    GPIO.setup(STECHEN, GPIO.IN) #Stechen
    GPIO.setup(FERTIG, GPIO.IN) #Schuetzen fertig
    GPIO.setup(TREFFER, GPIO.IN) #Trefferaufnahme
    GPIO.setup(LICHT, GPIO.IN) #Lichtschalter
    GPIO.setup(NOT, GPIO.IN) #notfall
    GPIO.output(ROT, True)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, True)
    GPIO.output(HUPE, True)
    GPIO.output(AB, True)
    GPIO.output(CD, True)
    GPIO.output(LED, True)
    GPIO.output(RES, True)
    
def rot_hupe(three=False, two=False):
    GPIO.output(ROT, False)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, True)
    GPIO.output(HUPE, False)
    time.sleep(0.5)
    GPIO.output(HUPE, True)
    if three:
        time.sleep(0.5)
        GPIO.output(HUPE, False)
        time.sleep(0.5)
        GPIO.output(HUPE, True)
        time.sleep(0.5)
        GPIO.output(HUPE, False)
        time.sleep(0.5)
        GPIO.output(HUPE, True)
    elif two:
        time.sleep(0.5)
        GPIO.output(HUPE, False)
        time.sleep(0.5)
        GPIO.output(HUPE, True)

def gelb():
    GPIO.output(GRUEN, True)
    GPIO.output(GELB, False)
    GPIO.output(ROT, True)

def gruen_hupe():
    GPIO.output(ROT, True)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, False)
    GPIO.output(HUPE, False)
    time.sleep(0.5)
    GPIO.output(HUPE, True)

def notfall():
    rot_hupe(three=True)
    GPIO.output(AB, True)
    GPIO.output(CD, True)
    time.sleep(10)
    GPIO.output(ROT, True)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, True)
    GPIO.output(AB, True)
    GPIO.output(CD, True)
    GPIO.output(HUPE, True)
    main()

def trefferaufnahme(flag):
    while inkey() == 't' or GPIO.input(TREFFER) == False:
        break

def wait_for_stop(timeout, flag):
    stop_time = time.monotonic() + timeout
    while stop_time >= time.monotonic():
        key = inkey(timeout=1)
        if key == 's' and flag == False or GPIO.input(FERTIG) == False and flag == False:
            flag = True
            return flag
        elif key == 'e':
            notfall()
            main()

def umschalten(timeout, flag):
    flag = False
    GPIO.output(AB, False)
    rot_hupe(two=True)
    time.sleep(10)
    gruen_hupe()
    wait_for_stop(timeout, flag)
    if flag == False:
        gelb()
        wait_for_stop(30, flag)
    rot_hupe(two=True)
    GPIO.output(AB, True)
    GPIO.output(CD, False)
    time.sleep(20)
    flag = False
    gruen_hupe()
    wait_for_stop(timeout, flag)
    if flag == False:
        gelb()
        wait_for_stop(30, flag)
    rot_hupe(three=True)
    flag = False
    trefferaufnahme(flag)
    rot_hupe(two=True)
    time.sleep(10)
    gruen_hupe()
    wait_for_stop(timeout, flag)
    if flag == False:
        gelb()
        wait_for_stop(30, flag)
    rot_hupe(two=True)
    GPIO.output(CD, True)
    GPIO.output(AB, False)
    flag = False
    time.sleep(20)
    gruen_hupe()
    wait_for_stop(timeout, flag)
    if flag == False:
        gelb()
        wait_for_stop(30, flag)
    rot_hupe(three=True)

def start(timeout):
    for d in range(6):
        umschalten(timeout, flag)
        trefferaufnahme(flag)
    aus()
    main()

def aus():
    GPIO.output(ROT, True)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, True)
    GPIO.output(AB, True)
    GPIO.output(CD, True)
    GPIO.output(HUPE, True)

def stechen():
    rot_hupe(two=True)
    time.sleep(10)
    gruen_hupe()
    wait_for_stop(10, flag)
    gelb()
    wait_for_stop(30, flag)
    rot_hupe(three=True)
    trefferaufnahme()
    GPIO.output(ROT, True)
    GPIO.output(GELB, True)
    GPIO.output(GRUEN, True)
    GPIO.output(AB, True)
    GPIO.output(CD, True)
    GPIO.output(HUPE, True)
    GPIO.cleanup()
    main()

def main():
    try:
        initialize()
        system('clear')
        print("2 = 2 Minuten \n")
        print("4 = 4 Minuten \n")
        print("m = Mannschaft \n")
        print("x = Stechpfeil \n")
        print("e = Sofort Ende \n")
        print("s = Schuetzen fertig \n")
        print("t = Trefferaufnahme fertig \n")
        print("l = Lichtschalter \n")
        licht_an = True
        while True:
            time.sleep(0.1)
            sys.stdin.flush()
            key = inkey()
            if key == '2' or GPIO.input(STARTA) == False:
                start(90)
            elif key == '4' or GPIO.input(STARTB) == False:
                start(210)
            elif key == 'm' or GPIO.input(MANN) == False:
                start(50)
            elif key == 'e' or GPIO.input(NOT) == False:
                notfall()
            elif key == 'x' or GPIO.input(STECHEN) == False:
                stechen()
            elif key == 'l' or GPIO.input(LICHT) == False:
                licht_an = not licht_an
                GPIO.output(LED, licht_an)
    except KeyboardInterrupt:
        GPIO.cleanup()
    finally:
        print(" Neustart erforderlich.")
if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird mit 4 Leerzeichen pro Ebene, keine Tabs.
`GPIO.cleanup` muß immer aufgerufen werden, nicht nur bei Ctrl+C. Daher ja auch der finally-Block.
`sys` und `name` werden importiert aber nicht benutzt, sollte auch nicht benutzt werden.
`system` sollte nicht benutzt werden.

Code: Alles auswählen

#!/usr/bin/python3
from RPi import GPIO
import time

PINS = {
    20: "NOT",
    16: "LICHT",
    12: "TREFFER",
    25: "FERTIG",
    24: "STECHEN",
    23: "MANN",
    18: "4MIN",
    26: "2MIN",
}

def main():
    GPIO.setmode(GPIO.BCM)   #Art der Pin-Nummerierung
    GPIO.setup(PINS.keys(), GPIO.IN)

    try:
        while True:   # Endlosschleife, mit Strg-C beenden
            for pin, name in PINS.items():
                input = GPIO.input(pin)
                print(f"{name}: {input}")
            time.sleep(2.0)
    finally:
        GPIO.cleanup()

if __name__ == '__main__':
    main()
Im Eigentlichen Programm hast Du eine globale Variable `flag`, die zum Glück nicht verwendet wird. `trefferaufnahme` hat ein `flag`-Argument das nicht benutzt wird.
In `umschalten` hast Du ein flag-Argument, das aber gleich wieder überschrieben wird. Später wird mit flag verglichen, was aber unsinnig ist, weil das Ergebnis eh fix ist.
An vielen Stellen wird `main` aufgerufen, was ein Fehler ist. Statt Rekursion ist eine Schleife das richtige. Es darf also im ganzen Programm nur einen Aufruf von main geben, und zwar ganz unten. So wie es jetzt ist, ist der Programmablauf total chaotisch.
cleanup steht, wie oben schon geschrieben, an der falschen Stelle.

Zum eigentlichen Problem: das ist nicht einfach lösbar, da Du ja auf einen Tastendruck wartest, kannst Du nicht so einfach auch auf GPIOs warten. Das geht sauber nur per Callbacks, Threads und Queues.
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

OK, viel Input.
Der eigentliche Gedanke war eine globale flag zu erstellen, die in die Funktionen übergeben wird.
Dein Beispielcode bringt mir bei GPIO.setup(PINS.keys(), GPIO.IN) einen Abbruch mit der Meldung
ValueError: Channel must be an integer or list/tuple of integers.
import sys wird für den system('clear') im main() verwendet um die Seite neu aufzubauen, aber du darfst mich gern korregieren, wenn ich mich irre.
Für die Callbacks, Threads oder Queues würde ich mich über einen Link freuen, wo evtl. ein ähnliches Problem behandelt wird.
( Tastendruck, oder GPIO.input)
Eventuell hat einer schonmal sowas gemacht und kann mir nen Link dazu nennen?
Und eine Frage hätte ich da noch: Wie hast du gesehen, dass ich Tabs genommen habe, da 4 Leerstellen einem Tabstop entsprechen?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann braucht GPIO.setup offensichtlich eine Liste.

Code: Alles auswählen

GPIO.setup(list(PINS.keys()), GPIO.IN) 
Statt os.system benutzt man subprocess.run, obwohl Consolenprogramme nicht ungefragt den Bildschirm löschen sollten.
Tabs sieht man im Forum, da sie 8 Leerstellen entsprechen. Das ist auch das Problem mit Tabs.
Bevor Du etwas neues hinzufügst, solltest Du erst den alten Code aufräumen.

Und der klarere Weg wäre, einfach `inkey` so zu erweitern, dass es beim entsprechenden GPIO ein passendes Zeichen zurückgibt.
Such einfach ein bißchen hier im Forum, da gibt es Beispiele zu Queues und Callbacks
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

So, habe mich jetzt mit dem Callback und inkey Funktion erweitern beschäftig.
Leider bekomm ich nirgends Informationen, wie ich ein Char in die inkey Funktion zurück schreiben kann.
Die Einrückungen sind ebenfalls aufgeräumt.
Ich vermute mal das bei dem beigefügten Code mein return nicht so funktioniert wie ich es gern hätte.

Code: Alles auswählen

def taster_callback(channel):
    global time_stamp
    time_now = time.time()
    if (time_now - time_stamp) >= 0.3:
        if GPIO.input(26):
            GPIO.remove_event_detect(26)
            return '2'
Aufgerufen wird das ganze im main mit:

Code: Alles auswählen

GPIO.add_event_detect(26, GPIO.RISING, callback = taster_callback, bouncetime=300)
Das return '2' sollte mir eigentlich die Taste 2 auslösen, um über die inkey Funktion dann den weiteren Programmschritt aufzurufen.
Kann mir einer von euch sagen was ich falsch mache?
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Straggle: Vergiss das es ``global`` gibt.

Das ``return`` gibt einen Wert an den Aufrufer zurück. Der ist hier irgendwas was Du nicht kennst und das keine Ahnung hat was es mit der "2" anfangen soll.

`remove_event_detect()` ist keine gute Idee, das macht komische Probleme. Die `RPi.GPIO` ist an sich schon keine so gute Idee. `gpiozero` hat die deutlich bessere API.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

OK, hab gerade im Internet nachgesehen: remove_event_detect() ist keine gute Idee.
Vielleicht war meine Frage auch etwas falsch gestellt.
Wenn ich anstatt return '2' return print('2') schreibe bekomme ich die Ausgabe in der Console angezeigt.
Wie kann ich aber anstatt die Ausgabe auf die Console auszugeben, diese an stdin in der inkey Funktion übergeben?
Der Aufrufer ist ja, so wie ich das sehe, die add_event_detect Zeile, oder liege ich da falsch?
Somit sollte doch die 2 ins Main übergeben werden, was mir nicht weiterhilft, da die Zahl ja in die inkey Funktion sollte, damit auch die gewünschte Funktion ausgeführt wird.
Für das global kann ich mir später was überlegen, bzw. die Zeitfunktion im callback kann ich vermutlich auch entfernen, da eine bouncezeit im event festgelegt ist, oder ist das auch nicht korrekt?
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist ja schon erwaehnt worden, wie man diese Werte in das Hauptprogramm bekommt - mit einer Queue. Und du liegst falsch, dass der Aufrufer add_event_detect ist. Das meldet nur an, dass du benachrichtigt werden willst.
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

Erstmal Danke für eure Bemühungen.
Leider stehe ich immer noch ein bisschen auf dem Schlauch:

Code: Alles auswählen

#!/usr/bin/python3

from RPi import GPIO
import sys, termios, tty
from queue import Queue
from time import sleep, monotonic
from os import system
from functools import partial

ROT = 17
GELB = 27
GRUEN = 22
HUPE = 13
AB = 5
CD = 6
LED = 21
RES = 19
IN_PINS = [26, 18, 23, 24, 25, 12, 16, 20] 
#STARTA=26, STARTB=18, MANN=23, STECHEN=24, FERTIG=25, TREFFER=12, LICHT=16, NOT=20
flag = False

def inkey(timeout=None):
    fd=sys.stdin.fileno()
    remember_attributes=termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    attributes = termios.tcgetattr(fd)
    if timeout is not None:
        attributes[-1][termios.VMIN] = 0
        attributes[-1][termios.VTIME] = timeout
    termios.tcsetattr(fd,termios.TCSADRAIN, attributes)
    character=sys.stdin.read(1)
    termios.tcsetattr(fd,termios.TCSADRAIN, remember_attributes)
    return character

def initialize():

def callback(queue, channel):
    queue.put(channel)
    taster = queue.get()
    if taster == 26:
        print("Taster")
        return queue.put('2')
    elif taster == 18:
        return queue.put('4')
    elif taster == 23:
        return queue.put('m')
    elif taster == 20:
        return queue.put('e')
    elif taster == 24:
        return queue.put('x')
    elif taster == 16:
        return queue.put('l')
    elif taster == 12:
        return queue.put('t')
    elif taster == 25:
        return queue.put('s')
    else: return queue
    
def rot_hupe(three=False, two=False):

def gelb():
    
def gruen_hupe():
    
def notfall():

def trefferaufnahme():
    while inkey() != 't':
        pass

def wait_for_stop(timeout):
    global flag
    stop_time = monotonic() + timeout
    while stop_time >= monotonic():
        key = inkey(timeout=1)
        if key == 's' and flag == False or GPIO.input(25) == 0 and flag == False:
            flag = True
            return flag
        elif key == 'e':
            notfall()

def umschalten(timeout):

def start(timeout):

def aus():

def stechen():

def main():
    try:
        initialize()
        system('clear')
        queue = Queue()
        GPIO.add_event_detect(26, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(18, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(23, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(24, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(25, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(12, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(16, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        GPIO.add_event_detect(20, GPIO.RISING, callback = partial(callback, queue), bouncetime=300)
        print("2 = 2 Minuten \n")
        print("4 = 4 Minuten \n")
        print("m = Mannschaft \n")
        print("x = Stechpfeil \n")
        print("e = Sofort Ende \n")
        print("s = Schuetzen fertig \n")
        print("t = Trefferaufnahme fertig \n")
        print("l = Lichtschalter \n")
        licht_an = True
        while True:
            sleep(0.1)
            #STARTA=26, STARTB=18, MANN=23, STECHEN=24, FERTIG=25, TREFFER=12, LICHT=16, NOT=20
            sys.stdin.flush()
            key = inkey()
            if key == '2':
                print (queue.get())
                start(90)
            elif key == '4':
                start(210)
            elif key == 'm':
                start(50)
            elif key == 'e':
                notfall()
            elif key == 'x':
                stechen()
            elif key == 'l':
                licht_an = not licht_an
                GPIO.output(LED, licht_an)
    finally:
        GPIO.cleanup()
        print(" Neustart erforderlich.")
if __name__ == '__main__':
    main()
In den Callback habe ich versucht eine Queue einzubinden, die mir die dementsprechenden Rückgabezeichen sendet. Wie ich diese jetzt in die inkey Funktion bekomme ist mir leider immer noch nicht klar?
Was ich auch nicht versteh ist, das der GPIO.input(25) in der wait for stop Funktion über Tasterdruck funktioniert.
Über die globale flag möchte ich mich im Moment noch nicht unterhalten. Darum kann ich mich später kümmern.
Nicht relevante Teile des Codes habe ich herausgekürzt.
Die Bildschirmausgabe Taster bekomme ich auf den Bildschirm, ebenfalls das print (queue.get()) nach dem Tasterdruck, wenn ich 2 auf der Tastatur drücke. Also wird in die return queue.put('2') nicht wirklich eine 2 hinterlegt sondern die 26.
Ist schon wieder spät. Hat einer von euch noch eine Idee mich in die richtige Richtung zu schubsen?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll denn der Unsinn, etwas in die Queue zu packen um es gleich wieder rauszulesen?
Warum hast Du das `wait_for_stop` schon wieder so umständlich geschrieben, statt, wie ich es Dir gezeigt habe, einfach per Exception gelöst?

Code: Alles auswählen

#!/usr/bin/python3
from RPi import GPIO
import sys, termios, tty
from queue import Queue, Empty
from time import sleep, monotonic
from functools import partial

ROT = 17
GELB = 27
GRUEN = 22
HUPE = 13
AB = 5
CD = 6
LED = 21
RES = 19

KEY_PINS = {
    26: '2',
    18: '4',
    23: 'm',
    20: 'e',
    24: 'x',
    16: 'l',
    12: 't',
    25: 's',
}

def callback(queue, key, _):
    queue.put(key)

def initialize():
    queue = Queue()
    for pin, key in KEY_PINS.items():
        GPIO.setup(pin, GPIO.IN)
        GPIO.add_event_detect(pin, GPIO.RISING, callback=partial(callback, queue, key), bouncetime=300)
    return queue

def inkey(queue, clear=True, timeout=None):
    if clear:
        while not queue.empty():
            queue.get()
        sys.stdin.flush()
    fd=sys.stdin.fileno()
    remember_attributes=termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    attributes = termios.tcgetattr(fd)
    attributes[-1][termios.VMIN] = 0
    attributes[-1][termios.VTIME] = 0
    termios.tcsetattr(fd,termios.TCSADRAIN, attributes)
    if timeout is not None:
        end_time = monotonic() + timeout
    else:
        end_time = float('inf')
    while True:
        try:
            character = queue.get_nowait()
        except Empty:
            pass
        else:
            break
        character = sys.stdin.read(1)
        if character:
            break
        if monotonic() > end_time:
            return None
    termios.tcsetattr(fd,termios.TCSADRAIN, remember_attributes)
    return character

def wait_for_stop(queue, timeout):
    stop_time = monotonic() + timeout
    while stop_time >= monotonic():
        key = inkey(queue, timeout=1)
        if key == 's':
            return True
        elif key == 'e':
            raise KeyboardInterrupt()

def main():
    try:
        queue = initialize()
        print("2 = 2 Minuten \n")
        print("4 = 4 Minuten \n")
        print("m = Mannschaft \n")
        print("x = Stechpfeil \n")
        print("e = Sofort Ende \n")
        print("s = Schuetzen fertig \n")
        print("t = Trefferaufnahme fertig \n")
        print("l = Lichtschalter \n")
        licht_an = True
        while True:
            key = inkey(queue, clear=True)
            if key == '2':
                start(90)
            elif key == '4':
                start(210)
            elif key == 'm':
                start(50)
            elif key == 'e':
                notfall()
            elif key == 'x':
                stechen()
            elif key == 'l':
                licht_an = not licht_an
                GPIO.output(LED, licht_an)
    finally:
        GPIO.cleanup()
        print(" Neustart erforderlich.")

if __name__ == '__main__':
    main()
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

Danke für die Korrektur.
Darf ich Fragen wie lange du schon Python programmierst?
Ist eine elegante Lösung mit der Pin-Liste.
Werde wenn ich fertig bin das ganze noch auskommentieren.
Vielen Dank nochmal. :D
Straggle
User
Beiträge: 13
Registriert: Sonntag 27. September 2020, 16:42

Eine Frage hätte ich aber noch:
Hab hier einen Presenter der pageup und pagedown sendet. Wie bekomm ich den auch in die inkey Abfrage?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Solche Presenter schicken ja normalerweise ganz normale Tasteneingaben. Du mußt halt schauen, welche Zeichenfolge bei pageup und pagedown kommen.
Antworten