-
• #2
Hi bret,
Yes, this is because there's no switch debouncing built in to Espruino. There's an issue on GitHub open for this as it'd be nice if you could just say:
setWatch(swap_on_down, BTN1, {repeat:true,edge:"rising", debounce:1/*ms*/});
It's been relatively low priority so far I'm afraid though!
-
• #3
Hi Gordon,
Thank you for verifying what I was seeing and explaining that there was no debouncing in version 1v50. It would certainly be very useful to make projects more reliable and have a polished, quality feel. As I write this and check out the issue on GitHub, it looks like you've added the functionality. Thank you very much for that. I look forward to trying it out!
Thanks again for creating and sharing Espruino with the world.
-
• #4
Hi. My first evening with Espruino... and my first program seems to have a lot in common with this thread...
i=0; lastTime=getTime(); function f() { now=getTime(); if ((now-lastTime)>0.2) { lastTime=now; i = (i+1) % 8; digitalWrite(LED1, i&1); digitalWrite(LED2,i&2); digitalWrite(LED3,i&4); } } setWatch(f,BTN,{repeat:true,edge:'rising'});
The intention is that for every press of the button the LEDs count in binary from 000 to 111...
Seems to work! Thanks!
-
• #5
I tested simple de-bouncer. The setWatch is used once, then re-enabled after a period of 200ms just after the associated function is called:
function test(){ console.log("Hello!"); //the actual task done after pressing the BTN1 setTimeout(setupBTN1, 200); //every time test() is ran the BTN1 handler is enabled again after a period of 200ms } function setupBTN1(){ setWatch(test, BTN1, {repeat:false, edge:"rising"}); } setupBTN1(); //single BTN1-triggered test() function call is enabled
-
• #6
I tested this de-bouncer on VL Discovery (BTN1 is an alias to the button available on this board). Not sure if the BTN1 name works on other boards
Bogdan -
• #7
Nice solution, Bogdan. I would improve it to allow passing params from one to another, so you would not need to use globals. This does degrade readability though:
function setupBTN1(customParams) { return function() { function test() { return callback(); } var id = setWatch(test, BTN1, {repeat:false, edge:"rising"}); function callback() { console.log('Hello! watch id was', id, 'and customParams was', customParams); clearWatch(id); setTimeout(setupBTN1(customParams + Math.random()), 1000); } }; } setupBTN1(0)();
-
• #8
I should point out that version 1v51 (in development) has debounce, so I wouldn't worry too much about this unless you want to do it for fun :)
You can get the development build from http://www.espruino.com/binaries/git for the Espruino board or https://espruino-nightly.noda.se/ for others.
-
• #9
A related question is if the RotaryEncoder module has debounce? I noticed that for each click when I turn the knob I always get four pulses. fortunately that is easy to work around. I have not checked the waveforms from the mechanical encoders yet, but I am using two, and one with and one without RC filter for debouncing. Both give four counts per click. (Mecanical encoders have a lot of contact bounce and need to have hardware or software debouncing)
-
• #10
The encoders have a really messy waveform but they cope quite well. When 1v51 comes out I'll enable debounce though.
4 counts per click is expected (I was surprised too). Each click represents a whole round of 00,01,11,10
-
• #11
> require("Encoder").connect(A1,A5,function (direction) { step += direction; if (step >=4) { pos += 1; if (pos>96) { pos=96; } step=0; print_pos(); } if (step <=-4) { pos += -1; if (pos<20) { pos=20; } step=0; print_pos(); } });
this is my workaround for getting one count per click (probably there is a more elegant way - I am new to javascript..)
the encoders I have are the cheapest kind, but used in this way it does not seem to be any difference if I have RC filters to handle debounce or not. good to know that debouncing will be introduced in the code later on. -
• #12
I am sure v1.52 is fine. Try,
setWatch('console.log(c=c+1||0)',BTN1,{repeat:true, edge:"falling", debounce:10});
it works perfectly. Or,
setWatch('console.log(c=c+1||0)',BTN1,{repeat:true, edge:"both", debounce:10});
too.
In another post about the LED and button tutorial, the following was stated:
I used that code but sometimes when I press the button once, my function gets called twice. I thought maybe I was being careless and tried very carefully to press and release it without any hesitation. I found that, no matter how careful I was, sometimes the function would get called once and sometimes 2-3 times. I changed the code to use "falling" instead and it seems to work reliably - the function only gets called once per button press.
Has anyone else experienced this behavior? Perhaps there is a bug? Is the switch debouncing implemented in hardware or software with Espruino?