Saturday, August 13, 2011

Using an External Button & LED with NETMF

In continuing with the BlinkyLEDNETMF for Electronics Noobs series of tutorials, today I’m going to demonstrate how to connect a button/switch to a Panda-II NETMF microprocessor and how to respond when the button is pushed.  Since I need to do something when the button is pushed, I thought this would be an opportune time to also show how to connect an LED to the board and light it up also.

Nearly every NETMF basic tutorial out there starts with a very simple program that uses the on-board button to light up the on-board LED.  That’s just great and is absolutely fantastic the first time you write a NETMF program.  However, as soon as you start working on a real project you soon discover that the on-board button & LED have very limited uses since they can’t be exposed outside of your project enclosure. Then the question comes up – how do I add more buttons?  How do I light up an LED on my project box?  How do I use more than one button or LED?

I’m going to demonstrate how to do this in the most basic situation – the one that will work for 95% of all hobbyist’s needs.

Panda-II Connections

For this project, you’ll need a momentary button, an LED, a breadboard, one 10K ohm resistor, one 100 ohm resistor, and some wires.

Like most things, there are many ways you could wire this up.  This is just one.  What I did was to first plug my button into the breadboard and wire one side of the button to the ground line (very top row on the breadboard).  Then, I connected a 10K ohm resistor (brown, black, orange) to the power (5V) line (2nd row on the breadboard) and used it to connect power to the other side of the button.  The 10K resistor prevents us from creating a “short” which could fry the electronics by allowing too much current to be pulled through the electronics.  Next, we put a 100 ohm resistor (brown, black, brown) on the power side of the button then connect the other side of the resistor to the analog 0 pin on the Panda-II.  This resistor prevents too much current from getting into the board and damaging it.

Panda-II Connections.Fritzing

Now that we have the button wired up, we’ll wire up the LED.  Since only a very small amount of current flows through pins of the Panda-II board we can connect the anode/positive side (longer wire) of the LED to the D5/PWM5 pin and wire the cathode/negative (shorter) side of the LED to our ground line.  That’s it for the wiring.

I do want to note here that if we were wiring the LED to an external power source that we would need to add a current limiting resistor to one side.  To determine the correct size resistor, you can use an LED calculator.

Now that we have the hardware all wired up, it’s time to write some software that responds to our button being pressed by lighting the LED.

In Visual Studio, we create a new console project and add the following references:

FEZPanda_II_GHIElectronics.NETMF.FEZ
Microsoft.SPOT.Hardware
Microsoft.SPOT.Native
mscorlib

In our Program.cs file that is automatically created, replace what is there by default with the following.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
 
namespace ExternalButtonAndLedTutorial
{
    public class Program
    {
        // Tell the CPU we're going to use digital pin #5 to send a signal to the LED.
        static readonly OutputPort _led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di5, false);
 
        public static void Main()
        {
            // Tell the CPU we're going to receive an analog signal from analog pin #0.
            var blueButton = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.An0, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
            
            // The second parameter in the line above ("true") tells the CPU that we want to use the "glitch" filter.
            // If you disable this line then run the program, you will notice in the debug windows that if you are not very fast
            // at pushing the button that the event will actually get fired multiple times.  We only want the event to fire once.  GHI gives
            // us this property that we can set to put a boundary around our first event and prevent redundant events from being fired.
            // Adjust the number of tick
            Cpu.GlitchFilterTime = new TimeSpan(TimeSpan.TicksPerSecond/2);     // 1 Tick = 100 nanoseconds
 
            // When the button is pushed it will signal an interrupt in the CPU which will in turn cause an OnInterrupt event to be thrown.
            // Our BlueButton_OnInterrup function will be called when the interrupt/event is fired.
            blueButton.OnInterrupt += BlueButton_OnInterrupt;
 
            while(true) Thread.Sleep(10);
        }
 
        private static void BlueButton_OnInterrupt(uint port, uint state, DateTime time)
        {
            _led.Write(true);       // Turn on the LED
            Thread.Sleep(1000);     //  wait 1 second...
            _led.Write(false);      // Turn off the LED
 
            Debug.Print("Blue Button Pushed! " + DateTime.Now.ToString());
        }
    }
}



I’ve chosen to document the code as comments in-line, but if anything isn’t clear please leave a comment and I’ll clear it up.


Make sure and set your project properties to deploy to the USBizi device then run it.  If you’ve done everything correct then when you push the button the LED should come on for half a second then turn back off. 


Now that you have one button and one LED working,  get creative!  You can reproduce this many times and as many different ways as your imagination will allow.  To use more buttons or more LEDs, just use any of the other pins and be sure to specify in your code when you define your buttons or LEDs which pin they are connected to and you’ll be fine.  Put these new skilz to work and be sure to post your results in the comments!

4 comments:

Hinnie said...

Why do the Thread.Sleep (1000) in the blue button interrupt routine?

My idea is to interrupt routine code as short as possible and certainly no wait loops into it

Richard said...

The reason I used Thread.Sleep(1000) in this example was purely cosmetic. Since I used a relatively high glitch filter, the interrupt will only fire at most every .5 seconds. Without the Sleep() the LED would come on and off so fast you wouldn't be able to see it. Of course, adjust as necessary for your app. If you're using the LED to show status (on/off) then you probably don't need it at all. However, it's important to understand that the Sleep() isn't a wait loop. When Sleep() is called it releases the CPU to other threads to execute and then resumes when the time is up. So, you will actually see better performance by using Sleep() more often when writing multithreaded NETMF apps.

Kar said...

Hello,

Nic article. I have one question. If you wire LED directly to Panda PIN you don't need a resistor?

Thank you for you help

ianlee74 said...

Thanks. Technically, you probably should but the reality is that the I/O ports don't put out enough current to cause problems for LEDs. So, when doing a quick test like where all the current will come from the port then I don't usually bother. In a more permanent project I would probably either not power the LED throught the port or include an appropriate resistor.

Post a Comment