1

I'm writing a python script that will control LEDs with a Wiimote using the cwiid library. The program recognizes the wiimote and is able to start the loops, but it will not let me stop the loop when the user presses "B" on the remote. Here is the relevant code, and I can provide the rest of the script if needed. Thanks.

  buttons = wii.state['buttons']

...

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    print 'Press B to cancel loop'
    keepRunning = True
    while keepRunning:
        blink(32)#5v green
        blink(38)#5v yellow
        blink(36)#5v blue
        blink(40)#5v red
        blink(37)#3v3 green
        blink(35)#3v3 yellow
        blink(33)#3v3 blue
        blink(31)#3v3 red
        if (buttons & cwiid.BTN_B):
            keepRunning  = False
    time.sleep(button_delay)

Here is the fixed loop per Stuart's answer

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    print 'Press B to cancel loop'
    keepRunning = True
    while keepRunning:
        blink(32)#5v green
        blink(38)#5v yellow
        blink(36)#5v blue
        blink(40)#5v red
        blink(37)#3v3 green
        blink(35)#3v3 yellow
        blink(33)#3v3 blue
        blink(31)#3v3 red
        buttons = wii.state['buttons']#added in this line
        if (buttons & cwiid.BTN_B):
            keepRunning  = False
    time.sleep(button_delay)
kalenpw
  • 695
  • 3
  • 10
  • 34
  • Also, there is no real need to check `buttons` again in your nested `if` statement, as this is guaranteed to be true by the first `if`. – Nelewout Jan 06 '16 at 18:41
  • if I keep the code as is and just switch keepRunning = False to break, it doesn't work, so the program never enters that second if statement. If I delete the buttons so my second if statment is if(cwiid.BTN_B): break or keepRunning = False then the program will run through the loop once(hit all the blinks) and then terminate regardless of if B is pressed or not – kalenpw Jan 06 '16 at 18:45
  • are you sure `cwiid.BTN_B` is properly mapped to `B`? – Nelewout Jan 06 '16 at 18:47
  • 1
    Don't know the library but presumably you need to check `wii.state['buttons'] & cwiid.BTN_B` rather than storing the value of `wii.state['buttons']` in a variable, which will not then change when the user presses different buttons. – Stuart Jan 06 '16 at 18:47
  • @N.Wouda yes, I have tested that out in the same program. – kalenpw Jan 06 '16 at 18:48
  • @stuart yep, you're exactly right by adding "buttons = wii.state['buttons']" before the second if statement I can now terminate the program on the press of B. I'll edit that into my original question and if you want to post it as an answer I'll accept it as the correct one. Thank you. – kalenpw Jan 06 '16 at 18:54

1 Answers1

1

wii.state['buttons'] appears to be a number, so storing it in the variable buttons means it is no longer updated when the user presses a different combination of buttons.

To fix this just replace buttons with a direct reference to wii.state['buttons'] each time.

You might want to consider checking whether B is pressed after each blink, like this:

from itertools import cycle
...
if wii.state['buttons'] & cwiid.BTN_A:
    print 'Button A pressed'
    print 'Press B to cancel loop'
    for colour in cycle([32, 38, 36, 40, 37, 35, 33, 31]):
        blink(colour)
        if wii.state['buttons'] & cwiid.BTN_B:
            break
    time.sleep(button_delay)
Stuart
  • 9,597
  • 1
  • 21
  • 30