Sainsmart 8 RGB led module

Hi everybody, It´s the first time I post in this forum (not in a forum) and since I have been using this huge knowledge database, I thought it was time for me to share something of what I´ve learn so far.
First of all, I began with the official arduino starter kit, making almost all practice in the book in a single day, I bought it because a weird idea came to my mind (now that I have researched that idea seems weirder and more crazy), and suddenly I won in a biddin a 6axis servo arm, with servos, a uno clon, adafruit 16servo shield and 2 extras (still working on moving the arm, do not ask about extras)

But stop with that, recently I got a sainsmart 8 RGB led module, I was amazed that its brigther than the usual RGB leds, my first code (that did not work at first time) turn on and off each led, first in 1 coor, then mixing 2 and finally the 3 to give a white light

this is the thing

wiring is as following:

UNO-----Sainsmart
5v ------- VCC (I think its beter to connect to an external supply and connect both 0v together)

2 ------- D1
3 ------- D2
4 ------- D3
5 ------- D4
6 ------- D5
7 ------- D6
8 ------- D7
9 ------- D8

10 ------- R
11 ------- G
12 ------- B (mine had swapped G & B)

For this module to work, you need to set to LOW the output of the led you want to turn ON, and LOW to the color pin you want the led to become, its kinda tricky specially when you´re used to PLCs with sinking inputs and sourcing outputs :wink:

the code is as follows:

int rgb[3];
int led[8];
int i = 0;
int j = 0;
int k = 0;


void setup() {
  Serial.begin(9600);
  k = 2;
  for (i = 0; i < 8; i++) {
    led[i] = k;
    k++;
  }
  for (i = 0; i < 8; i++) {
    pinMode(led[i], OUTPUT);
    digitalWrite(led[i], HIGH);
  }
  k = 10;
  for (i = 0; i < 3; i++) {
    rgb[i] = k;
    k++;
  }
  for (i = 0; i < 3; i++) {
    pinMode(rgb[i], OUTPUT);
    digitalWrite(rgb[i], HIGH);
  }
  k = 0;
}

void loop() {
  //R
  digitalWrite(rgb[0], LOW);
  roulette();
  //G
  digitalWrite(rgb[0], HIGH);
  digitalWrite(rgb[1], LOW);
  roulette();
  //B
  digitalWrite(rgb[1], HIGH);
  digitalWrite(rgb[2], LOW);
  roulette();
  //GB
  digitalWrite(rgb[1], LOW);
  roulette();
  //RG
  digitalWrite(rgb[2], HIGH);
  digitalWrite(rgb[0], LOW);
  roulette();
  //RB
  digitalWrite(rgb[1], HIGH);
  digitalWrite(rgb[2], LOW);
  roulette();
  //RGB
  digitalWrite(rgb[1], LOW);
  roulette();
  //OFF
  for (i = 0; i < 3; i++) {
    digitalWrite(rgb[i], HIGH);
  }
}

void roulette() {
  for (i = 0; i < 8; i++) {
    digitalWrite(led[i], LOW);
    delay(300);
    digitalWrite(led[i], HIGH);
  }
}

speed can be changed with the delay in the void roulette()
I think this code can be used with individual RGB leds, just connecting togheter all R´s, G´s and B´s and switching between the commons, but something tell mes the code will need some adjustments (like swapping the LOWs for HIGHs and viceversa)

Later, I was like, why I dont use PWM to mix colors? and also, lets learn something about multidimensional arrays, so I ended with another code, but I had to use this time a Mega since I wanted to control 8 pwm outputs,

same wiring as previous

and code (just ignore commented lines)

//declaring pins
int rgb[3];
int led[8];
//declaring aux variables
int i = 0;
int j = 0;
int k = 0;
int val;
//declaring da´array
int rgbArray[8][3] = {
  {0, 255, 255},
  {0, 0, 255},
  {255, 0, 255},
  {255, 0, 0},
  {255, 255, 0},
  {0, 255, 0},
  {0, 0, 0},
  {220, 55, 197}
};


void setup() {
  Serial.begin(9600);
  //initializing led pins
  k = 2;
  for (i = 0; i < 8; i++) {
    led[i] = k;
    k++;
  }
  for (i = 0; i < 8; i++) {
    pinMode(led[i], OUTPUT);
    digitalWrite(led[i], HIGH);
  }
  //initializing color pins
  k = 10;
  for (i = 0; i < 3; i++) {
    rgb[i] = k;
    k++;
  }
  for (i = 0; i < 3; i++) {
    pinMode(rgb[i], OUTPUT);
    digitalWrite(rgb[i], HIGH);
  }
  i = 0;
  j = 0;
  k = 0;
}

void loop() {
  writer();
  //randomizer();
}


void writer() {
  analogWrite(led[0], rgbArray[0][i]);
  analogWrite(led[1], rgbArray[1][i]);
  analogWrite(led[2], rgbArray[2][i]);
  analogWrite(led[3], rgbArray[3][i]);
  analogWrite(led[4], rgbArray[4][i]);
  analogWrite(led[5], rgbArray[5][i]);
  analogWrite(led[6], rgbArray[6][i]);
  analogWrite(led[7], rgbArray[7][i]);
  switcher();
  delay(5);
  i++;
  if (i == 3) {
    i = 0;
  }
}


void switcher() {
  if (i == 0) {
    digitalWrite(rgb[1], HIGH);
    digitalWrite(rgb[2], HIGH);
    digitalWrite(rgb[0], LOW);
  }
  if (i == 1) {
    digitalWrite(rgb[0], HIGH);
    digitalWrite(rgb[2], HIGH);
    digitalWrite(rgb[1], LOW);
  }
  if (i == 2) {
    digitalWrite(rgb[0], HIGH);
    digitalWrite(rgb[1], HIGH);
    digitalWrite(rgb[2], LOW);
  }
}


void randomizer() {
  for (int i = 0; i < 8; i++) {
  for (int j = 0; j < 3; j++) {
    rgbArray[i][j] = int(random(255));
  }
}
}

/*void printer() {
  Serial.print("I=");
  Serial.println(i);
  Serial.print("J=");
  Serial.println(j);
  Serial.print("val=");
  Serial.println(val);
}*/

firs I wanted to make a nested For loop to switch the analogWrite, something like

for(i=0;i<3;i++){
  for(j=0;j<8;j++){
val=Array[i][j];
analogWrite(pin[i],val);
}
}

but not only got confused my self, the leds would blink a lot, and a stable color couldnt be seen, so I used that less elaborated code, I erased the 4 (just rewrited) non working sketches, If I find the right time, I will try to rewrite them, since the lights seemed nice for a disco night 8)

Hope you get the chance to test it sometime, I need to sleep right now, some PNP PLCs awaits me in the morning

Greetings from Mexico

The boards of this type (there are a few variants) represent an arguably bizarre design. They provide a buffer transistor to each of 8 RGB LEDs, but no buffering on the colour commons. This is evidently in the expectation that the RGB LEDs will be selected one at a time, and the three colours will be driven for that particular LED during this multiplexing phase.

The problem with this is that it sets a one of eight multiplex cycle. If instead, buffer transistors were provided on the colours, then a one of three multiplex could be used for more brightness.

This would however require individual colour limiting resistors for each LED, a total of 24, in addition to those for the buffer transistor bases. It would also require either buffer transistors for each RGB LED as well, or the microcontroller able to source current to all three colours on each LED. If instead, the current for each colour is reduced to a third, then the effective multiplex is now one in nine, so I suppose the present design stands. It cannot be driven as a "one of three" multiplex as there are common current limiting resistors (330 Ohm) for the three colours.

Mind you, if we guess the LED voltage drop as 2.5V, then the colour current for the 330 Ohm resistors is about 6 mA and an Arduino output could easily drive three colours at once so the eight buffer transistors are arguably unnecessary and in fact the alternate design with more resistors (27) and fewer transistors (3) would in fact, be preferable.

The SainSmart board apparently feels the need to use 5k1 base-emitter pull-up resistors to turn the driver transistors off. The other boards do not but have a more conservative base drive (1k). Clearly if you are switching the output pins alternately HIGH and LOW, the extra base resistor is superfluous.

havent analized the circuit so deep but I indeed noticed that the amount of resistors and transistors is a bit weird, with the second code I got a somewhat bright color using a small delay, if I remove the delay all colors seems to fade into white, as long as human eye can make the trick, I think sainsmart wont improve the module, but a simple 5mp camera (or less) cant be fooled