Taster mit Mehreren Funktionen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo liebes Forum,
    ich habe mir ein kleines Programm mit Python geschrieben, damit kann ich meinen Sonos-Musik Player mit meinem RPi steuern.

    Meine Frage jetzt, wie kann ich einem Taster 2 funktionen zuweisen.

    Einmal wenn ich nur Kurz drauf drücke dann soll er die Musik starten die davor gelaufen ist und wenn ich bspw. eine Sek. draufbleibe auf diesem Tastern dann eine ganz bestimmte playlist.

    hier mein jetziger code:

    Kann mir bei meinem Problem vielleicht jemand helfen

    Bei fragen einfach melden
    Vielen Dank schonmal

    Domi256

  • Also erst mal würde ich davon absehen eine while zu verwenden, das verursacht zu viel CPU Last. Mach das lieber mithilfe Interrupts.

    Dazu hatte ich gerade gestern erst ein Script geschrieben bzw hier im Forum gepostet - wobei das für MPD ist aber dürfte ähnlich sein: Python-Script - mpd Steuerung mithilfe GPIO Taster


    Das nächste wäre das ich das Script aber auch nicht verstehe... Zum Beispiel " if not (GPIO.input(11)): " ... es wird also ausgeführt wenn der gpio NICHT gedrückt ist... Was wiederum bedeutet das alles in der while querfeldein einfach mal ausgeführt wird :s


    Um einem Taster mehrere Funktionen zu geben kann man eine Zeit nutzen, also die Auslösungszeit speichern und sobald der Taster wieder released wird gucken wieviel Zeit vergangen is und dann eine entsprechende Aktion ausführen. Auch das ginge mit Interrupts wesentlich einfacher da man dort auf RISING und FALLING egde prüfen kann

  • Ja kann man, habe es hier so vorgefunden:

    Die Seite hat im übrigen, viele gute Tipps!

    --
    lg Peter
    Schon gefunden? Ich helfe gerne :danke_ATDE:

  • Hey

    ich habs jetzt mal probiert, nur leider kenn ich mich gar nicht aus kannst du da vllt mal drüber schauen was ich falsch gemacht hab:

    wenn ich das skript ausführe dauert es ein 2 sek und dann ist das programm beendet


    danke schonmal

  • Oben hast du vermutlich einen copy&paste Fehler, da fehlt das i vom mport

    Aber das vermutlich wichtigste ist das du den unteren Teil des Scripts auch nicht gepostet hast - das initialisieren des Interrupts. Hast du das nur vergessen zu posten oder auch nicht in Echt im Script :huh: Also nach dem letzten
    #------------------------------------------------------------------------
    kommt noch mehr, das brauchst du auch :fies:


    Also das was du vor hast könnte in etwa so aussehen:

    Spoiler anzeigen

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

    HOST = '192.168.178.83'

    #GPIO pins
    Play = 11
    Pause = 12
    Lauter = 16
    Leiser = 18
    Next = 13
    Prev = 15

    #special function time (in sec) for Play pin to switch playlist
    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(Play, GPIO.IN, pull_up_down = PULL)
    GPIO.setup(Pause, GPIO.IN, pull_up_down = PULL)
    GPIO.setup(Lauter, GPIO.IN, pull_up_down = PULL)
    GPIO.setup(Leiser, GPIO.IN, pull_up_down = PULL)
    GPIO.setup(Next, GPIO.IN, pull_up_down = PULL)
    GPIO.setup(Prev, 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 == Play:
    if GPIO.input(Play) == GPIO.HIGH:
    timeTrigger = time()
    elif GPIO.input(Play) == GPIO.LOW:
    timeTrigger = time() - timeTrigger
    if timeTrigger >= SpecialTime:
    timeTrigger = 0
    #special function: play another playlist
    print "special play"
    else: #normal play
    timeTrigger = 0
    print "normal play"
    client.volume = 10
    client.play()

    elif GPIO.input(Pause) == GPIO.HIGH:
    client.pause()

    elif GPIO.input(Lauter) == GPIO.HIGH:
    client.volume += 2

    elif GPIO.input(Leiser) == GPIO.HIGH:
    client.volume -=2

    elif GPIO.input(Next) == GPIO.HIGH:
    client.next()

    elif GPIO.input(Prev) == GPIO.HIGH:
    client.previous()

    else:
    print "ERROR! Unknown GPIO pin triggered: %s" % pin

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

    try:
    GPIO.add_event_detect(Play, GPIO.BOTH, callback=Interrupt_event, bouncetime=100)
    GPIO.add_event_detect(Pause, GPIO.RISING, callback=Interrupt_event, bouncetime=150)
    GPIO.add_event_detect(Lauter, GPIO.RISING, callback=Interrupt_event, bouncetime=150)
    GPIO.add_event_detect(Leiser, GPIO.RISING, callback=Interrupt_event, bouncetime=150)
    GPIO.add_event_detect(Next, GPIO.RISING, callback=Interrupt_event, bouncetime=150)
    GPIO.add_event_detect(Prev, GPIO.RISING, callback=Interrupt_event, bouncetime=150)

    timeTrigger = 0
    client = SoCo(HOST)

    #keep script running
    signal.pause()
    except (KeyboardInterrupt, SystemExit):
    GPIO.cleanup()
    print "\nQuit\n"
    [/php](da siehst du auch den unteren Teil den du vergessen hast, aber der is freilich auch wichtig)

  • Hallo ich habe jetzt mal dein Code ausprobiert funktioniert fast! Vielen Dank für die Arbeit die du dir gemacht hast!

    Aber ich komm leider nicht drauf wie du definiert hast was ich an meinem Taster drücken muss das ich den "normal play" befehl und den "special play" ausführe.
    Und leider wenn ich einen anderen Taster als den an Pin 11 (Play Taster) dann stoppt die Musik kannst du mir vielleicht einen Tipp geben warum? Er erkennt zwar das ich den einen anderen Taster als 11 gedrückt habe aber er führt leider nicht den Befehl aus der hinter dem elif steht.


    Vielen Dank

    Domi256

    PS: kann es auch evtl sein das ich den Taster Falsch angeschlossen habe?
    Ich habe ihn wie folgt angeschlossen

    Spoiler anzeigen

    TasterSchaltung.jpg


    EDIT:
    ich hatte die Taster falschrum angeschlossen jetzt funktioniert alles Vielen Vielen Dank!!

    Einmal editiert, zuletzt von Domi256 (16. Februar 2015 um 09:51)

  • Aber ich komm leider nicht drauf wie du definiert hast was ich an meinem Taster drücken muss das ich den "normal play" befehl und den "special play" ausführe.

    Das wird durch SpecialTime festgelegt. Also was das Script macht ist beim drücken des Play Tasters die Unixtime zu speichern und wenn man den Taster wieder los lässt rechnet es die "Start Sekunden" von den aktuellen ab, ist die Differenz größer-gleich SpecialTime wird "special play" ausgeführt, wenn nicht dann "normal play"

    Also time() gibt den sog. Unixtimestamp aus. Das sind die Sekunden die seit dem 1.1.1970 vergangen sind. Das ist eine Linux/Unix weite standardisierte Zeiterfassung.

    Da für den Play Taster ein Interrupt für sowohl RISING als auch FALLING = BOTH aktiv ist, wird also bei sowohl drücken als auch loslassen ein Interrupt beachtet. Beim drücken des Tasters wird die Rückgabe von time() in die Variable timeTrigger geschrieben. Lässt man den Taster wieder los wird der aktuelle Wert von time() vom zuvor erfassten timeTrigger abgezogen, was dann zum Beispiel 1.5 Sekunden sein könnte und somit größer als 1.0 Sekunden wäre und der special Play ausgeführt wird ;)

  • jetzt noch eine frage ich habe ja die 6 taster angeschlossen und sonst nur noch einen wlan stick aber anscheinend braucht der stick wenn ich ihn so anstecke ohne usb hub zu viel strom

    hast du nen tipp was ich dagegen machen kann

    am strom hängt mein RPi mit einem normalen usb netzadapter und einem normalen micro usb kabel


    oder weisst du vllt wie ich messen oder auslesen kann wie viel stom mein RPi bekommt


    Danke :)

  • Ich hab keine Ahnung welchen PI du hast :s

    Aber das ist hier Offtopic - am besten du erstellst für dieses neue Problem einen anderen Thread


    PS: Wenn du einen älteren PI als B+ hast, dann ist es normal das der PI abschmiert sobald man im laufenden Betrieb ein Strom-hungriges USB-Device einsteckt...

Jetzt mitmachen!

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