(this is a flow on from discussions on InterrruptEdgeModeBoth)
When using an InterruptPort with a Native Event Handler, when using Port.InterruptMode.InterruptEdgeBoth, the information about the “state” of the interrupt does not reflect a particular state. Should it?
Test rig: Panda with 4.1.7.0, Di13 connected to a magnetic reed switch, other side of switch to GND, powered by USB.
App:
static long Mycount = 0;
public static void Main()
{
// Blink board LED
bool ledState = false;
OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, ledState);
InterruptPort DoorSensor = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di13, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
DoorSensor.OnInterrupt += new NativeEventHandler(DoorSensor_Capture);
while (true)
{
// Sleep for 500 milliseconds
Thread.Sleep(500);
// toggle LED state
ledState = !ledState;
led.Write(ledState);
}
}
static void DoorSensor_Capture(uint port, uint state, DateTime time)
{
Mycount++;
Debug.Print(Mycount+": " + state + " " + time + "." + time.Millisecond + "; " + time.Ticks );
}
On closing the switch:
Debug output often shows 3 or 4 passes of the interrupt on what should be one “trigger” when I close the switch by bringing the magnet close to it (some of that could be considerd noise, accepted). But most often, all of the passes show a state of 1; only infrequently will one record a 0. The milliseconds between individual readings is always close as well - well within 2 msec.
On opening the switch:
Almost always reliably there is only one event pass, and always reports a state of 1.
Here’s a sample output. Annotations at the end are mine
so there certainly isn’t a pattern - sometimes when 4 interrupts on close register, one has a zero “status” and othertimes it won’t; but in that sample I haven’t found one that gave a zero when only 3 interrupts were registered on closing the switch.
A reed switch bounces, thats a fact. So either debounce the switch in hardware, or do it in software. Also the supplied voltage is important (i read that somewhere), and surely 3.3V is too low.
I walked away from using reed switches, and replaced them with hall effect sensors. Allegro is a good source (not at home right now, can’t remember the part number).
I use them with InterruptEdgeBoth and can’t say I have any problems.
Our driver doesn’t handle denouncing when using edge both. The fix is easy, read the pin state in the interrupt handler and ignore the passed in value.
I noticed the same when creating the SD card detection class.
Fix is like Gus says:
private void sdDetectInterrupt_OnInterrupt(uint port, uint state, DateTime time)
{
// Read input again since the state argument seems unreliable
if (interrupt.Read())
reed switch and bounce - as I said, I expect some bounce, that is fine.
What I didn’t expect was the STATE to come in the way it did. I expected a lot more with a state of zero; the fact that that occurs very infrequently is just, well, weird.
The issue exists in any use of interrupt though, use two bare wires plugged into the board, when you connect them you’ll see this. I’m surprised there hasn’t been more questions about the original driver for the push button e-block because it uses the state passed in to detect pressed or not-pressed scenarios, which therefore shouldn’t work.
If we’re doing a re-read elsewhere (SD detect) then I can handle that. Still seems like an issue worth addressing in my view.
Eric, you recommended using Hall Effect sensors instead reed switches. That sounds like a great idea.
I want to use these to detect doors or windows opening/closing so I need to use magnets with the sensors. Have you used these with magnets? Can you recommend a suitable magnet to use?
These are the hall effect sensors i use: Allegro A3214
Magnets, whatever you want, the sensor is bi-polar. Did you know that in Hard disks there are tiny magnets that are of great use for this kind of application?