The output from the flashlight will be a lamp of some kind that will be controlled by a pin configured as an output on the target hardware. The connection to be used on a genuine device would be chosen when the circuit that controls the lamp is designed.
Most pins on a device are general purpose in that whether they are input or output is controlled by software. To control a simple device like the lamp on our flashlight, we can use an instance of the OutputPort class, which is provided as part of the .NET Micro Framework. It is an object whose job is to manage an output connection to an external device. The code to create the object is as follows:
OutputPort lampOutput = new OutputPort(lampPin, false);
The new keyword causes the creation of an object. An object is an instance of a class. The constructor (the code in a class that sets up the object) needs to know the physical pin the output is to be connected to. This is analogous to telling a file stream which file to use. In this case, it is a constant identifying the output pin. (We will see how this is done in detail later.) The constructor for the OutputPort also needs the initial state for the output port when it is created. The second parameter provides this information. In the preceding code, the pin will initially be set to low, which is specified by the Boolean value false. In other words, when the flashlight starts up, the lamp is not lit.
It is important to understand that in C#, objects are managed by reference. Figure 4-2 shows what happens when the OutputPort instance is created. Note that we do not create an object with the identifier lampOutput; instead we create a reference with that identifier, which is made to refer to a particular object.
Figure 4-2: An object and a reference.
We can call methods on our reference to give the instance commands. For example, to set the port output to high, we could use the following code:
The Write method accepts a single Boolean parameter that can either be true or false.
Remember that, because of the way the lamp is physically connected to the circuit, setting the output to high (true) might not cause the lamp to illuminate. A hardware designer may use buffers that will have the effect of inverting the sense of the signal, meaning that to light the lamp you might have to set the output to low.
The OutputPort class also contains a method called Read that returns a Boolean value indicating the state of the port.
if (lampOutput.Read()) Debug.Print("output high");
This code also shows the use of the reference Debug. This refers to an instance of an object that implements the debug output stream. This object contains a Print method that can be passed a string to be displayed on the debug channel, which is normally the output window in Microsoft Visual Studio 2005. Precisely how this works, and where the output appears, is not the concern of the user of the Debug object. The output could be sent to a file, transmitted down a serial port, or displayed on a screen.
This shows a very useful feature of object-based design: Our program can use an object that supports a particular set of methods without knowing the details of precisely what it does.