5 Replies Latest reply on Aug 18, 2016 1:18 PM by Intel Corporation

    How to debounce momentary switches on Gpio...

    jayls

      without delaying interrupt service routines?

       

      thanks.

        • 1. Re: How to debounce momentary switches on Gpio...
          Farit

          You can use the gpio-keys Linux module to connect switches.

          Connecting Buttons to Intel Edison | Hobby

           

          That article describes a function that sets the pullup resistors.

          You can code without it if you use external pullup resistors.

           

          The file arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c

          already has a definition for the power button. You can add your own definitions.

          You can set the debounce interval:

          .debounce_interval = 100

           

          /*

          * we will search these buttons in SFI GPIO table (by name)

          * and register them dynamically. Please add all possible

          * buttons here, we will shrink them if no GPIO found.

          */

          static struct gpio_keys_button gpio_button[] = {

                  {

                          .code = KEY_POWER,

                          .gpio = -1, /* GPIO number */

                          .active_low = 1,

                          .desc = "power_btn",/*Button description*/

                          .type = EV_KEY,

                          .wakeup = 0,

                          .debounce_interval = 3000,

                  },

                  {

                          .code = KEY_UP,

                          .gpio = 182,

                          .active_low = 1,

                          .desc = "up_btn",

                          .type = EV_KEY,

                          .wakeup = 0,

                          .debounce_interval = 100,

                  },

                  {

                          .code = KEY_DOWN,

                          .gpio = 12,

                          .active_low = 1,

                          .desc = "down_btn",

                          .type = EV_KEY,

                          .wakeup = 0,

                          .debounce_interval = 100,

                  },

                  {

                          .code = KEY_ESC,

                          .gpio = 13,

                          .active_low = 1,

                          .desc = "back_btn",

                          .type = EV_KEY,

                          .wakeup = 0,

                          .debounce_interval = 100,

                  },

                  {

                          .code = KEY_ENTER,

                          .gpio = 183,

                          .active_low = 1,

                          .desc = "down_btn",

                          .type = EV_KEY,

                          .wakeup = 0,

                          .debounce_interval = 100,

                  },

          };

           

          Then you can read events from /dev/input/event0

          cat /dev/input/event0

           

          • 2. Re: How to debounce momentary switches on Gpio...
            Intel Corporation
            This message was posted on behalf of Intel Corporation

            Hello jayls,
             
            I'm afraid I don't understand what you are trying to do, could you please explain us a little bit more about the context of the issue?
            When are you experiencing momentary switches on Edison's GPIOs? Is it when an interrupt is triggered? You mention that you don't want to delay the interrupts, have you tried this? What effect did it have? What else have you tried?
             
            Please be as detailed as possible, every detail will be of much help.
             
            -Peter.

            • 3. Re: How to debounce momentary switches on Gpio...
              jayls

              Hi Peter, here's some more info...

               

              Basically my project is building an audio controller. what might best be described as a wiimote like device. I.e. it contains a number of buttons/switches, and a 9DOF accel/gyro/magnetometer setup. The idea is that on occasions, depending on program logic, a button press might indicate the beginning (or end) of a stream of data to be sent to a receiving computer via wifi, or it might indicate a single value to be sent to the receiving computer via wifi. This could be a boolean value, or it could be a accel value at the time the button was pressed.

               

              Obviously I want the edison's response to a button press to be as fast as possible. The buttons are fairly cheap little things and so there is an issue of "bounce" when a key is pressed - a single button press induces more than one gpio interupt routine. This I gather is an inherent limitation of any button/switch.

               

              This problem can be solved either by hardware - a combination of a resistor and a capacitor, or by software in a fairly crude or alternatively fairly sophisticated manner

               

              I gather from here:

               

              Exploring Edison - Mraa GPIO

               

              That only one gpio interupt routine can run at a time. Thus a simple and crude debounce routine would be to simply add a delay into the interrupt routine, as is suggested in the link

               

              something like this:

               

              void onClick36(void* args)

              {

                  usleep(BOUNCE_DELAY);

                  if (flag36==false)

                  {

                      cout << "onClick36 clicked" << endl;

                      flag36 = true;

                  }

                  else {

                      flag36 = false;

                  }

              }

               

              I'm having to set BOUNCE_DELAY in excess of 1500 micro seconds to get even remotely acceptable results, and while if push came to shove I could live with this, I am wondering whether there are better approaches.

               

              I can see that farit's answer represents an alternative approach, bypassing mraa altogether - something that the linked article hints at. Unfortunately it is a little too sophisticated for my current level of knowledge in that area (hacking the yocto kernel?), although if I have to develop the requisite skills I will. Any or all further information on this, in the meantime, would be gratefully received. I am sure that this must be a common problem area.

               

              farit's answer links to Connecting Buttons to Intel Edison | Hobby

               

              which suggests that the edison contains pull up resistors. Is this so, or are they only on the arduino breakout board. Info on this would be useful in terms of implementing a hardware solution, as would information about the load presented by a gpio to the outside world, if that makes sense?

               

              As I say, I am functioning at the limits of my current knowledge at the moment, although I expect this to grow with time. In the meantime please bear with me.

              • 4. Re: How to debounce momentary switches on Gpio...
                Intel Corporation
                This message was posted on behalf of Intel Corporation

                Hi jayls,
                 
                As you mention this issue can be solved by a hardware approach, in fact, this is usually the way this behaviors are attended. If you would like to learn more about it, I'd suggest you to read http://www.labbookpages.co.uk/electronics/debounce.html.
                 
                Also, if you would like to deal with this behavior through software then the usual way of using an interrupt is that when an interrupt is triggered it raises an interrupt flag (you can use a Boolean variable) to indicate that the interrupt is running and that interrupt signals won't be captured until the interrupt routine finishes. At the end of the interrupt routine you will have to get back down the interrupt flag to indicate that it has finished. Have you implemented this flag?
                 
                Regarding Edison's pull-up resistors, you can check the module's hardware guide (http://www.intel.com/content/dam/support/us/en/documents/edison/sb/edison-module_HG_331189.pdf) in section 4.7, there you will find that the module has these resistors and that their values can be 2, 20, or 50 kΩ.
                 
                I hope this information helps you.
                -Peter.

                • 5. Re: How to debounce momentary switches on Gpio...
                  Intel Corporation
                  This message was posted on behalf of Intel Corporation

                  Hi jayls,

                  Do you have any updates about this?

                  -Peter.