I'm building a pi robot. It uses a ps3 controller for input. When the X button is pressed, it takes a photo. For some reason, it takes around 5 shots at a time. Is there a way to bounce the input so it only recognises one press?

I'm assuming it's registering multiple presses each time... Part of the code is attached, but I must state most of it is used from piborg.org

joystick = pygame.joystick.Joystick(0)

button_take_picture = 14            # X button

while running:
        # Get the latest events from the system
        hadEvent = False
        events = pygame.event.get()
        # Handle each event individually
        for event in events:
            if event.type == pygame.QUIT:
                # User exit
                running = False
            elif event.type == pygame.JOYBUTTONDOWN:
                # A button on the joystick just got pushed down
                hadEvent = True
            elif event.type == pygame.JOYAXISMOTION:
                # A joystick has been moved
                hadEvent = True
            if hadEvent:
                # Read axis positions (-1 to +1)
                if axisUpDownInverted:
                    upDown = -joystick.get_axis(axisUpDown)
                    upDown = joystick.get_axis(axisUpDown)
                if axisLeftRightInverted:
                    leftRight = -joystick.get_axis(axisLeftRight)
                    leftRight = joystick.get_axis(axisLeftRight)
                # Apply steering speeds
                if not joystick.get_button(buttonFastTurn):
                    leftRight *= 0.5
                # Determine the drive power levels
                driveLeft = -upDown
                driveRight = -upDown
                if leftRight < -0.05:
                    # Turning left
                    driveLeft *= 1.0 + (2.0 * leftRight)
                elif leftRight > 0.05:
                    # Turning right
                    driveRight *= 1.0 - (2.0 * leftRight)
                # Check for button presses
                if joystick.get_button(buttonResetEpo):
                if joystick.get_button(buttonSlow):
                    driveLeft *= slowFactor
                    driveRight *= slowFactor
                if joystick.get_button(button_take_picture):
  • This isn't really a Pi specific question. There are many ways to debounce keys. In this case I suggest you note when the photo is taken and ignore any further presses for x seconds. – joan Jun 10 '16 at 18:52
  • ok i see your point, could you explain how you would ignore after the 1st instance? – JONAS402 Jun 10 '16 at 19:15
  • I'd subtract the photo time from the current time. – joan Jun 10 '16 at 19:19
  • 1
    Please make an effort to use basic grammar and punctuation in your questions. Otherwise, you'll probably find that people don't really care enough to answer your question if you don't care enough to ask it properly. – Jacobm001 Jun 10 '16 at 19:30
  • i dont really understand what you mean. the goal is to only have one picture taken. surely if i was to take photo time from current time i would still be doing this 5 times? or do you mean if the two are equal, then continue, else break the function? sorry im quite new to python having a bit of a hard time – JONAS402 Jun 10 '16 at 19:33

in the end i found an answer on stack overflow!


What seems to be happening is that the X button stays down for multiple frames. Some other events might happen during this time, causing a call to take_picture() in your code for every frame. To fix this, you can either call take_picture() only on JOYBUTTONUP (when the button is released), or move the if joystick.get_button(button_take_picture) part to inside the pygame.JOYBUTTONDOWN section.

Alternatively, you could use another variable to indicate whether the picture was already taken, like this:

picture_was_taken = False

while running: hadEvent = False events = pygame.event.get() for event in events: ... if event.type == pygame.JOYBUTTONUP: if not joystick.get_button(button_take_picture) picture_was_taken = False ... if hadEvent: if joystick.get_button(button_take_picture) and not picture_was_taken: take_picture() picture_was_taken = True

thank you so much tomer https://stackoverflow.com/users/1806873/tomer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.