Using GPIO buttons to control Raspbmc

3.4k Views Asked by At

I am trying to write code for a car xbmc project. I made my own button keypad with pull-down resistors and plugged into the GPIO ports. Installed python and the GPIO addon. My goal is to catch button presses, and if the button is held for 1.5 secs, it will execute a different command to xbmc (for example, the right key would skip to the next track if held). I'm not too familiar with Python, so it's been a pretty long process getting to where I am. I chose to use the GPIO.add_event_detect() function since it has a built-in debouncer, but I think it's new because I can't find many examples of it being used. This is what is throwing errors:

Traceback (most recent call last):
  File "buttons.py", line 15, in <module>
    GPIO.add_event_detect(buttons[index], GPIO.RISING, bouncetime=200)
RuntimeError: Edge detection already enabled for this GPIO channel


#!/usr/bin/env python
import Rpi.GPIO as GPIO
import time, os, httplib, json
GPIO.setmode(GPIO.BCM)

buttons = [4, 17, 18, 22, 23, 24, 27]
numbuttons = len(buttons)
index = 0
for index in numbuttons:
    GPIO.setup(index, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
    index = 0
    for index in numbuttons:
        GPIO.add_event_detect(buttons[index], GPIO.RISING, bouncetime=200)
        if GPIO.event_detected(buttons[index]):
            time_pressed = time.time()
            GPIO.add_event_detect(buttons[index], GPIO.FALLING, bouncetime=200)
            if GPIO.event_detected(buttons[index]):
                time_released = time.time()
                if (time_released - time_pressed) >= 1.5:
                    button_held(index)
                else:
                    button_pressed(index)
    time.sleep(0.01)

def button_pressed(index):
    url = "/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22"
    url2 = ",%22id%22:1}"
    player = "Player.GetActivePlayers%22"
    playcode = "Player.PlayPause%22,%22params%22:{%22playerid%22:"
    guidecode = "Player.GetProperties%22,%22params%22:{%22playerid%22:"
    upcode = "Input.Up%22,%22params%22:{%22playerid%22:"
    downcode = "Input.Down%22,%22params%22:{%22playerid%22:"
    leftcode = "Input.Left%22,%22params%22:{%22playerid%22:"
    rightcode = "Input.Right%22,%22params%22:{%22playerid%22:"
    backcode = "Input.Back%22,%22params%22:{%22playerid%22:"
    conn = httplib.HTTPConnection("127.0.0.1:8080")
    if index == 0:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + guidecode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc guide")
    elif index == 1:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + leftcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc left")
    elif index == 2:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + playcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc play/pause")
    elif index == 3:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + upcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc up")
    elif index == 4:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + backcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc backspace")
    elif index == 5:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + downcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc down")
    elif index == 6:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + rightcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc right")

def button_held(index):
    url = "/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22"
    url2 = ",%22id%22:1}"
    player = "Player.GetActivePlayers%22"
    playcode = "Player.PlayPause%22,%22params%22:{%22playerid%22:"
    upcode = "Input.Up%22,%22params%22:{%22playerid%22:"
    downcode = "Input.Down%22,%22params%22:{%22playerid%22:"
    backcode = "Input.Back%22,%22params%22:{%22playerid%22:"
    nextcode = "Player.GoNext%22,%22params%22:{%22playerid%22:"
    prevcode = "Player.GoPrevious%22,%22params%22:{%22playerid%22:"
    shuffcode = "Player.Shuffle%22,%22params%22:{%22playerid%22:"
    mutecode = "Application.SetMute%22,%22params%22:{%22playerid%22:"
    conn = httplib.HTTPConnection("127.0.0.1:8080")
    if index == 0:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + shuffcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc guide")
    elif index == 1:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + prevcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc left")
    elif index == 2:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + playcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc play/pause")
    elif index == 3:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + upcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc up")
    elif index == 4:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + backcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc backspace")
    elif index == 5:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + downcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc down")
    elif index == 6:
        conn.request("GET", url + player + url2)
        r = conn.getresponse()
        j = json.loads(r.read())
        playeron = j["result"]
        if json.dumps(playeron) == "[]":
            conn.request("GET", url + "input.select%22" + url2)
            conn.close()
        else:
            playerid = json.dumps(j["result"][0]["playerid"])
            conn.request("GET", url + nextcode + playerid + "}" + url2)
            conn.close()
        conn.close()
        print("execute xbmc right")
1

There are 1 best solutions below

0
On

I thought I was just hitting that command and popping the error, but I was iterating the loop first. This makes sense since the event catcher cant be turned on more than once. I simply edited my code to initialize it and add a new event detect only when the button is pressed. I also cleaned up the code I found on an XBMC forum and it works.

import Rpi.GPIO as GPIO
import time, os, httplib, json, requests, pdb
from requests.auth import HTTPBasicAuth
GPIO.setmode(GPIO.BCM)

def main():
    buttons = [4, 17, 18, 22, 23, 24, 27]
    numbuttons = len(buttons)
    index = 0
    for index in range(numbuttons):
        GPIO.setup(buttons[index], GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.add_event_detect(buttons[index], GPIO.RISING, bouncetime=200)
    while True:
        index = 0
        for index in range(numbuttons):
            if GPIO.event_detected(buttons[index]):
                GPIO.remove_event_detect(buttons[index])
                time_pressed = time.time()
                GPIO.wait_for_edge(buttons[index], GPIO.FALLING)
                time.sleep(0.01)
                time_released = time.time()
                if (time_released - time_pressed) >= 1.5:
                    button_held(index)
                else:
                    button_pressed(index)
                GPIO.add_event_detect(buttons[index], GPIO.RISING, bouncetime=200)
        time.sleep(0.01)

def button_pressed(index):
    url = 'http://192.168.1.138:8888/jsonrpc'
    postheaders = {'content-type': 'application/json'}
    command = {"jsonrpc":"2.0", "id": 1, "method": ""}
    if index == 0:
        command['method'] = 'Input.Select'
        print("execute xbmc guide")
    elif index == 1:
        command['method'] = 'Input.Left'
        print("execute xbmc left")
    elif index == 2:
        command['method'] = 'Input.Info'
        print("execute xbmc play/pause")
    elif index == 3:
        command['method'] = 'Input.Up'
        print("execute xbmc up")
    elif index == 4:
        command['method'] = 'Input.Back'
        print("execute xbmc backspace")
    elif index == 5:
        command['method'] = 'Input.Down'
        print("execute xbmc down")
    elif index == 6:
        command['method'] = 'Input.Right'
        print("execute xbmc right")
    resp = requests.post(url, auth=('xbmc','xbmc'), data=json.dumps(command), headers=postheaders)

def button_held(index):
    url = 'http://192.168.1.138:8888/jsonrpc'
    postheaders = {'content-type': 'application/json'}
    command = {"jsonrpc":"2.0", "id": 1, "method": ""}
    if index == 0:
        command['method'] = 'Player.PlayPause'
        print("execute xbmc shuffle")
    elif index == 1:
        command['method'] = 'Player.GoNext'
        print("execute xbmc left")
    elif index == 2:
        command['method'] = 'Player.SetMute'
        print("execute xbmc play/pause")
    elif index == 3:
        command['method'] = 'Input.SetShuffle'
        print("execute xbmc up")
    elif index == 4:
        command['method'] = 'Input.Back'
        print("execute xbmc backspace")
    elif index == 5:
        command['method'] = 'Input.SetRepeat'
        print("execute xbmc down")
    elif index == 6:
        command['method'] = 'Player.GoPrevious'
        print("execute xbmc right")
    resp = requests.post(url, auth=('xbmc','xbmc'), data=json.dumps(command), headers=postheaders)
if __name__ == '__main__':
    main()