-1

So I'm trying to make a simple debounce and I just can't figure out where I messed up. Here is the code:

def debounce(var, db):
    if var == 1 and db == 0:
        db = 1
    elif var == 0:
        db = 0
    else:
        var = 0
    return var, db


while True:
    mouse_buttons = get_mouse_buttons()    # -This is the fuction that if the mouse's buttons are pressed

    pressed, db = debounce(mouse_buttons[0], db)
    mouse_buttons = (pressed, 0, 0)

    print(mouse_buttons[0])

My expected output would be if I press the mouse button, then it would be a 1 for once, then turn 0 untill I release and press it again. The current code gives out a 1 for the first time, and no matter what, it only gives out 0 after. (I tested it, it has nothing to do with the function that returns the pressed buttons on the mouse.)

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Dawe
  • 3
  • 2
  • 1
    Can you tell a little bit more of the expected result of the function, and what does not work properly (unexpected return? Error?) Thanks! – HenriChab Mar 18 '21 at 23:12
  • Sorry for the lack of information, I edited it it be more precise. – Dawe Mar 18 '21 at 23:22
  • what value does db start with - just form completeness ? – Tony Suffolk 66 Mar 18 '21 at 23:26
  • Actually it works for me when replacing the function `get_mouse_buttons()` by `def get_mouse_buttons(): return [int(input())]` to simulate a click with an input. – HenriChab Mar 18 '21 at 23:40
  • 1
    @HemChab - that suggest therefore that `get_mouse_buttons()` isn't doing what is expected. – Tony Suffolk 66 Mar 19 '21 at 00:16
  • Yop, definitely, the debounce function should not be in cause there – HenriChab Mar 19 '21 at 00:19
  • @HenriChab - I concur. I just repeated the test with `get_mouse_buttons()` replaced with `(int(input('>>').lower()=='y'), 0, 0)`. Where a input of 'y' or 'Y' is the button being pressed, and I get the expected results - the code only prints 1 when you go from 'n' to 'y' which is the intention. – Tony Suffolk 66 Mar 19 '21 at 00:22

2 Answers2

0

debounce always needs to set db. You don't do that in all cases. If you want pressed to be the debounced value, then you want:

def debounce(var, db):
    if var == 1 and db == 0:
        db = 1
    else:
        db = 0
    return db, var

To figure this out, write the states down on paper over time:

var = 0 1 1 1 1 1 1 0 0 0 1 1 1
 db = 0 1 0 0 0 0 0 0 0 0 1 0 0
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • the problem is, that when db is already 1, he wants to return var as 0 - ie ignore continued button presses. – Tony Suffolk 66 Mar 18 '21 at 23:33
  • He wants the first parameter to return 0 in that case. This does that. Notice that I swapped the order of the return values. The `db` in his main program need to be the memory of what the actual button press was last time. That comes in the `debounce` as `var`. – Tim Roberts Mar 18 '21 at 23:35
  • you are right - I hadn't spotted that you had swapped the values of db and var. – Tony Suffolk 66 Mar 19 '21 at 14:12
0

Just to confirm your test expectations

var  |  db  |  var,db 
----------------------
  0     0      0,0
  0     1      0,0
  1     0      1,1
  1     1      0,1

If this is correct then I am not sure that your function does do that.

This is simpler - to reproduce the same logic table.

def debounce(var, db):
    return var and not db, var

In this case when var is 0 - this will return 0,0 When var is 1 this will return 1,1 if db == 0 When var is 0 this will return 0,1 if db == 1

Addendum - when I re-ran your code with get_mouse_buttons() replaced with this :

def get_mouse_buttons():
    return (int(input('>>').lower()=='y'), 0, 0)

Where you get to decide (by typing Y/y) whether the mouse button is pressed, it turns out that your debounce code - although clunky does actually do what is expected - your loop only prints a 1 when you type a 'y' initially or you go from not a 'y' to a 'y' - ie your code correctly detects the initial change from non-pressed to pressed.

Since you state your code doesn't work thereofre th clear suspect is your get_mouse_buttons() function - which you have claimed works ok.

Tony Suffolk 66
  • 9,358
  • 3
  • 30
  • 33
  • Very clear to make it a logic table but I think it does produce that: if `var=0`, then it goes through the second condition so var stays at 0 and db is set to 0, so it returns `(0, 0)`. If `var=1` and `db=0`, we are in the first condition and it returns `(1, 1)` as db becomes 0. Finally, if `var=1` and `db=1`, we are in the third condition and it returns `(0, 1)` as var is set to 0. am I missing something? It should give the right result. – HenriChab Mar 18 '21 at 23:47
  • @HenriChab - maybe I parsed the multiple ifs wrong then - I prefer the logic rather than nested ands. – Tony Suffolk 66 Mar 19 '21 at 00:14
  • Your solution is definitely better! But I try to understand why his solution does not work – HenriChab Mar 19 '21 at 00:15
  • @HenriChab as you suggest - it does work when you use `input` so that suggest (as I mentioned in the other comment chain) that `get_mouse_buttons()` doesn't work. – Tony Suffolk 66 Mar 19 '21 at 00:17