[Python] Schleife per Tastendruck abbrechen (Raspi)


Gray

Erfahrenes Mitglied
#1
Hi,

ich hab ein Problem mit einem kleinen Python Script was auf einem Raspberry Pi läuft. Es läuft ein Timer ab und dieser soll per Tastendruck gestoppt bzw. abgebrochen werden.

Mein Problem ist das so lange diese Schleife läuft die den Timer anzeigt anscheinend auf keinen Tastendruck mehr reagiert wird.

Vollständiger Code

Code:
#!/usr/bin/env python
import RPi.GPIO as GPIO
import time

RoAPin = 15     # pin11
RoBPin = 16     # pin12

RoteLed = 33
GrueneLed = 35

ResetButton = 31

KaltButton = 38
WarmButton = 40

SDI   = 11
RCLK  = 12
SRCLK = 13

stop = 0
globalCounter = 0

flag = 0
Last_RoB_Status = 0
Current_RoB_Status = 0

segCode = [0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f]

def setup():
        GPIO.setmode(GPIO.BOARD)           # Numbers GPIOs by physical location
        GPIO.setup(RoAPin, GPIO.IN)     # input mode
        GPIO.setup(RoBPin, GPIO.IN)

        GPIO.setup(RoteLed, GPIO.OUT)
        GPIO.output(RoteLed, GPIO.HIGH)

        GPIO.setup(GrueneLed, GPIO.OUT)
        GPIO.output(GrueneLed, GPIO.HIGH)

        GPIO.setup(ResetButton, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(KaltButton, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(WarmButton, GPIO.IN, pull_up_down=GPIO.PUD_UP)

        GPIO.setup(SDI, GPIO.OUT)
        GPIO.setup(RCLK, GPIO.OUT)
        GPIO.setup(SRCLK, GPIO.OUT)
        GPIO.output(SDI, GPIO.LOW)
        GPIO.output(RCLK, GPIO.LOW)
        GPIO.output(SRCLK, GPIO.LOW)

def digits2registers(number, digits=2):
        res = 0
        for _ in xrange(digits):
               res <<= 8
               res |= segCode[number % 10]
               number /= 10
        return res

def hc595_shift(dat):
        org = dat
        dat = digits2registers(dat)
        for bit in range(0, 16):
                GPIO.output(SDI, dat & (1 << (15 - bit)))
                GPIO.output(SRCLK, GPIO.HIGH)
                time.sleep(0.0001)
                GPIO.output(SRCLK, GPIO.LOW)



        GPIO.output(RCLK, GPIO.HIGH)
        time.sleep(0.0001)
        GPIO.output(RCLK, GPIO.LOW)

        print org

def rotaryDeal():
        global flag
        global Last_RoB_Status
        global Current_RoB_Status
        global globalCounter
        global stop
        Last_RoB_Status = GPIO.input(RoBPin)
        while(not GPIO.input(RoAPin)):
                Current_RoB_Status = GPIO.input(RoBPin)
                flag = 1
        if flag == 1:
                flag = 0
                if (Last_RoB_Status == 0) and (Current_RoB_Status == 1):
                        globalCounter = globalCounter + 1
                if (Last_RoB_Status == 1) and (Current_RoB_Status == 0):
                        globalCounter = globalCounter - 1
        if (globalCounter < 0):
                globalCounter = 99
        if (globalCounter > 99):
                globalCounter = 0

def reset(pin):
        global globalCounter
        global stop
        globalCounter = 0
        stop = 1
        print 'stop'
        hc595_shift(globalCounter)

def loop(pin):
        global globalCounter
        global stop
        rotaryDeal()
        counter = globalCounter
        hc595_shift(counter)

        if GPIO.input(KaltButton) == GPIO.LOW or GPIO.input(WarmButton) == GPIO.LOW:
                if GPIO.input(KaltButton) == GPIO.LOW:
                        GPIO.output(GrueneLed, GPIO.LOW)
                elif GPIO.input(WarmButton) == GPIO.LOW:
                        GPIO.output(RoteLed, GPIO.LOW)

                for i in range(globalCounter):
                        if stop == 1:
                                break
                        time.sleep(1)
                        globalCounter = globalCounter - 1
                        hc595_shift(globalCounter)
                else:
                        GPIO.output(GrueneLed, GPIO.HIGH)
                        GPIO.output(RoteLed, GPIO.HIGH)

def main():
        GPIO.add_event_detect(15,GPIO.BOTH)
        GPIO.add_event_callback(15,loop)

        GPIO.add_event_detect(WarmButton,GPIO.FALLING)
        GPIO.add_event_callback(WarmButton,loop)

        GPIO.add_event_detect(KaltButton,GPIO.FALLING)
        GPIO.add_event_callback(KaltButton,loop)

        GPIO.add_event_detect(ResetButton,GPIO.FALLING)
        GPIO.add_event_callback(ResetButton,reset)

        while True:
                time.sleep(0.0001)

def destroy():
        globalCounter = 0
        hc595_shift(globalCounter)
        GPIO.cleanup()

if __name__ == '__main__':
        setup()
        try:
                main()
        except KeyboardInterrupt:
                destroy()


Die wesentlichen Teile sind der Timer mit der betroffenen Schleife:

Code:
def loop(pin):
        global globalCounter
        global stop
        rotaryDeal()
        counter = globalCounter
        hc595_shift(counter)

        if GPIO.input(KaltButton) == GPIO.LOW or GPIO.input(WarmButton) == GPIO.LOW:
                if GPIO.input(KaltButton) == GPIO.LOW:
                        GPIO.output(GrueneLed, GPIO.LOW)
                elif GPIO.input(WarmButton) == GPIO.LOW:
                        GPIO.output(RoteLed, GPIO.LOW)

                for i in range(globalCounter):
                        if stop == 1:
                                break
                        time.sleep(1)
                        globalCounter = globalCounter - 1
                        hc595_shift(globalCounter)
                else:
                        GPIO.output(GrueneLed, GPIO.HIGH)
                        GPIO.output(RoteLed, GPIO.HIGH)


Und die Reset Funktion:

Code:
def reset(pin):
        global globalCounter
        global stop
        globalCounter = 0
        stop = 1
        print 'stop'
        hc595_shift(globalCounter)

Was ich im Endeffekt möchte ist das sobald ich auf den ResetButton drücke die Schleife vom Timer abgebrochen wird.

THX