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

Unexpected callback invocation in wait_edge. #3

Open
Appeltabak opened this issue Feb 13, 2015 · 0 comments
Open

Unexpected callback invocation in wait_edge. #3

Appeltabak opened this issue Feb 13, 2015 · 0 comments

Comments

@Appeltabak
Copy link

I encountered strange behaviour on a pin when a rising edge occured. I set a new rising edge on a pin with the following callback:

def callback():
    print("Callback started")
    time.sleep(10)
    print("Callback finished")

When I triggered one rising edge, the callback executed once, as expected. When I triggered two rising edges sequentially, the callback executed twice. But when I triggered more then two rising edges sequentially, the callback is just executed just twice.

I encountered this behaviour in the implementation of Pin.wait_edge (It's more than likely that this behaviour occurs in the other implementations of wait_edge:

def wait_edge(self,fd,callback,debouncingtime):
    debouncingtime=debouncingtime/1000.0 # converto in millisecondi
    timestampprec=time.time()
    counter=0
    po = select.epoll()
    po.register(fd,select.EPOLLET)
    while True:
        events = po.poll()
        timestamp=time.time()
        if (timestamp-timestampprec>debouncingtime) and counter>0:
            callback()
        counter=counter+1
        timestampprec=timestamp

po.poll blocks the loop until a rising egde occur. Then it excutes the callback. If during the excuting one or more rising edges occur, po.poll will not block the very first next run of the while loop. It seems that the po object (which is an epoll object) 'buffers' one edge event and therefore is does not block.

Suggested soluction:
On edge, but before the execution of the callback, the polling for events should be disabled and after the execution should be re-enabled. This will stop polling during the execution of the callback and will not 'buffer' another event.

while True:
    events = po.poll()
        # Disable polling here.
    timestamp=time.time()
    if (timestamp-timestampprec>debouncingtime) and counter>0:
        callback()
        # Enable polling here again.
    counter=counter+1
    timestampprec=timestamp
kevba added a commit to Appeltabak/ablib that referenced this issue Feb 14, 2015
kevba added a commit to Appeltabak/ablib that referenced this issue Feb 14, 2015
kevba added a commit to Appeltabak/ablib that referenced this issue Feb 14, 2015
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

1 participant