Taster, Funktion, Schleife beenden,

  • Hallo Zusammen,

    ich stehe vor einem Problem und komme leider nicht weiter.
    Ich habe einen Taster angeschlossen und dieser soll bei Tastendruck eine Funktion ausführen.
    Einmal die CPU Temp im Terminal ausgeben und beim nächsten Tastendruck die Zeit.
    Ich würde aber die Zeit gern in einer Schleife laufen lassen, damit diese immer aktuell ist. Wenn ich aber wieder die Taste drücke, soll wieder die CPU Temp angezeigt werden.

    Anbei ist der Code.


    Wenn ich die Schleife bei der Zeit weg lasse, dann funktioniert alles auch sauber.
    Sobald ich aber die Schleife bei der Zeit wieder aktiviere, komme ich aus der Schleife nicht mehr per Tastendruck heraus.

    Vielleicht kann mir hier jemand helfen, oder mir sagen, wie ich es schlauer machen kann.

    Danke

  • Hallo Wusa,

    solange Du in der While-Schleife der Zeit keine Tasterabfrage zum Verlassen dieser Schleife drin hast, wird das Programm auch anweisungsgemäß in dieser Schleife verharren.

    Ich würde die Anweisung aus der Zeit-Schleife in main() bringen - dann aber ohne Schleifen-Konstrukt. Dann macht das Programm genau das, was Dir vorschwebt.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (8. März 2015 um 17:32)

  • Hallo Wusa,

    so?

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Lies dich mal durch die Doku
    http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/

    Des Weiteren würde ich in der ``def main()`` bzw. in der Hauptfunktion die anderen Funktionen aufrufen. Auch ``global`` weglassen, denn Werte betreten eine Funktion durch Parameter und werden mit ``return```zurückgegeben. Die Funktion ``zeit()`` ist auch eher sinnlos und die Namen der Variablen und Funktionen sollten IHMO auch aussagekräftig sein.

  • Ich werde mir jetzt dann gleich deinen Link durchlesen, aber was ich schon mal im vorherein nicht verstehe, warum ich alle Funktionen in der "main" Funktion aufrufen soll?

    Das mit der Zeit sehe ich jetzt nicht so schlimm. Es soll für mich eigentlich nur eine Übung bzw. soll es für mich ein Lernen von Python sein.
    Da ich noch nicht allzuviel damit gemacht habe, aber ich mir die Programmiersprache beibringen will.

    Danke

  • bootsmann

    Ich hoffe ich verstehe dich richtig. Ich soll "def temp()" und "def zeit()" und "def taster()" innerhalb der "def main()" schreiben?

    Wenn das so ist, für was schreibt man dann Funktionen?

    Ich finde das viel übersichtlicher, wenn man für alles mögliche eine Funktion (def ...) schreibt.

    Verstehe ich vielleicht hier was Grundsätzliches falsch?

    Danke

  • Ne, ich meinte in etwa so:

    Gebe den Funktionen aussagekräftige Namen. Also benenne sie danach, was sie tun. Auch achte darauf, dass 4 Leerzeichen gemacht werden und nicht 8.

    http://legacy.python.org/dev/peps/pep-0008/#tabs-or-spaces
    http://legacy.python.org/dev/peps/pep-0…ing-conventions

  • Hallo,

    so ist der Code schöner (ungetestet):

    Gruß, noisefloor

  • Hi.
    noisefloor

    vielen Dank für deinen Code.
    Ich habe ihn getestet und paar kleine Fehler noch beseitigt. Leider ist es aber hier so, dass nur einmal die aktuelle Zeit angezeigt wird.
    Ich hätte gerne die Zeit in einer Art Schleife, dass diese immer aktuell ist.
    Sobald ich aber irgendwo eine Schleife einbaue, komme ich per Tastendruck nicht mehr heraus.

    Kannst du mir hier vielleicht auch nochmal helfen.

    Danke!

  • Ich empfehle für Taster lieber Interrupts zu nutzen. Das ist nicht nur schöner sondern auch schneller und kürzer.

    [code=php]
    import RPi.GPIO as GPIO
    import time
    import signal

    #------------------------------------------------------------------------
    # use the raspi board pin number
    #GPIO.setmode(GPIO.BOARD)
    # use the gpio number
    GPIO.setmode(GPIO.BCM)

    # only one of following for GPIO.IN:
    PULL = GPIO.PUD_DOWN #GPIO -> GND
    #PULL = GPIO.PUD_UP #GPIO -> 3V3

    Taster = 17
    #------------------------------------------------------------------------

    GPIO.setup(Taster, GPIO.IN, pull_up_down=PULL)

    def cputemp():
    with open('/sys/class/thermal/thermal_zone0/temp', 'r') as f:
    CPUtemp = int(float(f.readline().split()[0]))
    CPUtemp = round((CPUtemp/1000.0), 2)
    return CPUtemp

    def interrupt_event(pin):
    zeit = time.strftime("%d.%m.%Y %H:%M:%S")
    if GPIO.input(Taster) == GPIO.HIGH:
    print "{} Rising edge detected on {}".format(zeit, pin)
    print cputemp()
    else:
    print "{} Falling edge detected on {}".format(zeit, pin)


    if __name__ == '__main__':
    try:
    GPIO.add_event_detect(Taster, GPIO.BOTH, callback=interrupt_event, bouncetime=150)
    #keep script running
    signal.pause()
    except (KeyboardInterrupt, SystemExit):
    print "\nQuit\n"
    GPIO.cleanup()
    [/php]

  • Hm, die Zeit sollte obiges Beispiel bereits ausgeben, oder nicht :s

    Wenn du mit nur einem Taster anhand der Zeit wie lange der Taster gedrückt wird, mehrere Funktionen ausführen willst, kannst du folgendes nutzen:

    [code=php]
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    # v0.1 by meigrafd
    #
    import sys
    from time import sleep, time
    import RPi.GPIO as GPIO
    import signal
    #------------------------------------------------------------------------

    #GPIO pins
    Taster = 17

    #special function time (in sec)
    SpecialTime = 1

    # only one of following:
    PULL = GPIO.PUD_DOWN #GPIO -> GND
    #PULL = GPIO.PUD_UP #GPIO -> 3V3

    # to use RaspberryPi pin numbers
    GPIO.setmode(GPIO.BOARD)

    #------------------------------------------------------------------------

    # set up GPIO input channels
    GPIO.setup(Taster, GPIO.IN, pull_up_down = PULL)

    #------------------------------------------------------------------------

    def interrupt_event(pin):
    global timeTrigger

    # only for debug:
    if GPIO.input(pin) == GPIO.HIGH:
    print "rising edge on %s" % pin
    elif GPIO.input(pin) == GPIO.LOW:
    print "falling edge on %s" % pin

    if pin == Taster:
    if GPIO.input(Taster) == GPIO.HIGH:
    timeTrigger = time()
    elif GPIO.input(Taster) == GPIO.LOW:
    timeTrigger = time() - timeTrigger
    if timeTrigger >= SpecialTime:
    #special function
    print "special"
    else:
    #normal function
    print "normal"
    else:
    print "ERROR! Unknown GPIO pin triggered: %s" % pin

    #------------------------------------------------------------------------

    try:
    GPIO.add_event_detect(Taster, GPIO.BOTH, callback=interrupt_event, bouncetime=100)
    timeTrigger = 0
    #keep script running
    signal.pause()
    except (KeyboardInterrupt, SystemExit):
    GPIO.cleanup()
    print "\nQuit\n"
    [/php]

    Quelle bzw Erklärung: Taster mit Mehreren Funktionen

    Weitere mögliche Lösung:
    Auf Flanken reagieren und mehrer Befehle ausführen
    Scroll-Menü

  • Ja dein obiges Beispiel gibt die Zeit ohne Probleme aus, bzw. das ganz Skript funktionierte auf Anhieb.

    Es wird aber nur einmal die Zeit ausgegeben, dann muss ich nochmals die Taste drücken, dann kommt die Zeit nochmals.

    Was ich eigentlich sagen wollte. Wenn man zb. die 2 "Funktionen" auseinander nimmt, sodass bei Tastendruck die CPU Temp angezeigt wird, und beim nochmaligem Tastendruck wird die Zeit in einer Schleife ausgegeben, sodass jede Sekunde die aktuelle Zeit angezeigt wird. Drückt man dann nochmals die Taste, wird die Schleife mit der Zeit beendet und die CPU Temp wird wieder angezeigt.

    Ich habe schon überall Schleifen eingebaut und irgendwie versucht, diese wieder zu beenden. Leider schaffe ich es nicht.

  • Schleifen werden überbewertet :D

    Wie wärs hiermit:

    [code=php]
    import RPi.GPIO as GPIO
    import time
    import signal
    import threading

    #------------------------------------------------------------------------
    # use the raspi board pin number
    #GPIO.setmode(GPIO.BOARD)
    # use the gpio number
    GPIO.setmode(GPIO.BCM)

    # only one of following for GPIO.IN:
    PULL = GPIO.PUD_DOWN #GPIO -> GND
    #PULL = GPIO.PUD_UP #GPIO -> 3V3

    Taster = 17
    #------------------------------------------------------------------------

    GPIO.setup(Taster, GPIO.IN, pull_up_down=PULL)

    def cputemp():
    with open('/sys/class/thermal/thermal_zone0/temp', 'r') as f:
    CPUtemp = int(float(f.readline().split()[0]))
    CPUtemp = round((CPUtemp/1000.0), 2)
    return CPUtemp

    def TimedRequest(when, what):
    global timed
    when = float(when)
    what = str(what)
    zeit = time.strftime("%d.%m.%Y %H:%M:%S")
    if what == "pitemp":
    print "{} --> {}".format(zeit, cputemp())
    timed = threading.Timer( when, TimedRequest, [when, what] )
    timed.start()

    def interrupt_event(pin):
    global timed
    if GPIO.input(Taster) == GPIO.HIGH:
    if not timed:
    timed = threading.Timer( 1.0, TimedRequest, ["1.0", "pitemp"] )
    timed.start()
    else:
    timed.cancel()
    timed = False

    if __name__ == '__main__':
    try:
    timed = False
    GPIO.add_event_detect(Taster, GPIO.BOTH, callback=interrupt_event, bouncetime=150)
    #keep script running
    signal.pause()
    except (KeyboardInterrupt, SystemExit):
    print "\nQuit\n"
    GPIO.cleanup()
    if timed:
    timed.cancel()
    [/php]

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!