Main Site Documentation

Problem with simple InterruptPort


#1

I’m working on a simple garage door sensor with a magnetic switch, and attaching it to an InterruptPort. For my tests, I just have a jumper from IO14 and a jumper from the 3v, and to turn it “on” I cross them.

Anyway, here’s my simple code. The problem is it’s unreliable. Here’s the output where I basically crossed and uncrossed the jumper wires every second or two. My final state was open, so the interrupt should have sent me a 0 state, but it didn’t.

I’m new to this, so I’m sure I’m doing something wrong…

Output:
1/01/2009 02:31:38: interrupt=True
01/01/2009 02:31:40: interrupt=False
01/01/2009 02:31:41: interrupt=True
01/01/2009 02:31:43: interrupt=True

Any suggestions?


private static InterruptPort _garageSwitch = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO14, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
		static void GarageSwitchOnInterrupt(uint port, uint state, DateTime time)
		{
			bool interruptState = state != 0;
			Debug.Print(DateTime.UtcNow + ": interrupt=" + interruptState);
		}
		public static void Main()
		{
			_garageSwitch.OnInterrupt += GarageSwitchOnInterrupt;
			Thread.Sleep(Timeout.Infinite);
			return;
		}


#2

You are using both edges. Can you try to trigger interrupt on either edge?


#3

Hi Gus,

When I do that, I only get either true or false (depending on whether I use InterruptEdgeHigh or InterruptEdgeLow) only. What I really wanted was true for closed, false for open so I needed both.

What I’m trying to do as my first project is a basic garage door sensor project. I have a relay switch hooked up to a wireless transmitter for my door opener, and I have a magnetic switch to tell me when the door is open/closed. I finished the hardware and was on to the software when I noticed this issue.

I was hoping I could use an InterruptPort and it would tell me anytime the door open/closes reliably. But it seems to “miss” events for some reason as I described. It works most of the time but not reliably for every event like I’d hoped. Seems like such a simple thing. Maybe I should use the 5v source instead of 3v? Or use my own pulldown resistor instead of the CPU’s? Any other ideas?


#4

Jason,
Have you tried increasing the GlitchFilterTime?
Try adding this line as first line in Main() would set it to 200 miliseconds. In your scenario, you could probably even set it to 1000. Good luck!

 Microsoft.SPOT.Hardware.Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 200);

#5

Hari - thanks for the suggestion. I tried that but it doesn’t seem to matter.

I tried this code:


private static InterruptPort _garageSwitch = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO14, true, 
Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
static void GarageSwitchOnInterrupt(uint port, uint state, DateTime time)
{
	bool interruptState = state != 0;
	Debug.Print(DateTime.UtcNow + ": interrupt=" + interruptState);
}
public static void Main()
{
	Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 1000);
	_garageSwitch.OnInterrupt += GarageSwitchOnInterrupt;
	Thread.Sleep(Timeout.Infinite);
	return;
}

And I got this output. You can see from the times when I crossed/uncrossed my jumpers, but I was doing it rapid-fire, more often than once a second, so the glitch filter seems to be doing its thing but I’m not getting the low edge interrupt reliably at all.

Again my setup is very simple, wire in IO14 and wire from 3v.

01/01/2009 00:08:20: interrupt=True
01/01/2009 00:08:21: interrupt=True
01/01/2009 00:08:22: interrupt=True
01/01/2009 00:08:23: interrupt=False
01/01/2009 00:08:24: interrupt=True
01/01/2009 00:08:25: interrupt=True
01/01/2009 00:08:26: interrupt=True

I also tried turning off the glitch filter. It would trigger on low edge more often, but in the below I still ended with the wires not touching and never got the low edge interrupt.

01/01/2009 00:12:14: interrupt=False
01/01/2009 00:12:15: interrupt=True
01/01/2009 00:12:15: interrupt=False
01/01/2009 00:12:16: interrupt=True
01/01/2009 00:12:16: interrupt=False
01/01/2009 00:12:17: interrupt=True
01/01/2009 00:12:17: interrupt=True


#6

I’ve made some tests and have the same behaviour :frowning:

If I hook say DI10 to IO14 and generate pulses on DI10, then I see correct results.

But, if I manually hook/un-hook 3.3V to IO14, then once in while (quite often, in fact) I get a true value even though the pin is not wired :think:


#7

That’s probably because your pin is floating. You should add a small circuit for pulling up or pulling down the signal.


#8

Same results with a pulldown resistor :’(


#9

I know you need both edges. I asked you to try one just to see if you would have any problems.

Let us look into this but for now create a thread to check your switch 10 times per second


#10

With or without an external pulldown resistor and Port.InterruptMode.InterruptEdgeLow, I get interrupts with value 0 when I plug in the 3.3V :o

If I unplug 3.3V, I of course get an interrupt with value 0, as expected. Something weird, here :think:

Edit: it looks like a glitch problem because I’m using the same code on my professionnal project and don’t have this behaviour. The “EdgeHigh” signal comes from a wheel encoder.


#11

Maybe you can post a simple schematic of your wiring? I suspect your seeing bounce events longer than the glitch filter. I have found that triggering my interrupt on both edges and even adding a bit of a delay can help in such cases.

For example

Interrupt->SW on
Record Timestamp-On
Interrupt->SW off
Record Timestamp-Off
If (Timestamp-Off - Timestamp-On > threshold) Then event is valid


#12

Gus - I didn’t have any problems with one edge or the other so that seems to work. As for the polling method, yeah - I’ll do that for now, should work fine - thanks for your help.

Bec - thanks for confirming I’m not missing anything at least too obvious :wink:

Jeff - based on my limited understanding I don’t think it’s glitch filter related. If I disable the glitch filter wouldn’t I get multiple events, but still finally get the right value at some point? When I ran without glitch filter, I still completely missed my final event - I had the contact open, but never got a false value from the interrupt. I also tried different glitch filter values, including extremely long ones (1s) and missed some low event deliveries.


#13

Jeff, I understand your point, but then it would also confirm that it’s not working as expected :think:

Jason4 : it may be even more obvious than we think, thus making us miss it anyway :wink:


#14

Not sure how the guys have covered glitch filter on edgeBoth as this maybe tricky. This can cause one of the edges to be lost between glitches! This can be really tricky.

Can someone try something? Make a small program (5 lines) that reads a button and then debug.print up or down.

Ideally, you should see

up
down
up
down
up

but if there is an error you would see

up
down
up
up <<----------- this shouldn’t happen but if there is glitch filter then it may happen?
down
up
down

I will forward this to our developers to double check


#15

Without pulldown resistor :

public class Program
    {
        static InterruptPort Inter1 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO14, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);

        public static void Main()
        {
            Inter1.OnInterrupt += Inter1_OnInterrupt;
            Thread.Sleep(Timeout.Infinite);
        }

        static void Inter1_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Debug.Print(data2 == 1 ? "up" : "down");
        }
    }

Result :

down  --> initial state, I suppose (no button press)
up
down
up
up
up
up
up
down

Now, with a pulldown resistor :

up
down
up
down
up
down
up
down
up
up
up
down
up
down
up
down

It happens less often, though. But still…


#16

I’ve just tried with a mecanical relay and I have the same result.

But this time, it was longer before it happens. The main reason for this, to me, is the fact the the relay can’t switch very fast, so I wait 1 sec between two switches.

Here are the components I’ve used for those tests :

http://www.phidgets.com/images/3051.jpg

http://gotronic.fr/commut-opt/07366-opt.jpg

http://gotronic.fr/commut-opt/07192n-opt.jpg

Edit: the doesn’t work anymore ?


#17

Guy wait wait,

From user manual

[quote]Enabling interrupts for both rising and falling edges is supported but in
this case the glitch filter is disabled[/quote]


#18

RTFM again :wall:

Thx Josef :’(


#19

Well, I still have a problem. Even disabling the glitch filter I miss some low events.


private static InterruptPort _garageSwitch = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO14, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
		static void GarageSwitchOnInterrupt(uint port, uint state, DateTime time)
		{
			bool interruptState = state != 0;
			Debug.Print(DateTime.UtcNow + ": interrupt=" + interruptState);
		}
		public static void Main()
		{
			_garageSwitch.OnInterrupt += GarageSwitchOnInterrupt;
			Thread.Sleep(Timeout.Infinite);
			return;
		}

I get the below by crossing/uncrossing the wires. Without glitch filter I would expect multiple events maybe, but in this case I ended with an open circuit and never got any open circuit interrupt.
01/01/2009 00:00:42: interrupt=False
01/01/2009 00:00:42: interrupt=True
01/01/2009 00:00:43: interrupt=False
01/01/2009 00:00:43: interrupt=True
01/01/2009 00:00:43: interrupt=True
01/01/2009 00:00:43: interrupt=True
01/01/2009 00:00:44: interrupt=True

Is this expected, and if so is there any point at all to ever using InterruptEdgeBoth, as it seems it serves no purpose since there’s no guarantee you’ll receive any given event.