Problem with edge:"rising"

Posted on
  • In another post about the LED and button tutorial, the following was stated:

    setWatch can be called like setWatch(swap_on_down, BTN1,
    {repeat:true,edge:"rising"}); so that it only calls your swap_on_down
    function when the button becomes pressed.

    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?

  • 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!

  • 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.

  • 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!

  • 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 
    
  • 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

  • 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)();
    
  • 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.

  • 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)

  • 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

  • > 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.

  • 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.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Problem with edge:"rising"

Posted by Avatar for bret @bret

Actions