Jeroen Swart

.NET Architect

Netduino - Getting Started with switches

After getting the blinking LED, the next thing to do is experiment with a switch. Besides an on-board LED, the Netduino also comes with an on-board switch, so we can work without extra components.

There are two ways to use a digital input-port. As an InputPort, which requires us to constantly check for an input-value ourselves, or as an InterruptPort, which will provide an event when the value changes. I will show code for each.

For this example, the program will turn the LED on when the button is pressed. When using the on-board switch, the program may look like this:

public class Program
{
    public static void Main()
    {
        // initialize the onboard LED
        OutputPort ledPort = new OutputPort(Pins.ONBOARD_LED, false);
        // initialize the onboard switch
        InputPort switchPort = new InputPort(Pins.ONBOARD_SW1, false,
                                             Port.ResistorMode.Disabled);

        // do forever...
        while (true)
        {
            // turn the LED on
            //, if the switch is pressed (== false, because switch is inverted)
            ledPort.Write(switchPort.Read() == false);
        }
    }
}

After the output port for the LED is created as in the blink example, the input port is created for the on-board switch. In this case the glitch-filter is turned off, since bouncing of the switch contacts is not an issue here. The pull-up resistor inside the port of the MCU is disabled, since the on-board switch already has a pull-up resistor. More on this later. Important note: since the switch has a pull-up resistor, the value on the port is low/false when the switch is pressed; the value is high/true when it is released.

Using an InputPort, as shown above, the code is required to regularly read the input port to check if the switch has been pressed and act accordingly. An easier way is to use an InterruptPort, as shown below.

public class Program
{
    // initialize the onboard LED
    private static OutputPort ledPort = new OutputPort(Pins.ONBOARD_LED, false);
 
    public static void Main()
    {
        // initialize the onboard switch
        InterruptPort switchPort = new InterruptPort(Pins.ONBOARD_SW1, false,
                                                     Port.ResistorMode.Disabled,
                                                     Port.InterruptMode.InterruptEdgeBoth);
        // add an event-handler for the switch
        switchPort.OnInterrupt += new NativeEventHandler(switchPort_OnInterrupt);
 
        // wait forever...
        Thread.Sleep(Timeout.Infinite);
    }
 
    ///
    /// Event handler for the onboard switch.
    ///
    ///The port for which the event occurs.
    ///The state of the switch.
    ///Time of the event.
    private static void switchPort_OnInterrupt(uint port, uint data, DateTime time)
    {
        // turn the LED on, if the button is pressed (== 0, because switch is inverted)
        ledPort.Write(data == 0);
    }
}

In this version, an InterruptPort is created for the on-board switch, again with the glitch filter and the internal resistor disabled. The interrupt mode is set to both edges, meaning that an event is raised when the value on the port changes from low to high and when it changes from high to low. This allows us to respond when the switch is pressed and when it is released. In both cases, the OnInterrupt event is raised, for which a handler is registered. The handler turns the LED on or off depending on whether the switch is pressed or released.

In this example, the program enters sleep-mode as soon as the initialization of the ports is done. When an event is raised, the program wakes up, the handler is called and goes back to sleep again.

If you want to use your own switch, there are several ways to connect a switch to the Netduino (or a MCU in general), but a common way is shown in the schematic below.

As with the LED, you need to combine the switch with a resistor. Not only to restrict the current, but also to prevent a shortcut when the button is pressed. As with the on-board switch, because a pull-up resistor is used, the value at the port is high when the button is not pressed, and the value is low while the button is pressed.

You can connect the switch & resistor to any of the available ports A0-5 or D0-D13 , as long as you change the first argument of the InputPort or InterruptPort constructor to correspond with the selected port. E.g. when connected to the D0 port, the port should be constructed as follows:

InterruptPort switchPort = new InterruptPort(Pins.GPIO_PIN_D0, false,
                                             Port.ResistorMode.Disabled,
                                             Port.InterruptMode.InterruptEdgeBoth); 

Next: getting started with transistors.

Comments (7) -

  • Paul Laba

    1/23/2012 12:57:53 PM |

    Thanks for these great articles!

    In this article you mention, "The pull-up/-down resistor inside the port of the MCU is disabled, since ..."  It's worth noting that the Netduino and Netduino Plus MCU has programmable pull-up resistors on its output pins, but no pull-down resistors.  If you attempt to use the ResistorMode.PullDown option when creating an InputPort object, your program will throw an exception.

    • Jeroen

      2/5/2012 12:24:00 AM |

      Thanks for the compliment. And you are right about the pull-down, thanks for noticing. Most MCU's I've worked with have both pull-up and -down resistors and the Port.ResistorMode enumeration also has values for both, but I never checked the specs of the MCU on the Netduino.

  • Psysoul

    2/8/2012 8:00:41 PM |

    If you copy the source, pay attention to this line:

    switchPort.OnInterrupt += new NativeEventHandler(switchPort _OnInterrupt);

    There is an unnecessary space:
    switchPort _OnInterrupt should be switchPort_OnInterrupt

    • Jeroen

      2/8/2012 9:49:21 PM |

      Thanks for noticing that. I fixed the source code.

  • D Fitz

    4/1/2012 9:46:24 PM |

    "ledPort.Write(switchPort.Read() == false);"

    Im new to coding and this confused me a little. I assume what happens here is the .Write is only performed if .Read == false ? At which point you write a false to the ledPort ?

    I ask as my board doesnt seem to work with the top example. Its a revision B, I'm using VS2010 express

    • Joel B

      7/5/2013 6:06:17 PM |

      I'm guessing you've figured this out by now... but for anyone else who is wondering:

      You are correct - the ledPort.Write() will write a value of 'true' to the port when the switchPort is false.  Since the switch port seems to work in reverse (meaning that it has a value of false when the button is pressed), this will cause the ledPort.Write to write a value of true out when the button is pressed.

  • Frank

    10/18/2013 9:14:24 PM |

    Thanks for this article, I am just learning hardware and your stuff is very helpful.  I have a question, you wrote: "As with the LED, you need to combine the switch with a resistor. Not only to restrict the current, but also to prevent a shortcut when the button is pressed."  why do you need the resistor and how would this stop a shortcut?  

Pingbacks and trackbacks (4)+

Comments are closed