Netduino Day 7 – RGB LED color formation using Pulse Width Modulation

Pulse Width Modulation (PWM) is a digital method of delivering a varying amount of power to a load, and hence can be used to control the brightness of an LED or speed of a DC motor. Controlling the power, we will make this tutorial colorful using a Red Green Blue (RGB) LED. Each segment (lead) of an RGB-LED will get a PWM signal via RgbLed class allowing us to illuminate the RGB-LED with any color defined by RGB. This class can also generate random colors. Using the RgbLed class, some standard colors can also be sent to a RGB-LED.

RGB-LED illuminating a purple color

Circuit Setup and Theory

To understand PWM, let’s understand the terms that make a modulated pulse width signals. The very important one is Duty Cycle. In lay man terms this duty cycle is a value in percent of ON status compared to OFF status. From the figure below we can see the formula to calculate the duty cycle.

PWM wave and its terminology

Now, let’s co-relate the above to our project. Let’s say we like to produce a “grey” color. We know the RGB value for grey is 128, 128, and 128. This means, if we mix 50% of red (50% of 256 is 128), 50% of green and 50% of blue, we will get a grey color. The value of 50% came from 128/256*100 %. With respect to above figure, if Ton = 50% for Red leg, Ton = 50% of Green leg and Ton = 50% of Blue leg of a RGB LED then we will have a gray color out from a RGB-LED. The calculated value is nothing but the duty cycle of a PWM. In the RgbLed class, we basically adjust the duty cycle to illuminate the RGB-LED with a desired color.

Here is a DutyCycle Excel spreadsheet to understand it little further and it also somewhat followed in the RgbLed class.

The connections are not that difficult. Netduino digital pins, 5, 6, 9 and 10 can be configured as PWM pins, out of which we will configure 5, 6 and 9. The outputs of these pins are fed to the base of a NPN transistor. When the pulse is high, the transistor goes into saturation mode and allows the flow from collector to the emitter where our RGB LED is connected. Since the RGB-LED used in this tutorial is common anode, the anode lead is connected to +5v. The circuit diagram below illustrates the connection.

Circuit diagram: Connecting RGB-LED with Netduino

Picture below shows the circuit setup on a breadboard and its connections to the Netduino.

Connection with Netduino

…and here is actual connection. For the aesthetics of the circuit connection, wires are rearranged.

Breadboard wiring: Connecting RGB-LED with Netduino

C# .NET Program

Using the RgbLed class is really simple so let’s skip it for now and focus into the class itself. The constructor of the class takes four arguments, pin number for red, green and blue, the last argument is optional for commonAnode which is true by default. Based on the circuit diagram it’s not too important whether we set this value to true or false. In this constructor method new instances of PWM class are crated then a ColorTable Hashtable is populated with standard color.

public RgbLed(Cpu.Pin redPwmPin, Cpu.Pin greenPwmPin, Cpu.Pin bluePwmPin, bool commonAnode = true)
{
	RedLED = new PWM(redPwmPin);
	GreenLED = new PWM(greenPwmPin);
	BlueLED = new PWM(bluePwmPin);
	LEDs = new PWM[] { RedLED, GreenLED, BlueLED };
 
	CommonAnode = commonAnode;
	ColorTable = new Hashtable();
	ColorTable.Add(0, new byte[] { 0, 0, 0 });		// Off (~~ Black color)
	ColorTable.Add(1, new byte[] { 0, 100, 100 }); 	// Aqua
	ColorTable.Add(2, new byte[] { 0, 0, 100 });	// Blue
	ColorTable.Add(3, new byte[] { 100, 0, 100 });	// Fuchsia
	ColorTable.Add(4, new byte[] { 50, 50, 50 });	// Gray
	ColorTable.Add(5, new byte[] { 0, 50, 0 });		// Green
	ColorTable.Add(6, new byte[] { 0, 100, 0 });	// Lime
	ColorTable.Add(7, new byte[] { 50, 0, 0 });		// Maroon
	ColorTable.Add(8, new byte[] { 0, 0, 50 });		// Navy
	ColorTable.Add(9, new byte[] { 50, 50, 0 });	// Olive
	ColorTable.Add(10, new byte[] { 50, 0, 50 });	// Purple
	ColorTable.Add(11, new byte[] { 100, 0, 0 });	// Red
	ColorTable.Add(12, new byte[] { 75, 75, 75 });	// Silver
	ColorTable.Add(13, new byte[] { 0, 50, 50 });	// Teal
	ColorTable.Add(14, new byte[] { 100, 100, 100 });// Whilte
	ColorTable.Add(15, new byte[] { 100, 100, 0 });	// Yellow
}

There are three public methods available for setting a color, the TurnIT, Write and RandomColor methods. To have standard color, call TurnIt method and pass the standard color from Color Enum. The Write method takes three byte arguments for red, green and blue color. Finally, RandomColor will calculate random number for the red, green and blue color value.

public void TurnIt(Color color)
{
	if (ColorTable.Contains((int)color))
	{
		colorArray = (byte[])ColorTable[(int)color];
		SetColor();
	}
	else
		throw new Exception("Color not found");
}
public void Write(byte red, byte green, byte blue)
{
	colorArray = new byte[] { (byte)(red * 100 / 255), (byte)(green * 100 / 255), (byte)(blue * 100 / 255) };
	SetColor();
}
public void RandomColor()
{
	Random random = new Random();
	colorArray = new byte[] { (byte)random.Next(100), (byte)random.Next(100), (byte)random.Next(100) };
	SetColor();
}
public override string ToString()
{
	colorString = string.Concat("RGB(", colorArray[0], ", ", colorArray[1], ", ", colorArray[2], ")");
	return colorString;
}

All the public methods internally call the SetColor private method which basically changes the duty cycle of the PWM instances for each read, green and blue pins.

private void SetColor()
{
	if (CommonAnode) colorArray = AdjustPolarityValue(colorArray);
	LEDs[0].SetDutyCycle((uint)colorArray[0]); // Red
	LEDs[1].SetDutyCycle((uint)colorArray[1]); // Green
	LEDs[2].SetDutyCycle((uint)colorArray[2]); // Blue
}
private byte[] AdjustPolarityValue(byte[] colorArray)
{
	return new byte[] { (byte)(100 - colorArray[0]), (byte)(100 - colorArray[1]), (byte)(100 - colorArray[2]) };
}

Here’s the RgbLed Class diagram:

RgbLed Class Diagram

Output

To demonstrate the usage of each three public methods, there are three parts in the video. First it shows the standard color then it shows spectrum of colors by looping through different color loops and finally some random color.

… to show some standard colors

RgbLed led = new RgbLed(Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D5, false   );
 
// Display standard colors
led.TurnIt(RgbLed.Color.Red);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Navy);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Purple);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Green);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Maroon);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Blue);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Fuchsia);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Teal);
WaitAndTurnOff(500, led);
 
led.TurnIt(RgbLed.Color.Yellow);
WaitAndTurnOff(500, led);

… to show different colors

for (int red = 0; red < 255; red += 50)
{
    for (int green = 0; green < 255; green += 50)
    {
        for (int blue = 0; blue < 255; blue += 50)
        {
            led.Write((byte)red, (byte)green, (byte)blue);
            Debug.Print(led.ToString());
 
            WaitAndTurnOff(100, led);
        }
    }
}

… and for generating random colors (looping 20 times),

for (int i = 0; i < 20; i++)
{
    led.RandomColor();
    WaitAndTurnOff(500, led);
}
private static void WaitAndTurnOff(int time, RgbLed led, byte longerOn = 2)
{
    Thread.Sleep(time * longerOn);
    led.TurnIt(RgbLed.Color.Off);
    Thread.Sleep(time);
}

Here’s a quick output video of the above code.

Related Posts

5 comments

Leave a Reply

Your email address will not be published. Required fields are marked *