Controlling Common Anode RGB Led

Greetings;

This is likely a clone of scattered information around this forum and the web.
Yet; because simplicity has its own complexity; I wanted to share with you all my own achievement.

Note Before Start:
This project is currently on development and due to finding myself learning on how to do things properly; please do take into consideration the comments bellow.
For now; this tutorial serves ONLY for understanding purposes; and as you will read bellow some things need improvement.
Please do NOT attempt this project; or adapt it you're far more experienced.
As said bellow: "the configuration can damage your module and has inefficient code".

About
In the following tutorial you will understand how to wire the Common Anode RGB Led properly and so code the Arduino to receive the Values (Since I'm still learning how to do better; these values will be of String type - However using byte is recommended).

Requirements

1 x Micro Controller (Here Arduino Nano)
4 x Dupont Cables (Yellow, Red, Green and Blue)
1 x RGB Led (Common Anode)
3 x 1K Ohm Resistors
1 x PCB (you can use breadboard for prototyping)

Wiring

Note(s):

Please take into consideration that I have used a YELLOW wire to Power the Led instead of the traditioanl RED.
This to make it simple to read wich wires are connecting to the colors.

Power: Yellow Wire
Red: Red Wire
Green: Green Wire
Blue: Blue Wire


image free host

Code

/* RGB Led Power Pin */
#define rgbPwr 2

/* R, G, B Pins*/
int rPin = 9;
int gPin = 10;
int bPin = 11;

/* Serial Listen */
String inData;                  // The data received conerted (cast) To String
bool hasNewData = false;        // Serial Has New Data (True or False)
char SerialReceivedChars[32];   // The char array that will contain received chars.
char endMarker = '\n';          // End Marker. A way to know that no more chars will be comming for the current operation.
int maxNrChars = 32;            // Max. Number of chars permitted.

/* Setup for your RGB Led */
void InitRGB() 
{
  pinMode(rgbPwr, HIGH);    // Power
  pinMode(rPin, OUTPUT);    // Red Pin
  pinMode(gPin, OUTPUT);    // Green Pin
  pinMode(bPin, OUTPUT);    // Blue Pin
}

// This method will be Reading Serial for Incomming Data (under "loop" method)
void SerialListen()
{
    static byte ndx = 0; /* Data Received in Bytes */
    char receivedChar;

    while (Serial.available() > 0 && hasNewData == false)
    {
        receivedChar = Serial.read();

        /* While Received Data (Payload) hasn't Received the Terminator Char */
        /* Add Received Chars to rc Variable */
        if (receivedChar != endMarker)
        {
            SerialReceivedChars[ndx] = receivedChar;
            ndx++;

            /* Limit Received Chars to the Maximum Number of Chars. */
            /* Whenever a new Char is Received While Maximum Number of Chars is Already Occupied: Replace Last Char with New Char. */
            if (ndx >= maxNrChars) { ndx = maxNrChars - 1; }
        }

        /* else: Terminator Char was Received. */
        /* Terminate Number of Defined Characters Variable. */
        /* [Note]: In C/C++ a string is an array of char terminated with a NULL byte ('\0'); */
        /* Set newData Variable to True. Meaning: New Data Has Been Received. */
        else
        {
            SerialReceivedChars[ndx] = '\0'; /* Terminate the string. Default: '\0'*/
            ndx = 0;
            hasNewData = true;
        }

        if (hasNewData)
        {
            inData = String((char*)SerialReceivedChars);
            
            SetColor(inData);
            hasNewData = false;
            inData = "";
        }
    }
}

/* Set the Color from Serial Input Data */
void SetColor(String inData)
{
  // Toggle the Power pin to Maximum Value (Lower Value will Dim the Led)
  analogWrite(rgbPwr, 255);

  Serial.println(inData);

  // Split a String : Start Position; End Position
  String red = inData.substring(3, 6);       /* Get the 3rd to 6th Characters */
  String green = inData.substring(6, 9);     /* Get the 6th to 9th Characters */
  String blue = inData.substring(9, 12);     /* Get the 9th to 12th Characters */

  // Convert String values to Integers
  int r = atoi(red.c_str());
  int g = atoi(green.c_str());
  int b = atoi(blue.c_str());

  // If RGB Led is Common Anode; use Conversion bellow.
  // The Common anode Values are Inverted.
  // Therefore 0 Represents 255 and 255 represents 0.
  int rVal = 255 - r;
  int gVal = 255 - g;
  int bVal = 255 - b;

  // Set the Led Values (Set Color)
  analogWrite(rPin, rVal);
  analogWrite(gPin, gVal);
  analogWrite(bPin, bVal);
}

void setup() { Serial.begin(115200); InitRGB(); }
void loop() { SerialListen(); }

Finally:

Upload your code; open your Serial Monitor and type the command like:

RGB255000000 (to Toggle Red)
RGB000255000 (to Toggle Green)
RGB000000255 (to Toggle Blue)

Why use Strings ?
Why use a mixture of named variables and #define ?
Why are there many variables, pin numbers for example, declared as int when their value will not exceed 255 for which a byte would suffice ?
Why are values that will not change, such as pin numbers, not declared as const ?

NEWBIE WARNING

I’m worried that you’re using pin ‘rgbpower’ to drive the high side of all three LEDs.
A couple of cardinal rules broken there...
Powering a ‘device’ from a logic pin is ill-advised, and you’ll be exceeding the rating of that pin in some circumstances.

Your code also mentions dimming the LEDs with the rgbpower pin..?
A) That’s possible, but ‘why’ if you use PWM on the separate LED pins ?
B) You don’t use that in your code.

As Bob mentioned, lose the String functions.

As a tutorial, this needs a lot of work, currently, it is long-winded, inefficient code, and has real potential to destroy the cpu chip.

Sorry, back to the drawing board.

Greetings;

Sorry for the delay; thank you all for your feedback.

Will try to update the tutorial ASAP as suggested.
While I'm working on it; I placed a note on my Post so users take your suggestions into consideration first.

Note: I'm learning C++ and Electronics on the go; therefore I apologize for the mess.

  • The rgbPowerPin is intended for Dimming.
  • The String functions; are used so I can control Arduino with my Computer (via Serial Communication).
    I'm actually working on that. Definitely have to change that to Byte values.
  • #define and variables: Honestly I rather simply use #define; but I don't really understand yet why so many times I cant access the definitions; and I do can access the variables.
    Thus using what works for me.
  • constants: You're right.

I'm actually working on that. Definitely have to change that from string to byte.

Do you mean you are going to move from Strings to strings ?