RGB LED with VB 2008 and transistors

Hello,

I have a problem with color mixing a RGB LED with the serial port. I can’t insert the R, G and B directly into the 9, 10 and 11 pins, because there’s only 1 plus on the LED and 3 min. So what I tried is to hook up 3 transistors so I would still be able to control the values of the brightness of each LED.

Visual Basic 2008 sends codes via the serial port to the arduino. If the trackbar for the red LED is being scrolled, and the value is 25, then it will send this:
<
25

If the green trackbar is being scrolled, it adds 1000 to the value, so the Arduino knows that the green LED needs to be activated:

<
1025

It adds 2000 for the blue LED:

<
2025

This is my arduino code:

int val = 0;
int select = 1;
int baseR = 9;
int baseG = 10;
int baseB = 11;
int led = 13;

void setup()
{
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  pinMode(baseR, OUTPUT);
  pinMode(baseG, OUTPUT);
  pinMode(baseB, OUTPUT);
}

void loop()
{
  digitalWrite(led, HIGH);
  if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      val = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            if(aChar <= 1000)
            {
              select = 1;
            val = val * 10 + aChar - '0';
            }
            else if(aChar >= 999 && aChar <= 2000)
            {
              select = 2;
              val = val * 10 + aChar - '0';
              val = val - 1000;
            }
            else
            {
              select = 3;
              val = val * 10 + aChar - '0';
              val = val - 2000;
            }
      }
      while(aChar != '>');
        if(select == 1)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseR, val);
      val = 0;
        }
        else if(select == 2)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseG, val);
      val = 0;
        }
        else if(select == 3)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseB, val);
      val = 0;
        }
    }
  }
}

The ‘baseR’, ‘baseG’ and ‘baseB’ are the bases of the transistors. It sends values via the PWM pins.

I would really appreciate it if someone would help me out.

Thanks in advance,
Deco Aoreste

directly into the 9, 10 and 11 pins, because there's only 1 plus on the LED and 3 min.

So you connect the plus on the LED to 5V, the - on each of the three colours to a resistor and then to the pins of the arduino.

Then sending 0 will be full on and 255 full off.

You don't say what is wrong with your code I assume it won't work but what does it do?

That's what I did, except for connecting the plus to the 5V on the Arduino. I inserted the plus on pin 13, because pin 13 has a built-in resistor. And as you can see in the code, it turns on the LED at the begin of the loop:

digitalWrite(led, HIGH)

And what it does; nothing. There's a really tiny red glow, which is hard to see.

I inserted the plus on pin 13, because pin 13 has a built-in resistor.

No it hasn't.

I inserted it on the 5V pin. I’ve managed to fade a normal LED with a transistor, and a more simple version of this code, so I know that it’s possible to fade a LED with a transistor.

Any suggestions?

Edit:
I used this code to fade a normal LED with a transistor:

int val = 0;
int base = 9;
int led = 13;

void setup()
{
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  pinMode(base, OUTPUT);
}

void loop()
{
  digitalWrite(led, HIGH);
  if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      val = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
          val = val * 10 + aChar - '0';
      }
      while(aChar != '>');
      analogWrite(base, val);
      val = 0;
    }
  }
}

The VB 2008 application sends data like this:
<
25

Why are you doing things the hard way, Make it simple, but not too simple. Those LEDs are COMMON ANODE, and are meant to be wired like grumpy_mike said, if you are uncomfortable of giving reverse values to the function loop then do it like:

analogWrite(baseR, 255-val);

This gives you the "right" colour.

David

It does light up now, and I can modify the red glow. I cannot turn of the blue and green LEDs, they are lit up fully.

So how have you wired them up? You need a separate resistor for each of the three colours, wired up to a septate output pin.

You did change all the code? not just analogWrite(baseR, 255-val); ? the others must be changed too: analogWrite(baseR, 255-val); // inveritng the reversed LED by deducting value from 255, wich is OFF. analogWrite(baseG, 255-val); analogWrite(baseB, 255-val);

resistors on all katode pins.

Yes, I did that. How I wired it: the longest pin(+) is connected to the 5V pin. The 3 remaining pins (R, G and B) Are connected through a resistor to the pins 9, 10 and 11. R to 9, G to 10 and B to 11.

I can fade the red LED in the RGB LED, but if I scroll the trackbar for green or for blue, the red LED is lit up on his maximum. The green and blue LED are always on their maximum; I cannot control the brightness.

This is a screenshot of my application:

And this is my Arduino code:

int val = 0;
int select = 1;
int baseR = 9;
int baseG = 10;
int baseB = 11;

void setup()
{
  Serial.begin(9600);
  pinMode(baseR, OUTPUT);
  pinMode(baseG, OUTPUT);
  pinMode(baseB, OUTPUT);
}

void loop()
{
  if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      val = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            if(aChar <= 1000)
            {
              select = 1;
            val = val * 10 + aChar - '0';
            }
            else if(aChar >= 999 && aChar <= 2000)
            {
              select = 2;
              val = val - 1000;
              val = val * 10 + aChar - '0';
            }
            else
            {
              select = 3;
              val = val - 2000;
              val = val * 10 + aChar - '0';
            }
      }
      while(aChar != '>');
        if(select = 1)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseR, 255 - val);
      val = 0;
        }
        else if(select = 2)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseG, 255 - val);
      val = 0;
        }
        else if(select = 3)
        {
        val = constrain(val, 0, 255);
      analogWrite(baseB, 255 - val);
      val = 0;
        }
    }
  }
}

How do you diffrentiate between R G and B?
you have only 1 value “val” to pwm 3 pins, not a good idea
Can you test the while loop, is it getting what you expect from the VB
try serialmonitor it
try making 3 variables valR, valG, valB and setting them from the while loop

What the hell is happening here:

You set val = 0 in the beginning before while loop
then you minus it by 1000 if it is Blue then val = -1000
then you muliply it by 10 now the val = -10000

if green, you minus the val by 2000 then val is -2000
multiply by 10 now your val is -20000

What kind of code is VB sending?
can’t you just send your ‘<’ followed by ‘r’ if it is red ‘b’ if it is blue ‘g’ if it is green and then the value, much simpler
then you check for < character, wich led character and finally the value, best to use seperate int variables for each of the LEDs

David

[edit]You can also use modulo to get the value from the aChar
http://arduino.cc/en/Reference/Modulo[/edit]

You have :-
aChar = Serial.read();

and then go on to say:-
if(aChar <= 1000)

The read reads only a single byte so it can only have a value from 0 to 255, therefore none of your other conditions can possibly be set. I also can’t see where val is set initially.

I think you are misunderstanding how serial communications work at the arduino end. It only reads one byte at a time. If you are receiving ASCII characters or any other form of encoded multi byte data you have to build it up on the arduino side to make a proper variable.

If the green trackbar is scrolled, then it will send the value + 1000, so the arduino knows that the green LED has to be modified.

I changed my VB code and Arduino code. VB sends ‘<r’ if the red trackbar is scrolled, ‘<g’ for the green trackbar and ‘<b’ for the blue one. I also modified my Arduino code:

int valR = 0;
int valG = 0;
int valB = 0;
int select = 1;
int ledR = 9;
int ledG = 10;
int ledB = 11;

void setup()
{
  Serial.begin(9600);
  pinMode(ledR, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop()
{
  if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<r')
    {
      valR = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valR = valR * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valR = constrain(valR, 0, 255);
      analogWrite(ledR, 255 - valR);
    }
    else if(aChar == '<g')
    {
      valG = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valG = valG * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valG = constrain(valG, 0, 255);
      analogWrite(ledG, 255 - valG);
    }
    else if(aChar == '<b')
    {
      valB = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valB = valB * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valB = constrain(valB, 0, 255);
      analogWrite(ledB, 255 - valB);
    }
    }
  }

It still doesn’t work; all the LEDs light up on their maximum, I can’t fade them with my VB application.

@Grumpy_Mike: You’re right that I might misunderstand the serial communication. I just started with programming my Arduino. Do you have any tutorials that explain it well?

You can’t say:-
if(aChar == ‘<r’)

aChar CAN ONLY BE ONE BYTE

My VB application now sends this, if the red trackbar is scrolled to 125:
<
r
125

My Arduino code:

int valR = 0;
int valG = 0;
int valB = 0;
int select = 1;
int ledR = 9;
int ledG = 10;
int ledB = 11;

void setup()
{
  Serial.begin(9600);
  pinMode(ledR, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop()
{
  if(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      char SelectColor = Serial.read();
      if(SelectColor = 'r')
      {
      valR = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valR = valR * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valR = constrain(valR, 0, 255);
      analogWrite(ledR, 255 - valR);
    }
    else if(SelectColor = 'g')
    {
      valG = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valG = valG * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valG = constrain(valG, 0, 255);
      analogWrite(ledG, 255 - valG);
    }
    else if(SelectColor == 'b')
    {
      valB = 0;
      do{
          while(Serial.available() <1)
            ;
        aChar = Serial.read();
        if(aChar >= '0' && aChar <= '9')
            {
            valB = valB * 10 + aChar - '0';
      }
}
      while(aChar != '>');
        valB = constrain(valB, 0, 255);
      analogWrite(ledB, 255 - valB);
    }
    }
  }
}

I can now only fade the red LED.

while(aChar != '>');

will do nothing because of the ; at the end.

You perform the second read:- char SelectColor = Serial.read();

Without seeing if there is anything in the buffer.

You seem to have 'do' statements without any matching while the while should be outside the curly braces of the do:- http://www.arduino.cc/en/Reference/DoWhile

I noticed in your code

void loop()
{
if(Serial.available() > 0)
{
char aChar = Serial.read();
if(aChar == ‘<’)
{
char SelectColor = Serial.read();
if(SelectColor = ‘r’)

it needs to read if(SelectColor == ‘r’) otherwise it will always set SelectColor = ‘r’ every time it hits this point. this would make you only able to control the Red value.

you would also have to make sure it is “==” for each of your other If statements.

-Will