Interrupt Issues

We are having issues with double interrupts that have the same IO state. We have disabled the glitch filter as suggested, however we are still getting the double interrupt with the same state of the IO. We also have an external pull up resister, so no need for that in the code. Here is a sample code:


using System;
using Microsoft.SPOT;

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


namespace InterruptTestApp
{
    public class Program
    {
        static InterruptPort _pwrIndication;

        public static void Main()
        {
            _pwrIndication = new InterruptPort(EMX.Pin.IO1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            _pwrIndication.OnInterrupt += new NativeEventHandler(_pwrIndication_OnInterrupt);
           

            Thread.Sleep(Timeout.Infinite);
        }

        static void _pwrIndication_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Debug.Print("Data 2 " + data2.ToString() + " Time:" + time.Ticks.ToString());
            Debug.Print("_pwrIdication Read = " + _pwrIndication.Read().ToString());
        }
    }
}

Here is the output:

Data 2 0 Time:128752466173410058
_pwrIdication Read = False
Data 2 1 Time:128752466185727705
_pwrIdication Read = True
Data 2 0 Time:128752466185728691
_pwrIdication Read = True
Data 2 0 Time:128752466187057991
_pwrIdication Read = False
Data 2 0 Time:128752467234118642
_pwrIdication Read = False
Data 2 1 Time:128752467234119968
_pwrIdication Read = False
Data 2 1 Time:128752467234122152
_pwrIdication Read = False
Data 2 0 Time:128752467234123378
_pwrIdication Read = False

As you can see we get double interrupts where the Data2 variable is = to uint 1 and a few cases where it is equal to 0. As this is a edge interrupt, this should not be possible to get two interrupts in a row where the data2 = 1 or two in a row where data2 = 0.

It seems that the interrupt handler is returning the wrong state of Data2.

Dale

Is this to decode a signal or you have buttons?

The first thing to do is to remove the glitch filter which doesn’t work well with both edges. You can use it if you have one edge.

As you can clearly see it is disabled. Am I missing something here?

We are decoding a relay closure, we have an external filter that accounts for debouncing.

As you can see from the output data, we get the wrong status and get two interrupts with the same data2 status, which if its an edge interrupt should be impossible, as a value of 0 or false should not trigger the interrupt if it is already 0 or false?

Also note that when we physically read the IO port, we get the wrong status. Which might happen I guess if there is some latency on the reading of the port. However, the interrupt should read the correct status.

Dale

since an internal filter is being used, I suspect that you are spending too much time in the voltage band between 0 and 1, which can result in funny things happening. check your rc tme.

Mike,

Normally I would agree with you, but however we are using an Opto Isolated Transistor with an external pull up, so it lingering around in the transition area is very remote.

Can someone run the example code and pulse an input and see if they get this same issue. I have seen others on here with similar issues.

Dale

Can you connect it to a PWM signal that is running slow and try it? This will rule out your circuit.

I’ve been told in the past that the best way to get reliability in interrupt routines was to do another read() of the value of the pin and if it was the same as the “saved state” then just bail on the interrrupt handler.

               bool CurrentState = OpenedSensor.Read();
                if (CurrentState == OpenedSensorState) return;
 //here you know you have changed state. 

I had started a thread here on this a while ago, and this was the outcome of that discussion. No amount of debounce external helped either. This has been very reliable since.

Doing a read of a signal in its interrupt event handler is not reliable. There will be several milliseconds between the time that the hardware interrupt occurred and when your event handler is called.

The method you described above can lose signal transitions if the signal changes rapidly.

So we ran a function generator into the input and everything ran fine up to 2khz. We also scoped the input into the EMX and the signal looked good. Where we get problems I think is if the pulse length is very short, then we get wrong information into the Interrupt Handler.

I agree, it seems very unreliable to read the sensor input in the interrupt routine, as sometimes it does not read the correct level as Mike described.

Any thoughts?

Dale

Sure, depending on the speed your interrupts are occuring the reliability in re-reading is an issue. In my discussed case, the sensor changes very infrequently and only in seconds so I can take the hit.

We have confirmed that the issue is with the pulse width (duty cycle). If the pulse width is too short, the falling edge is not detected. This is obviously an issue as we end up missing interrupts, and can get into a stale state.

The only way to work around this is to poll on a frequent basis, however that really defeats the purpose of interrupts. We are not using the pulses for timing so we can use a polling scheme, however if we were using a edge detection for a rough timing algorithm then using interrupts is the only way to go, and it seems that they are broken.

We use interrupts in other sections of our code for doing some conversion (serial to ethernet) and that is really what is concerning me, we could get into trouble there.

Gus, Can you comment, it seems that this is an ongoing issue with the community as there has been discussions on this issue before.

Dale

How about quantifying too short? I don’t remember anyone in the past having an issue with too short of a pulse width, but there must be some limitation on the MF devices.

Have you considered going to chip manual and checking the specifications?

You can use one edge and things will work better. The problem with 2 edges is that if you have noise then you may see false data. On top of that, glitch filters won;t work nicely in edge both. Same happens if the transition is too fast.

If you feed a clean signal in, you will see valid data. Perhaps use only one edge?

Unfortunately I cannot use just one edge, I have to detect both edges. Why are the interrupts not queued? So they eventually come in. I guess I don’t understand how I can miss interrupts, or get false data.

Dale

2 pins maybe?

Again, the design is already built and is already been through qualifications (CE, EMI, vibration testing) so we can’t change the hardware design.

Dale

Have you considered to implement the interrupt handler in RLP? I have an example here: http://code.tinyclr.com/project/429/counting-pulses-over-time-with-rlp/

Thanks for the info, Ill take a look at it. I was really hoping that GHI would take a look at it as clearly it is an issue and it should work out of the box, and not have to write work-arounds.

Dale

It is normal that managed code can’t follow an interrupt at 2KHz on the EMX. ASAIK the only way to go is RLP.

I replied to the email you sent to us already.