Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino Plus 2 - InterruptEdgeLevelHigh


  • Please log in to reply
14 replies to this topic

#1 Lunddahl

Lunddahl

    Advanced Member

  • Members
  • PipPipPip
  • 152 posts
  • LocationEurope, Denmark

Posted 30 November 2012 - 11:03 PM

Hi There!

I was trying to solve the classic problems around a bouncing contact for my Beer Timer project, and i got caught up into trying to understand all about how an simple InterruptPort works.

Now from what i seem to read InterruptEdgeHigh and InterruptEdgeLevelHigh is generating an interrupt at the same time, on the rising edge, but the latter one is only generating one interrupt and then disables interrupts until the .ClearInterrupt() method is called on the InteruptPort object.

However running the code below, is working fine, but trying to use the "level" type InterruptModes fails with an error, when i try to subscribe to the interrupt event.

A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll

on:

Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);

The full code is here, however the failing lines is commented out:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace NP2.Example_Button_InterruptPort
{
    public class Program
    {
        static OutputPort Led;
        static InterruptPort Button;
        static DateTime Button_LastInterruptTime = DateTime.Now;
        static Boolean Led_State = false;

        public static void Main()
        {
            Led = new OutputPort(Pins.ONBOARD_LED, false);
            Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeHigh);
            //Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeLevelHigh);
            Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);
            
            Thread.Sleep(Timeout.Infinite);
        }

        static void Button_OnInterrupt(uint port, uint state, DateTime time)
        {
            if (Button_LastInterruptTime.AddMilliseconds(200) < time)
            {
                Led_State = !Led_State;
                Button_LastInterruptTime = time;
                Led.Write(Led_State);
            }

            //Thread.Sleep(10);
            //Button.ClearInterrupt();
        }
    }
}

Why is it not working, is there another thing i do not know yet. :-)

- Ulrik

#2 Lunddahl

Lunddahl

    Advanced Member

  • Members
  • PipPipPip
  • 152 posts
  • LocationEurope, Denmark

Posted 04 December 2012 - 11:17 PM

No one knows about the "level" type interupts, are they not implemented, or just broken ? Chris ?

#3 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 December 2012 - 02:34 AM

Hi Ulrik, You are correct...the level interrupts fire once and then auto-disable. It's a useful feature for single-shot interrupts. Each family of microcontroller has its own HAL for NETMF. Some implement the level interrupts and some do not. The core STM32 HAL does not. That said...let's add this to the STM32 core. I've added to our short list of new features to add to Netduino Plus 2. We should be able to carry it across to Netduino Go as well. Is this a blocking issue for you? We're trying to keep the frequency of updates to a reasonable number...but we could get you a beta release with this feature within a few days if you're in need :) Chris

#4 Lunddahl

Lunddahl

    Advanced Member

  • Members
  • PipPipPip
  • 152 posts
  • LocationEurope, Denmark

Posted 05 December 2012 - 02:51 PM

That said...let's add this to the STM32 core. I've added to our short list of new features to add to Netduino Plus 2. We should be able to carry it across to Netduino Go as well.


Nice, very nice indeed.

Is this a blocking issue for you? We're trying to keep the frequency of updates to a reasonable number...but we could get you a beta release with this feature within a few days if you're in need :)


It's not a blocking issue at all, and the code above is an example on how you can live without this feature perfectly fine in the case of manual contacts or relays.

But in the future i think level interupts will be nice to have, as the solution is cleaner and more understandable.

People that are new into electronics often forget that contacts bounces, and the MCU they are using is fast enough to detect that, several times for every press/change.

And the netduinos do attract a lot of those people, myself included.


- Ulrik Lunddahl

#5 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 06 December 2012 - 03:46 PM

... People that are new into electronics often forget that contacts bounces, and the MCU they are using is fast enough to detect that, several times for every press/change. ...


That being said, I am curious: do you find that the glitch filter option of the input port to be ineffective? debounce is truly one of my very least favorite chores, so I was pleased to see this in .NETMF

-dave

#6 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 06 December 2012 - 04:01 PM

That being said, I am curious: do you find that the glitch filter option of the input port to be ineffective? debounce is truly one of my very least favorite chores, so I was pleased to see this in .NETMF

The glitch filter does not help much to handle debouncing, because it samples the input during very short time period, usually only a few microseconds (e.g. four times 'get pin state' native function call, which is basically direct GPIO register access with some overhead), bouncing occurs in time intervals orders of magnitude longer, tens or even hundreds of milliseconds, depending on the switch mechanical construction.

#7 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 06 December 2012 - 08:15 PM

The glitch filter does not help much to handle debouncing, because it samples the input during very short time period, usually only a few microseconds...


Oh, interesting, I thought keybounce was the whole raison detre for glitch filter. Actually googling "netmf glitch filter" yields some indications that this is the intended purpose (e.g. first hit http://wiki.microfra.../index.php/GPIO and also the Microsoft http://msdn.microsof...y/cc532245.aspx); not that I believe everything I read on the web! But yes microseconds is too short, I usually use 20-50ms in my c/asm code implementations...



-dave

#8 Lunddahl

Lunddahl

    Advanced Member

  • Members
  • PipPipPip
  • 152 posts
  • LocationEurope, Denmark

Posted 07 December 2012 - 01:08 AM

Oh, interesting, I thought keybounce was the whole raison detre for glitch filter. Actually googling "netmf glitch filter" yields some indications that this is the intended purpose (e.g. first hit http://wiki.microfra.../index.php/GPIO and also the Microsoft http://msdn.microsof...y/cc532245.aspx); not that I believe everything I read on the web! But yes microseconds is too short, I usually use 20-50ms in my c/asm code implementations...


You can actually Get and Set the Cpu.GlitchFilterTime yourself, but as it works globally i have opted out of that solution, simply because i am afraid it might affect "other stuff" too.

With the fast CPU's we have the glitch filter might be able to filter out some noice, or not clean signals from other circuits, but for bounces from manual keys it's not usable.

I originally tested the glitch filter on the onboard button, and there was no noticeable difference whether used or not.

- Ulrik Lunddahl

#9 SenCan

SenCan

    New Member

  • Members
  • Pip
  • 6 posts

Posted 02 February 2013 - 02:42 AM

Hi There!

I was trying to solve the classic problems around a bouncing contact for my Beer Timer project, and i got caught up into trying to understand all about how an simple InterruptPort works.

Now from what i seem to read InterruptEdgeHigh and InterruptEdgeLevelHigh is generating an interrupt at the same time, on the rising edge, but the latter one is only generating one interrupt and then disables interrupts until the .ClearInterrupt() method is called on the InteruptPort object.

However running the code below, is working fine, but trying to use the "level" type InterruptModes fails with an error, when i try to subscribe to the interrupt event.

[font="'Courier New';"]A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll[/font]

on:
 

Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);
The full code is here, however the failing lines is commented out:

using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace NP2.Example_Button_InterruptPort{    public class Program    {        static OutputPort Led;        static InterruptPort Button;        static DateTime Button_LastInterruptTime = DateTime.Now;        static Boolean Led_State = false;        public static void Main()        {            Led = new OutputPort(Pins.ONBOARD_LED, false);            Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeHigh);            //Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeLevelHigh);            Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);                        Thread.Sleep(Timeout.Infinite);        }        static void Button_OnInterrupt(uint port, uint state, DateTime time)        {            if (Button_LastInterruptTime.AddMilliseconds(200) < time)            {                Led_State = !Led_State;                Button_LastInterruptTime = time;                Led.Write(Led_State);            }            //Thread.Sleep(10);            //Button.ClearInterrupt();        }    }}
Why is it not working, is there another thing i do not know yet. :-)

- Ulrik

 

Hi There!

I was trying to solve the classic problems around a bouncing contact for my Beer Timer project, and i got caught up into trying to understand all about how an simple InterruptPort works.

Now from what i seem to read InterruptEdgeHigh and InterruptEdgeLevelHigh is generating an interrupt at the same time, on the rising edge, but the latter one is only generating one interrupt and then disables interrupts until the .ClearInterrupt() method is called on the InteruptPort object.

However running the code below, is working fine, but trying to use the "level" type InterruptModes fails with an error, when i try to subscribe to the interrupt event.

[font="'Courier New';"]A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll[/font]

on:
 

Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);
The full code is here, however the failing lines is commented out:

using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace NP2.Example_Button_InterruptPort{    public class Program    {        static OutputPort Led;        static InterruptPort Button;        static DateTime Button_LastInterruptTime = DateTime.Now;        static Boolean Led_State = false;        public static void Main()        {            Led = new OutputPort(Pins.ONBOARD_LED, false);            Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeHigh);            //Button = new InterruptPort(Pins.ONBOARD_BTN, false, ResistorModes.Disabled, InterruptModes.InterruptEdgeLevelHigh);            Button.OnInterrupt += new NativeEventHandler(Button_OnInterrupt);                        Thread.Sleep(Timeout.Infinite);        }        static void Button_OnInterrupt(uint port, uint state, DateTime time)        {            if (Button_LastInterruptTime.AddMilliseconds(200) < time)            {                Led_State = !Led_State;                Button_LastInterruptTime = time;                Led.Write(Led_State);            }            //Thread.Sleep(10);            //Button.ClearInterrupt();        }    }}
Why is it not working, is there another thing i do not know yet. :-)

- Ulrik

Ulrik, thanks for your exaple sketch. How would onInterrupt work if we had multiple inputs to watch and if any is ON do something?



#10 SenCan

SenCan

    New Member

  • Members
  • Pip
  • 6 posts

Posted 02 February 2013 - 02:47 AM

Ulrik, thanks for your example sketch. How would you program "onInterrupt"  if we had multiple inputs to watch and if any is ON do something?



#11 Lunddahl

Lunddahl

    Advanced Member

  • Members
  • PipPipPip
  • 152 posts
  • LocationEurope, Denmark

Posted 02 February 2013 - 07:18 PM

Ulrik, thanks for your example sketch. How would you program "onInterrupt"  if we had multiple inputs to watch and if any is ON do something?

 

If i understand you correctly you have a case where you would want to react on more than one button, in that case i would create more interuptports, subscripe to interupts from all ports from one generic eventhandler.

 

That eventhandler would now get all interrupts, but they are fired with parameters, you should look for the port parameter, that should show you from what interuptport the interupt is coming.

 

- Ulrik Lunddahl



#12 SenCan

SenCan

    New Member

  • Members
  • Pip
  • 6 posts

Posted 07 February 2013 - 01:35 AM

Thanks for reply. I will try..

#13 karpediemnow

karpediemnow

    New Member

  • Members
  • Pip
  • 4 posts

Posted 07 November 2013 - 11:01 PM

Hello,

I have tried to use 

 

[color=rgb(102,0,102);]InterruptModes[/color][color=rgb(102,102,0);].[/color][color=rgb(102,0,102);]InterruptEdgeHigh[/color]

 

with new  Netduino Plus 2 (v4.2.2.2) but I have same issue.

 

Any Update?

 

Regards

Gianpaolo



#14 ppumkin

ppumkin

    New Member

  • Members
  • Pip
  • 1 posts

Posted 10 May 2014 - 08:19 PM

I am using Sparkfun weather station to make some C# code to go out in the wild.

 

But the HighLevelEdge still throws this error. So I get 0.002 ms bounce issues.

 

12:06:51.044 Trigger
12:06:51.045 Trigger
12:06:51.047 Trigger
 
Have to use softdebounce.
 
I  installed 4.2, but for some reason I cant run it in VS2012, so I installed the other 2010 SDK and VS2010, but the target it 4.2


#15 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 11 May 2014 - 03:27 AM

Hi ppumkin,

The 4.2 SDK uses the older Visual Studio 2010 release. If you install the VS2012/VS2013 SDKs, they will include support for 4.1, 4.2 and 4.3.

Chris




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.