Welcome!

.NET Authors: Liz McMillan, Yakov Werde, Matthew Pollicove , Kevin Benedict

Related Topics: .NET

.NET: Article

Making the .NET Micro Framework Work for You

The ultimate flashlight - building a device

An Input-Port Object
We now know how to create an object that will connect to an output pin. We can set the state of the object and also read back the state that we have set. Next, we need to create an object to interact with an input pin connected to the switch.

InputPort switchInput =
new InputPort(switchPin, false, Port.ResistorMode.PullUp);

The construction process for input pins is very similar to that for output pins, except that the constructor needs more information. The first parameter identifies the pin to be used; the second specifies whether a glitch filter is to be used on this signal. A glitch filter removes stray pulses from an input signal. Such pulses can be caused by electrical noise and might make our lamp flicker on and off. The third parameter is a value that indicates the mode in which the pin is to be configured. The ResistorMode type is enumerated, which means that it contains particular set of values. In this case, each of the values represents a way in which the input pin can be configured. These values are described here:
ResistorMode.PullUp: A resistor inside the hardware is set to pull the pin up. If nothing is connected to the pin, it will produce the value high. This means that a switch wired between the pin and ground (0 volts) will pull the pin low when it connects the two together, so the port will read false when the switch is closed.
ResistorMode.PullDown: This is the reverse of the PullUp arrangement, in that the pin is pulled low by an internal resistor. Any switch must be connected between the high supply rail and the pin so that when it is closed, the port will read high.
ResistorMode.None: In this configuration, no internal resistors are configured on the input. This means that the external hardware must provide them. If this mode is selected and the pin is left without a pull-up/pull-down resistor, it will generate noisy results because any voltage induced in the pin may be interpreted as signals. Once we have our input port, we can read it by calling the method it provides to get the current status:

if (switchInput.Read())
Debug.Print("input high");

This statement reads the port and prints the message if the input is being held high. We now know enough to create our first complete program.

A Complete Program - Our First Flashlight
Listing 1 is version 1.0 of our computer-controlled flashlight. This program implements a very simple push-button flashlight. When the input is set to high, the program switches the lamp on. When the Main method is called to start the program, it creates the input and output ports and then enters a loop that continuously copies the value of the switch onto the output port.

Figure 3 shows how the flashlight will be wired together. The switch will pull the input pin up to the positive voltage when it is closed. The output pin will produce a high level when the lamp is to be lit. This will cause a current flow through the lamp to ground, causing it to illuminate.

The program includes the code that defines the pins to be used. The Cpu.Pin type is another enumeration that identifies the range of pins available for the selected hardware. This enumeration will provide a range of values that depends on the underlying hardware. The Pin type is found in the Microsoft.SPOT.Hardware namespace. This sets out the features available on the Microsoft SPOT device. If you use a different hardware platform, or wish to connect the lamp or switch to different pins, you will have to set lampPin and switchPin to the appropriate values. The good news is that this is all you will have to do, because the port instances will be connected to the correct devices when they are created.

Inputs with Events
The preceding program will work well, but it is an example of polling. To monitor the state of the button, the switch continuously reads the value from the input port, meaning that the program is running at all times. This uses considerable processor time and may result in the flashlight battery draining before it has even been switched on. A much better way to manage inputs of this kind is to use interrupts. An interrupt is initiated by a change in the state of a port. Special circuitry that generates a signal that causes the processor to pause the currently executing program and run code in an interrupt handler detects this change. Once the interrupt has been dealt with, the program will resume execution.

In conventional embedded programming, the use of interrupts can be quite tricky. The programmer has to create the interrupt handler, bind that to the required interrupt, and then enable the interrupt signal hardware. Using the .NET Micro Framework, things are a lot easier. Rather than create an InputPort instance, you need to create an InterruptPort.

InterruptPort switchInterrupt = new InterruptPort( switchPin, // desired pin
false, // no glitch filter
Port.ResistorMode.PullDown, // pull the input down
Port.InterruptMode.InterruptEdgeBoth); // trigger on both edges

The InterruptPort is created very similarly to our previous input port, except for an additional parameter at the end that selects the signal conditions that will cause the interrupt to be produced. If you think about it, you realize that a signal can do two things: it can move from low to high or from high to low. With some devices, you might be interested only in transitions from low to high - for example, an analogue-to-digital converter may signal completion of a conversion by raising a signal line. If you care only about transitions in one direction, you can create an interrupt port that only detects such transitions.
At the moment, we have only the interrupt port. Next, we have to connect our interrupt handler to the port itself. To understand how to make this work, we must understand delegates.

METHODS AND DELEGATES
We have already seen that an instance of a class can contain data properties and executable methods. The properties hold the information and the methods give the instance its behaviors. To make our interrupt useful, we need a way to connect a particular method in an instance to the event that is triggered when the interrupt occurs. To achieve this, the C# language provides a mechanism called a delegate. A delegate is a reference to a method in an instance of a class. We create a delegate to refer to a method. We can then add this delegate instance to a list maintained by the event so that the delegate knows to call the method when the event occurs.

If you are a C programmer, you will be familiar with the idea of pointers to functions. You will also be accustomed to the experience of your program failing when you call the wrong type of function using a pointer. C# delegates are like pointers to functions, but are vastly more useful because they are type safe. Type safe means that there is no question of incorrectly calling the method referred to by a delegate, because the runtime system will make sure that all calls of the delegate are consistent with its declaration.


More Stories By Donald Thompson

Donald Thompson is responsible for overseeing the end-to-end design and day-to-day management of the developers, software, protocols, and technology strategy fueling the SPOT initiative. During the Internet boom, he built the centralized ad serving system used by all MSN Web properties, including Hotmail, MSNBC, and MSN.com. Prior to joining Microsoft, he developed an automated loan kiosk and decisioning system for Citibank, a cellular billing and management system for Bell South, and wrote AI and 3D graphics algorithms for commercial game companies. Before committing to a life of software, he was a professional child actor working in movies and television.

More Stories By Rob Miles

Rob Miles is a Microsoft Most Valuable Professional. He is a lecturer and Teaching Fellow in the Department of Computer Science at the University of Hull and is presently responsible for delivering the first year programming course and he also lectures on software development and virtual machine architectures. Visit his blog at www.robmiles.com

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.