Tuesday, March 29, 2011

What is PWM?

Here is a nice article on what is Pulse Width Modulation: PWM

Basically, with PWM you can simulate a voltage by turning the pin on and off (HIGH and LOW, 5V and 0V) according to a certain frequency.
The amount of time in a cycle that the pin is on and off (duty cycle) determines the resulting voltage between the pin and the component.

On Arduino, PWM values are output with analogWrite() using values between 0 and 255.

P.S.: Here's another great article about PWM that you should read.

Thursday, March 17, 2011

The Curious Case of Pull-Up / Push-Down Resistors

What are pull-up resistors? And push-down resistors?
While trying to find answers to these questions on-line, I could only find sources too advanced for me to understand (I'm still a newbie after all).

But only after coming across some phenomena while playing with my RGB LEDs, did I understand what's the idea.

You see, one might think that if a circuit is open (like a switch) that the potential (voltage) is 0V, but actually because of the static electricity in the environment, that isn't entirely true.
There are components that need so little energy to work, that they might be influenced by that electricity.

What happened to me was that while having a LED connected only to GND, when I touched the other lead, it would light up a little.
When I tried to use a push button in a circuit connecting only one end to an output pin and the other end to an input pin of the Arduino, the Arduino would read strange values either I did or didn't press the push button.

So, these pull-up / push-down resistors are to compensate for this extra energy, forcing the circuit to a stable state.

In the push button case, I had to use a resistor in parallel with the input pin of the Arduino, so that when the button isn't pressed, it would always read 0V (LOW).

The difference between pull-up and push-down is where you use that resistor, either connecting the component to GND or to the source.

I hope to have simplified it enough. What do you think?

RGB LED Part II

After some absence, I finally got some weekend time to play with my electronics.
Now that I have 100 new RGB LEDs, it’s time for some experiments.

I wanted to know how to control the colors emitted by this LEDs so here’s how I did it.

First I searched for a datasheet and found this one on Sparkfun.
According to it, the recommended current is 20mA, and the voltages are 2.0V, 3.2V and 3.2V for red, green and blue. As I wrote on my last post, each color has a different lead, and there is another for Ground (GND). These are common cathode LEDs, as it receives energy on the leads for the colors and all that energy is returned to the circuit on a single lead.

As I source all my projects with the Arduino connected to the laptop (as it already is a regulated power source), I calculated the resistors for a 5V source power.

V=R.I
Red --> (5 – 2.0) / 0.20 = 150 Ohm
Green / Blue --> (5 – 3.2) / 0.20 = 90 Ohm (The closest I have is 100 Ohm)


Connecting all wires, we can see that 3 different tiny LEDs lit up inside our 5mm RGB LED as you can see below.

Also we can see that we can’t count on a mixed color far from the LED, as the three parts point to different directions, although there might be some ways to try to improve that situation.

So the LED lights up. Big deal! Let’s play some more...

The next step is to be able to combine the three colors into making new colors.

First I tried to make a simple program on the Arduino using a (very, very poor) simulated PWM. Basically I would light up only one color at a time and tried different delay() times, to control the ‘quantity of color embedded’ in the final result. That idea came from the LED matrix project, as some kind of multiplexing.
Please, don’t waste your time on something like this.

After some online searching, I saw that the best way is to use ‘real’ PWM, as in using the PWM pins in the Arduino and analogWrite() the value (0-255) for each color. This controls the voltage at the pin, altering the luminosity of the LED. It is best to keep all color lit at the same time (not using delay()).

So now we can programmatically define the color we want to obtain, in theory. Again, with clear LEDs, it is kind of hard to observe a good mix of the light emitted by the three ‘sub-LEDs’.

But isn’t it cooler to be able to mess with those values by hand? So enter the potentiometers (pots).
My first try was to use 3 pots, to control each color. As two of them aren’t ‘breadboard friendly’, you can see below what a mess it is to connect it all.


But then I thought: “What a good opportunity to try to use push buttons.”
So I replaced the 3 potentiometers by 3 push buttons, and altered the Arduino program to cycle through the values for each color.
A simple control to avoid altering the values too much in one push was to have a small delay() after the digitalRead() of each button.




You might notice some resistors connected from each button to GND in parallel with the reader pins of the Arduino.
Those are push-down resistors.

And here is the code:
int R = 9;
int G = 10;
int B = 11;

int vR = 0;
int vG = 0;
int vB = 0;

int T = 200;
int d = 15;

void setup() {
pinMode(R, OUTPUT);
pinMode(G, OUTPUT);
pinMode(B, OUTPUT);
pinMode(7, OUTPUT);

pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);

digitalWrite(7, HIGH);
}

void loop() {
if(digitalRead(2) == HIGH)
{
vR+=d;
if(vR>l)
vR=0;

delay(T);
}

if(digitalRead(3) == HIGH)
{
vG+=d;
if(vG>l)
vG=0;

delay(T);
}

if(digitalRead(4) == HIGH)
{
vB+=d;
if(vB>l)
vB=0;

delay(T);
}

analogWrite(R, vR);
analogWrite(G, vG);
analogWrite(B, vB);
}


So to end it, I wanted to create a demo to cycle to all colors as simply as possible. I found ‘Hue-controllable RGB LED lamp‘ that shows how to cycle through the colors using only a Hue value.
I tried to use the conversion code directly from http://www.easyrgb.com/math.php?MATH=M21#text21, but all the values were quite wrong, so I lazily used the code akgraphics provided on the first post.
As the code was kind of slow because of lots of (unnecessary) math, I reduced it to:

void setup() // run once, when the sketch starts
{
//Serial.begin(9600); // set up Serial library at 9600 bps
}

void h2rgb(float H, int& R, int& G, int& B) {
int var_i;
float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

var_h = H * 6;
if ( var_h == 6 ) var_h = 0; //H must be < 1
var_i = int( var_h ) ; //Or ... var_i = floor( var_h )

//var_1 = V * ( 1 - S );
var_1 = 0;

//var_2 = V * ( 1 - S * ( var_h - var_i ) );
var_2 = ( 1 - ( var_h - var_i ) );

//var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );
var_3 = ( var_h - var_i );

if ( var_i == 0 ) {
var_r = V ;
var_g = var_3 ;
var_b = var_1 ;
}
else if ( var_i == 1 ) {
var_r = var_2 ;
var_g = V ;
var_b = var_1 ;
}
else if ( var_i == 2 ) {
var_r = var_1 ;
var_g = V ;
var_b = var_3 ;
}
else if ( var_i == 3 ) {
var_r = var_1 ;
var_g = var_2 ;
var_b = V ;
}
else if ( var_i == 4 ) {
var_r = var_3 ;
var_g = var_1 ;
var_b = V ;
}
else {
var_r = V ;
var_g = var_1 ;
var_b = var_2 ;
}

R = (1-var_r) * 255; //RGB results = 0 ÷ 255
G = (1-var_g) * 255;
B = (1-var_b) * 255;
}

void loop() // run over and over again
{
for(int val=0;val<1024;val++)
{
//Serial.println(val);
float h = ((float)val)/1024;
int h_int = (int) 360*h;
int r, g, b;
h2rgb(h,r,g,b);

analogWrite(9, r);
analogWrite(10, g);
analogWrite(11, b);

delay(10);
}
}