Fez panda interrupt buttons do not work

Hello,

For a first experiment i created a piece of code that would act like a stopwatch using two buttons.

I implemented the hardware button using the example mentioned here:

http://www.fezzer.com/project/42/button/

I have a spring loaded push button that i connected to pin 11 AND the other side to GND. I’m using the following code to register an eventhandler:


private HardwareButton ResBtn;
private HardwareButton StartBtn;


ResBtn = new HardwareButton(FEZ_Pin.Interrupt.LDR);
            ResBtn.ButtonPressEvent += new HardwareButton.ButtonPressEventHandler(Interupt_ButtonPressEvent);
            StartBtn = new HardwareButton(FEZ_Pin.Interrupt.Di11);
            StartBtn.ButtonPressEvent += new HardwareButton.ButtonPressEventHandler(Interupt_ButtonPressEvent);

When I test this code using the loader (LDR) button i have no problems at all. But when i connect another it doesn’t work. The debugger shows that in the following segment of code the data2 value ==1 instead of 0.


  void OnInterrupt(uint data1, uint data2, DateTime time)
        {
            ButtonState state = (data2 == 0) ? ButtonState.Pressed : ButtonState.NotPressed;

            ButtonPressEvent((FEZ_Pin.Interrupt)data1, state);
            InterruptPort p = button as InterruptPort;
            if (p != null)
            {
                p.ClearInterrupt();
            }
        }

And to be honest i have no idea why. I also played with the glitchfilter settings, googled around the internet but i’ve got no idea why this does not work as expected

What is HardwareButton?

Please try the example in the book, under “Interrupt Port”

Hardware button is the following class:


using System;
using Microsoft.SPOT;
using GHIElectronics.NETMF.FEZ;
using Microsoft.SPOT.Hardware;

namespace FexPandaTimerTest
{
    class HardwareButton : IDisposable
    {
        private InputPort button;
        public delegate void ButtonPressEventHandler(FEZ_Pin.Interrupt pin, ButtonState state);
        public event ButtonPressEventHandler ButtonPressEvent = delegate { };

        public HardwareButton(FEZ_Pin.Interrupt pin)
        {
            button = new InterruptPort((Cpu.Pin)pin, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            button.OnInterrupt += new NativeEventHandler(OnInterrupt);
        }

        public HardwareButton(FEZ_Pin.Digital pin)
        {
            button = new InputPort((Cpu.Pin)pin, true, Port.ResistorMode.PullUp);
        }

        void OnInterrupt(uint data1, uint data2, DateTime time)
        {
            ButtonState state = (data2 == 0) ? ButtonState.Pressed : ButtonState.NotPressed;

            ButtonPressEvent((FEZ_Pin.Interrupt)data1, state);
            InterruptPort p = button as InterruptPort;
            if (p != null)
            {
                p.ClearInterrupt();
            }
        }

        public ButtonState GetState()
        {

            return (button.Read() == false) ? ButtonState.Pressed : ButtonState.NotPressed;
        }

        #region IDisposable Members

        public void Dispose()
        {
            button.Dispose();
        }

        #endregion
    }
}


Above is my class HardwareButton but it is exactly the same as mentioned in the link in my first post. I tried the example and didnt have any problems except when using an external button.

Your code is not same as example driver provided by GHI.
Can you try the code as is first then make changes after you make sure it is working?

Gus,

I even made a copy with the class from the link, checked with two separate buttons but it still doesn’t work.

Strange! Can you please make a very small test code showing the complete test and how it doesn’t work?


 public class Program
    {
        private static InterruptPort button;
        private static InterruptPort button2;

        public static void Main()
        {
            button = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di11, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            button2 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.LDR, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            button.OnInterrupt += new NativeEventHandler(button_OnInterrupt);
            button2.OnInterrupt += new NativeEventHandler(button_OnInterrupt);
        }

        static void button_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            if (data2 == 0)
            {
                Debug.Print("Button pressed" + data1);
            }
        }

      
    }

If i press the button attached to Di11 then the data2 ==1 instead of zero. The other end of the pushbutton is connected to the GND pin. If I press the loader button then data2 will be zero and it will show a message that the button is pressed.

I believe glitch filter with InterruptEdgeBoth interrupts are not supported.
Please either try a high edge or a Low edge. If you need both edges, you have to disable glitch filter.
We will update the ebook.

Mike, I tried both suggestions but neither work.

Well i guess its probably got something to do with my electronic skills instead of my program skills. Because the onboard buttons do work. But i thought they weren’t connected in another way then my external button is.

All you need is a button connected between a pin and ground.

Skip interrupt and try to read the button state once every 100ms and print the value to the debug output. This will help you see what is going on.

Gus, it seems that indeed it had to do with my wiring of the whole thing. Also i changed the Port.InterruptMode.InterruptEdgeBoth to EdgeHigh and it worked. Thanks for your time.

I had similar issues when creating my SD-card detection class.

The value passed to the event handler isn’t reliable.

I fixed it by reading out the value again, like this:


// Declaration
private InterruptPort interrupt = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO33, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);         

// Event handler
private void sdDetectInterrupt_OnInterrupt(uint port, uint state, DateTime time)
{
   // Read input again since the state argument seems unreliable
   if (interrupt.Read())
   {
   }
   else
   {
   }
}