Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chapter 14 - Python version results in duplicate button events #7

Closed
anthonywittig opened this issue Sep 23, 2018 · 2 comments
Closed

Comments

@anthonywittig
Copy link

anthonywittig commented Sep 23, 2018

Hello,

When running the C code for chapter 14 everything works as expected. When running the Python code, the button has a duplicate event after the bouncetime. I was wondering if I was the only person to experience this behavior.

I modified the code as follows (see sections titled ### New code to test duplicate events) and for 10 seconds I see ~33 Skipping button press... output lines (corresponding to the bounce time of 300 and the 10 second ignore).

I've got a RPi 3 B+. Thanks for any insight you might be able to provide.

#!/usr/bin/env python3
########################################################################
# Filename    : Relay.py
# Description : Button control Relay and Motor
# Author      : freenove
# modification: 2018/08/02
########################################################################
import RPi.GPIO as GPIO
from datetime import datetime, timedelta

relayPin = 11    # define the relayPin
buttonPin = 12    # define the buttonPin
relayState = False

### New code to test duplicate events:
lastEventTime = datetime.now() - timedelta(seconds=10)
### End new code.

def setup():
        print ('Program is starting...')
        GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
        GPIO.setup(relayPin, GPIO.OUT)   # Set relayPin's mode is output
        GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    # Set buttonPin's mode is input, and pull up to high

def buttonEvent(channel):
        global relayState

        ### New code to test duplicate events:
        global lastEventTime
        print ('buttonEvent GPIO%d'%channel)
        if lastEventTime + timedelta(seconds=10) > datetime.now():
                print('Skipping button press...')
                return
        lastEventTime = datetime.now()
        ### End new code.

        relayState = not relayState
        if relayState :
                print ('Turn on relay ... ')
        else :
                print ('Turn off relay ... ')
        GPIO.output(relayPin,relayState)

def loop():
        #Button detect
        GPIO.add_event_detect(buttonPin, GPIO.FALLING, callback=buttonEvent, bouncetime=300)
        while True:
                pass

def destroy():
        GPIO.output(relayPin, GPIO.LOW)     # relay off
        GPIO.cleanup()                     # Release resource

if __name__ == '__main__':     # Program start from here
        setup()
        try:
                loop()
        except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child program destroy() will be  executed.
                destroy()

Output looks like this with a single button push:

Program is starting...
buttonEvent GPIO12
Turn on relay ... 
buttonEvent GPIO12
Skipping button press...
buttonEvent GPIO12
Skipping button press...
...
buttonEvent GPIO12
Turn off relay ... 

If I unplug the motor, there aren't any duplicate events.

@SuhaylZhao
Copy link
Member

Hi,

We analyzed the problem carefully.

This is because the motor is a high-power electrical device, the power supply voltage is pulled down at the start of the moment, resulting in GPIO18 pin signal changes, the program misjudged, and then closed the relay. Debounce way with the language of C and Python are not the same, which leads to the differences.

We decided to modify the circuit and separate the control part from the load part to solve this problem.

Thanks.

@anthonywittig
Copy link
Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants