Passing data to three 74HC595s

Hello gurus/-ettes,

I am satisfying my appetite for tinkering with a multicolor LED control system.

I have three potentiometers mapped to r, g and b, so I can get any color out of the LED.

To add the somersault points, I included three four digit, 7 segment LEDs. Each will show one of the rgb component values of the LED. I got it to work with one such display, no problem, but adding the other two has me baffled.

As I have thought of it, I have an array of 12 elements. This reads something like 025500000000 when the LED is all red, to 025502550255 for all white, etc. My idea was that if I pass that array to the shift registers, it would be read and displayed correctly.

The structure that does it for one value is

void makeArray(){
  redDig1 = int(valR/100);
  redDig2 = int((valR/10) % 10);
  redDig3 = int(valR-100*redDig1-10*redDig2);  
  greenDig1 = int(valG/100);
  greenDig2 = int((valG/10) % 10);
  greenDig3 = int(valG-100*greenDig1-10*greenDig2);  
  blueDig1 = int(valB/100);
  blueDig2 = int((valB/10) % 10);
  blueDig3 = int(valB-100*blueDig1-10*blueDig2);
  myArray[0] = 0xc0; //first digit of first LED unit is 0
  myArray[1] = num[redDig1];      
  myArray[2] = num[redDig2];      
  myArray[3] = num[redDig3];      
  myArray[4] = 0xc0; //first digit of second LED unit is 0
  myArray[5] = num[greenDig1];      
  myArray[6] = num[greenDig2];      
  myArray[7] = num[greenDig3];        

void showArray(){
  for (int i = 0; i < 4; i++) {
    // Select a single 7-segment display
    // Send data to 74HC595
    // Clear the display content

void chooseCommon(byte com) {
  // Close all single 7-segment display
  for (int i = 0; i < 4; i++) {
    digitalWrite(comPin[i], LOW);
  // Open the selected single 7-segment display
  digitalWrite(comPin[com], HIGH);

void writeData(int value) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Send serial data to 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, value);
  // Make latchPin output high level, then 74HC595 will update the data to parallel output
  digitalWrite(latchPin, HIGH);

But when I try to expand to the second shift register by upping the loop to eight elements (the i loop), it doesn’t do as I expected, so I must be doing something horribly wrong.

So, in essence my question boils down to how to pass three different values to three daisy chained shift registers? I am attaching the full file here so those interested can have a peek.

I am sorry if this is irritatingly low-level for you but it’s keeping me awake at night almost as much as Boris Johnson is.

Arduino_Ultimate_RGB_LED.ino (4.51 KB)

Can you please post the code that doesn’t work, because that is where your problem is and we can’t help if we can’t see what you don’t understand.

It's the attached ino file.

Sorry for the delay but I can only read attached files on my laptop not my iPad. Now I have looked at your code it is quite clear what you are doing wrong.

It is your write data function, you must make the latch LOW, then shift out data to all of your shift registers before making the latch HIGH.

It also seems that the code is outputting to four shift registers but your question seems to say you only have three, or does that mean three "more".

it's keeping me awake at night almost as much as Boris Johnson is.

Why is Bo-Jo keeping you awake? Surely it can't be his approach to Brexit because the two of you seem to have a common strategy:

My goal is to get things happening no matter what way it goes through.