Playing around with a FEZ Panda II is a lot of fun, especially when it comes to LED lights (and when it’s getting dark outside). Sure, you can make them simply blink, or maybe progam a more complex light-switching pattern, but you always end up with a lot of code to address the LEDs and wait some time between changing their state.
To make it easier to work with an LED, I’ve written a small wrapper class some time ago as described in this posting, but I really wanted to come around having to write a lot of (non-reusable) code just to make some LEDs blink.
My current solution: a very simple, char-based scripting module to control the LEDs. This is how it works:
- You define some simple script like
"R2 r2"
or "GH4 YZ4 a2"
- Based on the
ILights
interface, you create an instance of LEDLights
- An outer loop defines how often the sequence should be executed
- The inner loop iterates over the sequence and passes each char to the mini engine
- The lights start blinking, or whatever you told them to do
Actually, some of these steps could be encapsulated and the pin configuration for the LEDs is currently hard-coded, but for the beginning I wanted to keep the things as easy as possible.
See it in action
How does the script work?
In short: an uppercase letter switches the LED on, a lowercase letter switches it off, and a numerical letter pauses between two actions. I recently got some additional LEDs so I added support for 6 LEDs (please look up the pin configuration in the source code).
- r / R : red LED no. 1
- s / S : red LED no. 2
- y / Y : yellow LED no. 1
- z / Z : yellow LED no. 2
- g / G : green LED no. 1
- h / H : green LED no. 2
- a / A : all LEDs at once
- 1, 2, 3, …, 9 : pause for 500ms, 1000ms, 1500ms, …, 4500ms
All other characters are currently ignored, so you can add spaces to separate the parts of the script which makes it easier to read the script sequence.
Some examples
R2 r2
– the red LEDs is switched on, then waits for 1000ms, then the LED is switched off and the script waits again for 1000ms
R1Y1G4 r1y1g4
– the red, yellow and green LED is switched with short delay, then switched off again
zY2 yZ2
– the two yellow LEDs blink alternately
Tipps, tricks and ideas
When defining a sequence make sure that you add pauses, because otherwise the LEDs fill flicker based on the Netduino’s maximum speed.
It’s easy to forget the pause at the end of the script, which makes the sequence look strange when it gets repeated.
Of course, you can switch off an LED at the beginning of the script, even if it was not switched off before. This is very useful if the sequence has a complex overall pattern and an LED must stay switched on at the end of the script.
Some ideas to extend this project:
- Store more than one sequence in the program and add an IR-receiver or simply a button to switch the sequences
- Read the sequences from an SD card
- Connect the Netduino to the network and add either a webserver to the program to enter the sequence or fetch it from a website (or even from Twitter)
Source Code
For the LED class please look at this posting.
public interface ILights
{
void LightCommand(char c);
}
public class LEDLights : ILights
{
private int baseDelay = 500;
private LED led_R = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di1);
private LED led_Y = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di0);
private LED led_G = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di8);
private LED led_S = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di5);
private LED led_Z = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di3);
private LED led_H = new LED(GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di2);
public void LightCommand(char c)
{
switch (c)
{
case 'r': led_R.Off(); break;
case 'R': led_R.On(); break;
case 'y': led_Y.Off(); break;
case 'Y': led_Y.On(); break;
case 'g': led_G.Off(); break;
case 'G': led_G.On(); break;
case 's': led_S.Off(); break;
case 'S': led_S.On(); break;
case 'z': led_Z.Off(); break;
case 'Z': led_Z.On(); break;
case 'h': led_H.Off(); break;
case 'H': led_H.On(); break;
case 'a': led_R.Off(); led_Y.Off(); led_G.Off(); led_S.Off(); led_Z.Off(); led_H.Off(); break;
case 'A': led_R.On(); led_Y.On(); led_G.On(); led_S.On(); led_Z.On(); led_H.On(); break;
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': Sleep(c); break;
}
}
protected void Sleep(char c)
{
int num = c - '1' + 1;
int delay = num * baseDelay;
Thread.Sleep(delay);
}
}
public class Program
{
public static void Main()
{
string sequence = "R2 r2;
// process sequence
ILights lights = new LEDLights();
// switch off all lights at the beginning
lights.LightCommand('a');
// outer loop
bool looping = true;
while (looping)
{
for (int i = 0; i < sequence.Length; i++)
{
char c = sequence[i];
lights.LightCommand(c);
}
}
}
}