| By Donald Thompson, Rob Miles | Article Rating: |
|
| May 18, 2007 02:00 PM EDT | Reads: |
12,227 |
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.
Published May 18, 2007 Reads 12,227
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
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
- Kindle 2 vs Nook
- Confessions of a Ulitzer Addict
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Infrastructure-as-a-Service Will Mature in 2010: Microsoft's David Chou
- Windows 7 – Microsoft’s First Step to the Cloud
- Cloud Expo and the End of Tech Recession
- Jill Tummler Singer, Deputy CIO of CIA, Keynotes at GovIT Expo
- Reality Check at the Cloud Computing Expo
- Visual Studio 2010 Is Cloud Friendly
- Fired SCO CEO Fires Back
- Kindle 2 vs Nook
- The Difference Between Web Hosting and Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- Wave on Ulitzer: Confessions of a Google Wave Fanboy
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Best Practices
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Infrastructure-as-a-Service Will Mature in 2010: Microsoft's David Chou
- Eval JavaScript in a Global Context
- Windows 7 – Microsoft’s First Step to the Cloud
- Google Maps and ASP.NET
- Crystal Reports XI & How It Has Changed
- Converting VB6 to VB.NET, Part I
- Creating Controls for.NET Compact Framework in Visual Studio 2005
- Where Are RIA Technologies Headed in 2008?
- How to Write High-Performance C# Code
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Implementing Tab Navigation with ASP.NET 2.0
- i-Technology Photo Exclusive: Bill Gates & Steve Jobs In "Nerds"
- .NET Archives: Getting Reacquainted with the Father of C#
- i-Technology Viewpoint: "SOA Sucks"
- Programmatically Posting Data to ASP .NET Web Applications




























