GPIO Hardware Pushbutton control for XBMC?
#31
I've just done some testing, and confirm that disabling the script causes a crash. Looking into it more deeply the thing that's actually causing the crash is the GPIO clean-up line (if you comment that out then no crash occurs, although of course if you then try and re-enable it again you get errors as you're trying to set up GPIO that already exist).

I need to go out now, but I've grabbed a few logs so I can look into it more later. It may be a problem with how I'm trying to clean up just the specific pins I'm using, or it may be something wider. Hopefully the logs can narrow it down some more.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#32
OK, it looks like if you do the cleanup without first removing the event related to the pin, you get a crash.

I've revised the script to do that, and for me I can now enable and disable cleanly, so I presume switching profiles will do the same properly now. I've updated the zip file on my box account - grab the new copy from there (the new anti-DDOS measures seem to be stopping the pasting of scripts here, so I can't put it directly).

Basically it runs the Main class and sits in it looping every 5 seconds until an abortRequest is received, at which point the class ends and the TidyUp class is then run, which removes the events and then cleans up the GPIO pins used.

Give that a try (or modify your version to do something similar if you've already started your customisation of the scripting) and let me know if it cures the problem for you as well.


Edited to add the script, as a test:

Code:
#!/usr/bin/python

import sys
sys.path.append('/storage/.kodi/addons/python.RPi.GPIO/lib')

import RPi.GPIO as GPIO
import xbmc

upPin = 17      # board pin 11
downPin = 27    # board pin 13
leftPin = 22    # board pin 15
rightPin = 6    # board pin 31
selectPin = 13  # board pin 33
shiftPin = 19   # board pin 35

def up_callback(channel):
    if(GPIO.input(shiftPin)):
        xbmc.executebuiltin("Action(Up)")
    else:
        xbmc.executebuiltin("Action(Back)")

def down_callback(channel):
    if(GPIO.input(shiftPin)):
        xbmc.executebuiltin("Action(Down)")
    else:
        xbmc.executebuiltin("Action(Info)")
      
def left_callback(channel):
    if(GPIO.input(shiftPin)):
        xbmc.executebuiltin("Action(Left)")
    else:
        xbmc.executebuiltin("Action(Stop)")

def right_callback(channel):
    if(GPIO.input(shiftPin)):
        xbmc.executebuiltin("Action(Right)")
    else:
        xbmc.executebuiltin("Action(PlayPause)")

def select_callback(channel):
    if(GPIO.input(shiftPin)):
        xbmc.executebuiltin("Action(Select)")
    else:
        xbmc.executebuiltin("Action(ContextMenu)")

class Main:
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(upPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(downPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(leftPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(rightPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(selectPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(shiftPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.add_event_detect(upPin, GPIO.FALLING, callback=up_callback, bouncetime=300)
    GPIO.add_event_detect(downPin, GPIO.FALLING, callback=down_callback, bouncetime=300)
    GPIO.add_event_detect(leftPin, GPIO.FALLING, callback=left_callback, bouncetime=300)
    GPIO.add_event_detect(rightPin, GPIO.FALLING, callback=right_callback, bouncetime=300)
    GPIO.add_event_detect(selectPin, GPIO.FALLING, callback=select_callback, bouncetime=300)

    while not xbmc.abortRequested:
        xbmc.sleep(5)
      
class TidyUp:
    GPIO.remove_event_detect(upPin)
    GPIO.remove_event_detect(downPin)
    GPIO.remove_event_detect(leftPin)
    GPIO.remove_event_detect(rightPin)
    GPIO.remove_event_detect(selectPin)
    GPIO.cleanup([upPin,downPin,leftPin,rightPin,selectPin,shiftPin])

  
if (__name__ == "__main__"):
    Main()
    TidyUp()
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#33
(2016-02-27, 14:46)DarrenHill Wrote: OK, it looks like if you do the cleanup without first removing the event related to the pin, you get a crash.

I've revised the script to do that, and for me I can now enable and disable cleanly, so I presume switching profiles will do the same properly now. I've updated the zip file on my box account - grab the new copy from there (the new anti-DDOS measures seem to be stopping the pasting of scripts here, so I can't put it directly).

Basically it runs the Main class and sits in it looping every 5 seconds until an abortRequest is received, at which point the class ends and the TidyUp class is then run, which removes the events and then cleans up the GPIO pins used.

Give that a try (or modify your version to do something similar if you've already started your customisation of the scripting) and let me know if it cures the problem for you as well.

I will try it out in just a second but I noticed that in the TidyUp class that you didnt clean up the ShiftPin. Should I clean it up too or was that on purpose?

I may remove the shift pin though.
Reply
#34
No, that's an error.

There's no callback event to remove on that pin, but the GPIO setup should be cleaned up for it.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#35
(2016-02-27, 15:53)DarrenHill Wrote: No, that's an error.

There's no callback event to remove on that pin, but the GPIO setup should be cleaned up for it.

Since I am at home, I actually don't have much equipment on me. This was just a quick and very ugly way to test your script. Everything works so far including the profile changing. Thank you very much Darren.

Ignore the IC chip, there's a problem with it and it wasn't outputting correctly so I just put it to the side. I'll be sure to give you a full picture once I order the parts and all the troubleshooting goes smoothly.

http://puu.sh/nnj4G/3497d94194.jpg
Reply
#36
I just double-checked the code and the shift Pin is cleaned up -

Code:
GPIO.cleanup([upPin,downPin,leftPin,rightPin,selectPin,shiftPin])

it doesn't have a GPIO.remove_event_detect though as there isn't an event associated with that button - it is just checked during the callback from the other five to know which of the two actions to take for that button.

Sounds like we're in a good way anyway. I'm still looking forward to my protozero board being delivered, wanna get this project done too Smile
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#37
(2016-02-27, 17:13)DarrenHill Wrote: I just double-checked the code and the shift Pin is cleaned up -

Code:
GPIO.cleanup([upPin,downPin,leftPin,rightPin,selectPin,shiftPin])

it doesn't have a GPIO.remove_event_detect though as there isn't an event associated with that button - it is just checked during the callback from the other five to know which of the two actions to take for that button.

Sounds like we're in a good way anyway. I'm still looking forward to my protozero board being delivered, wanna get this project done too Smile

Hey Darren, so this is going to be a shot in the dark but I want my select pin to also be a play/pause action.
If I have that pin execute the play/pause action and select action at the same time would I run into any "big" problems?

Right now I need a button to play slideshows but I don't want to add an extra whole button.
Reply
#38
I think you'd have problems if you just put both actions, as you'd always do both which for example on trying to play a movie would first play it and then either immediately pause it or open up the OSD, depending on which order your actions were set.

What you could maybe do though is read in which Kodi window is currently open/active and then send whichever command would be the relevant one for that window. Details of the XBMC python modules are here . I guess it should be possible, although I'm not sure of the relevant command.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#39
(2016-02-28, 22:33)DarrenHill Wrote: I think you'd have problems if you just put both actions, as you'd always do both which for example on trying to play a movie would first play it and then either immediately pause it or open up the OSD, depending on which order your actions were set.

What you could maybe do though is read in which Kodi window is currently open/active and then send whichever command would be the relevant one for that window. Details of the XBMC python modules are here . I guess it should be possible, although I'm not sure of the relevant command.

So I'll probably have to figure out what kind of window I go into the pictures menu from home and do something along the line of

get"window"()
if "window"
action playpause
else
action select
Reply
#40
Something like that yes.

I'm not sure if it's possible to do, but it's what i would investigate if I were trying to do it.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#41
(2016-02-28, 22:44)DarrenHill Wrote: Something like that yes.

I'm not sure if it's possible to do, but it's what i would investigate if I were trying to do it.

The closest thing I could find was

getPath(...)
getPath() - returns a string.

I am not sure how to check what exactly it will return so I could test it. I also have a feeling it won't do anything I actually want it to do since it wa sunder the infotagvideo section of the python modules in xbmc.
Reply
#42
You're getting beyond my very limited skill and expertise in python at this point.

This might be better asked in the add-on development section where some of the more skilled scripters could possibly advise better. Indeed I'm interested to know if it's possible myself for future reference.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#43
(2016-02-28, 23:44)DarrenHill Wrote: You're getting beyond my very limited skill and expertise in python at this point.

This might be better asked in the add-on development section where some of the more skilled scripters could possibly advise better. Indeed I'm interested to know if it's possible myself for future reference.

Hey Darren just wanted to update you on a solution I came across. Well it still doesn't really minimize buttons at all but it adds more functionality.

Code:
def right_callback(channel):
        path3 = xbmcgui.getCurrentWindowId()
        if(path3 == 10501): #10501 is MUSIC USB SCREEN
            xbmc.executebuiltin("Action(SkipNext)")
        else:
            xbmc.executebuiltin("Action(Right)")

This will always perform the execution right on the screen, but if I am on a music playlist it will perform skip to the next song.
Reply
#44
Thanks - that was the kind of thing I was thinking of, but wasn't sure of the method or function to read the id of the window with focus.

In my usage I don't think I'm going to need it, as my buttons are planned for simple navigation and basic functionality, and my board will also have an IR receiver diode connected up to GPIO18 (pin 12) for more in-depth control via a remote. I already have the latter set up running on my Zero (using a diode and three jumper cables), the board will just include it and make it neater and more permanent.

But it's useful to know for future application anyway, so many thanks for keeping me up to date on it. Seems like a good place for your first reputation point Smile

By the way, I moved your other thread to the add-on development area - you'd posted it in the existing add-on support area which wasn't quite the right place. The dev area will get more attention from the Python scripters around here and should get better support.
|Banned add-ons (wiki)|Forum rules (wiki)|VPN policy (wiki)|First time user (wiki)|FAQs (wiki) Troubleshooting (wiki)|Add-ons (wiki)|Free content (wiki)|Debug Log (wiki)|

Kodi Blog Posts
Reply
#45
(2016-02-29, 12:36)DarrenHill Wrote: Thanks - that was the kind of thing I was thinking of, but wasn't sure of the method or function to read the id of the window with focus.

In my usage I don't think I'm going to need it, as my buttons are planned for simple navigation and basic functionality, and my board will also have an IR receiver diode connected up to GPIO18 (pin 12) for more in-depth control via a remote. I already have the latter set up running on my Zero (using a diode and three jumper cables), the board will just include it and make it neater and more permanent.

But it's useful to know for future application anyway, so many thanks for keeping me up to date on it. Seems like a good place for your first reputation point Smile

By the way, I moved your other thread to the add-on development area - you'd posted it in the existing add-on support area which wasn't quite the right place. The dev area will get more attention from the Python scripters around here and should get better support.

Thank you for doing so. I have a small question regarding the PlayPause function. It works everywhere except when trying to pause a Picture Slideshow. Does this also happen for you? It will play the slideshow but won't pause it.
Reply

Logout Mark Read Team Forum Stats Members Help
GPIO Hardware Pushbutton control for XBMC?0