Selecting individual outputs on Shift register. RGB LEDS

Hi All,
I have 4 RGB's set up through a 595 Shift register. The first from QA is connected to red only. The second is connected to QB, QC and QD. This illuminates each colour in sequence as per the delay. The third is connected to QE, QF and QG, same effect as pervious. The fourth, QH is connected red only. What I would like to do with the second LED is have pins QB, QC and QD high at same time and have provision to select colours IE 225, 135, 168. I could then apply this to other LED's as I add more registers.
Thanks,
Davy.

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
//holder for infromation you're going to pass to shifting function
byte data = 0;
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
}
void loop() {
//function that blinks all the LEDs
//gets passed the number of blinks and the pause time
blinkAll_2Bytes(4,2000);
// light each pin one by one using a function A
for (int j = 0; j < 8; j++) {
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, 0);
//red LEDs
lightShiftPinA(8-j);
//green LEDs
lightShiftPinA(j);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
delay(1500);
}
// light each pin one by one using a function A
for (int j = 0; j < 8; j++) {
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, 0);
//red LEDs
lightShiftPinB(j);
//green LEDs
lightShiftPinB(7-j);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
delay(1000);
}
}
//This function uses bitwise math to move the pins up
void lightShiftPinA(int p) {
//defines a local variable
int pin;
//this is line uses a bitwise operator
//shifting a bit left using << is the same
//as multiplying the decimal number by two.
pin = 1<< p;
//move 'em out
shiftOut(dataPin, clockPin, pin);
}
//This function uses that fact that each bit in a byte
//is 2 times greater than the one before it to
//shift the bits higher
void lightShiftPinB(int p) {
//defines a local variable
int pin;
//start with the pin = 1 so that if 0 is passed to this
//function pin 0 will light.
pin = 1;
for (int x = 0; x < p; x++) {
pin = pin * 2;
}
//move 'em out
shiftOut(dataPin, clockPin, pin);
}
// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut&#xFFFD;
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--)  {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
//blinks both registers based on the number of times you want to
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(200);
for (int x = 0; x < n; x++) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);
delay(d);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(d);
}
}

Hi @davyps

This might help:

This can't be done with '595 shift registers. Well, ok, there is a way, but it's very complicated and no-one uses it any more.

Get yourself some "individually addressable" LEDs sometimes called "neopixels". These come in various types such as ws2812 or apa103. With this type of led, and using one of several available libraries, you can control the colour of many LEDs with a single Arduino pin.

Your approach using '595 shift registers has two main limitations. First is that each '595 can only supply a max of 70mA before the chip is damaged. If this is to light 8 LEDs, you need to choose series resistors to limit the current to around 8 mA for each led, so less than half the maximum current the led can take, and so less bright, although often bright enough for many projects. The second limitation is that each output of the '595 is either high or low, giving you only 7 colours on an RGB led (red, green, blue, yellow, cyan, magenta, white). As I said before, there is a way to simulate PWM signals from a '595 but it is very complex, especially when using multiple shift registers. Now that addressable LEDs are cheap and easily available, no-one uses that technique any more, because it is so much easier to use the "new" way.

1 Like

Hi kgray9.
Thanks Mate for taking your time to answer me. Link was very helpful.

Davy.

Hi PaulRB,
Thanks Mate. I am a complete novice with all of this and around three months ago had an idea for a {I thought } simple project which would involve a few LEDs and a couple of batteries . Now I'm up to my neck in shift registers, AND gates, 555 timers, farads coming out of my ears. ;-} What I would like to do would involve 24 LED's. I would like these to come on in groups of three. IE First three light up and go out then delay. Next three light up , go out and so on. I would also like to add secondary effects such theatre chase. Is this something that can be done with 5mm ws2812 LED's?

Thanks,
Davy.

WS2812 LEDs are awesome! No matter how many you have, they only require one Arduino digital pin, and are daisy-chained.

I don't thing WS2812 are made in 5mm. They are SMD LEDs, usually on LED strips.

Each one can be controlled individually, even with only one Arduino pin. So, one at a certain point on the strip can be turned on with the rest off. And it can be turned on any color you want.

You should search WS2812 LED projects on google.

Hi Kato.
Check this out.

Davy.

:face_with_raised_eyebrow:

Does it say WS2812 anywhere on the page? I can't see.

Hi,
To make it clear, @davyps is using RGB LEDs, not WS2812 LEDs.

@davyps can you please post a circuit diagram of your project?
How many 595 do you aim to use?

Thanks.... Tom.. :grinning: :+1: :coffee: :australia:

Hi Kato. Yes it mentions WS2812 in description at bottom of page.

Davy.

It does, yes. Pretty expensive, though!

@davyps have a look for apa106 LEDs (I said apa103 by mistake before). They are compatible with ws2812 and may be cheaper, if you want 5mm format.

We know. We are trying to convince @davyps that ws2812 or similar would make his project hugely simpler.

1 Like

In other words, he was "barking up the wrong tree" and needed to change over now before getting too deep. :+1:

Hi All. Thanks for your input. I’ll tell what I’m trying to achieve. I would like to fit LED’s to a Monopoly Board to hang on a wall.
Features as follows;
• Apply colour LED to each group with corresponding colour. IE Orange, Red, Purple etc. I would like this to switch these on individually for each set. IE Three Orange HIGH then delay. Then three Red HIGH then delay and so on around the board.
• After initial loop I would then like to have all the LED’s illuminate in an array around the board {Theatre Array} changing colours as it goes.
I'd like to use the neopixels as suggested by PaulRB.

Cheers Davy.

PS does anyone know a suitable sketch for this?

It's a myth, among beginners, that any sketch they could possibly want exists, somewhere out there!

You invented something original and unique. It's going to need unique code.

Start with some of the example sketches that come with whichever neopixel library you choose. The Adafruit Neopixel and the FastLed libraries are the two most popular, but there are a few others.

Something to know about neopixels is that they are, or can be, very bright and need a lot of current. Your board will have, I guess, 40 LEDs and these could need up to 2.2A if they were all at maximum brightness white at the same time. That's way too much for the Arduino to supply. So get a 5V power supply with a good current rating. You can power the Arduino from that supply also (connecting to the Arduino's 5V pin). Lower brightness settings and other colours use much less current. For example, full brightness red, blue or green would only require one third as much current.

1 Like

Perhaps "fantasy" might be more apropos?

In no respect does the Arduino "supply" anything in the way of power. Now that would be a myth. :grin:

You supply power to the Arduino, not "from" it. :roll_eyes: Regrettably, for purely historical reasons, the older Arduino designs incorporate a minimal voltage regulator and the documentation implies this is useful for something, which is generally misleading. UNO, Nano, etc, run on 5 V and require a proper 5 V supply.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.