help me improve my code for controlling 64 leds with 2 74HC595N ic's

Hello everyone, today i am doing a project controlling 64 leds with 2 74HC595Ns and a ardunio mega 2560. I need help on improving the code so that I can light an individual LED in the 64 bit array and I can control which one to light up. I am fairly knowledged with ardunio code so you can share any knowledge you have, I greatly appreciate it. Im using multi-colored LEDs (R G B W R G B W x eight ) red,green,blue and white. I soldered it my self and hooked up everything but Im having alot of trouble lighting up an LED i want. I tried to use this code but it lights up all over the place and the reds seem to be only lighting up, Getting the blue or white to light up is extremely tricky, but they do light up but I had no idea how it worked. Thank you for your time and help The picture below is extremely similar to the set up I am using except that the HIGH and LOW data pins are reversed. The leds I used are 3mm Leds.
//


//
This is the code
//

int latchPin = 6;  //Pin connected to groundd
int clockPin = 5;  //Pin connected to  ground
int dataPin = 7;   //Pin connected to ground

int latchPin2 = 3;  //Pin connected to vcc
int clockPin2 = 2;  //Pin connected to vcc
int dataPin2 = 4;   //Pin connected to vcc

void setup() {
  //output to control shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
}

void loop() {




  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 132);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);



  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 145);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);

  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 2);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 253);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);
}

Thank you again for your help.

Wrong approach.

Use a MAX7219.

Just buy one of these modules:

If you don't want to use the LED matrix provided, just mount pins instead of the sockets and connect it to your own LEDs.

Beats mucking around with 74HC595s and getting a poor result since they are not "up to" the job. And a Mega2560 is way overkill!

Also read the instructions and go back and post your code properly.

I used that for one of my previous projects, this is also for a class, so I would need to use at least 2 multi-plexing chips, I decided to use the 595 chip because it was kind of similar to my previous project

OK, so it is purely for demonstration and not for any serious use so performance does not matter. That answers my objections to your choice of hardware. The resistors should then be 1k.

Please do fix up the code mark-up in that first post here. It is a bit if a nuisance to deal with otherwise.

The connection of the incorrectly labelled "Brightness control" to Vcc - 5 V - is a mistake (but not your mistake - it was just a blunder that has been copied mindlessly from one project design to another for a long time) and should be removed. :astonished:

It is somewhat easier to control the 74HC595s if they are chained - three pins controls both.

If no-one else does, I will look at your code later. :grinning:

Paul__B:
OK, so it is purely for demonstration and not for any serious use so performance does not matter. That answers my objections to your choice of hardware. The resistors should then be 1k.

Please do fix up the code mark-up in that first post here. It is a bit if a nuisance to deal with otherwise.

The connection of the incorrectly labelled "Brightness control" to Vcc - 5 V - is a mistake (but not your mistake - it was just a blunder that has been copied mindlessly from one project design to another for a long time) and should be removed. :astonished:

It is somewhat easier to control the 74HC595s if they are chained - three pins controls both.

If no-one else does, I will look at your code later. :grinning:

Sorry about that will read up on how to post the code's correctly. Im actually at the moment not using any other sensors until I can control the LEDs purely with code, from there everything will connect and be much easier. The bottom half of the code (loop portion) is whats really confusing me. Wouldn't 1k ohms make the Leds too dark? Thank you for your help.

aimmet:
Sorry about that will read up on how to post the code’s correctly. Im actually at the moment not using any other sensors until I can control the LEDs purely with code, from there everything will connect and be much easier. The bottom half of the code (loop portion) is whats really confusing me. Wouldn’t 1k ohms make the Leds too dark? Thank you for your help.

OK, just go back and modify your original post using the “More → Modify” option below the right hand corner of your post to mark up your code as such using the “</>” icon in the posting window.

Just highlight each section of code (or output) from the IDE and click the icon. In fact, the IDE has a “copy for forum” link to put these markings on for you so you then just paste it here in a posting window.

Just as a reminder for anyone - do not attach it as a “.ino” file. People can usually see the mistakes directly and do not want to have to actually load it in their own IDE. And that would also assume they are using a PC and have the IDE running on that PC.

But don’t forget to use the “Auto-Format” (Ctrl-T) option first to make it easy to read. If you do not post it as “code”, it can be quite garbled and is always more difficult to read.


aimmet:
Wouldn’t 1k ohms make the LEDs too dark?

As I said, 74HC595s are not intended for this job. You are using one 74HC595 output to drive each of 8 segments/ rows at a time using another 74HC595 output which you hope will carry all eight of those in the digit/ column at once. Well, I am at least presuming you want to light (or appear to light) a number if not most or all of the LEDs at once.

So your cathode driver is rated at 25 mA (and you do not expect it to pull the output down to ground at that current, at 25 mA it will likely pull down to only 1 V) which means if it is possible all eight LED anodes will be driven at once their current will be limited to 3 mA each. LED drop 3 V (for white), ignoring voltage drop in the high side driver (one eighth of a Volt), 5 V supply leaves 1 V across the resistor, so a 330 Ohm resistor would in fact set the current at 3 V however a white LED with a 1.5 V drop would correspondingly require a 680 Ohm resistor. You will find that the brightness varies depending on how many LEDs in the column are lit at once.

I presume that you are not going to make all LEDs on each row the same colour, so 1k resistors for all would be the easiest. But if you are using current efficient LEDs rather than the 30-year-old ones languishing in my parts boxes, they will be quite adequate - for your indoor demonstrations. As I said, for a serious application, it is a different ball game and you would not be doing it this way.

Ok Well i dont have any other chips available, would using a 1k ohm resisitor fix this issue or using a separate power source for the LEDs? I pretty much have everything built, I dont have to light all leds at once, just turning at least 8 at a time would be nice, I just need a working demo to demanstrate that i can control each led with the circuit that I built

Thank you for fixing the presentation of the code.

Again, apologies, I have not addressed your original problem at this point - may find the time to do so later.

The matter of the resistors - 1k recommended - is just so that you do not overload your 74HC595s along the way. There are display modules sold on eBay which use two 74HC595s and have no resistors. That design is complete rubbish but whether they fail or not - or whether anyone cares because you surely would not use those modules in a serious design - is perhaps moot.

I see, but my time is running out so im just trying to see if i can just get at least one of each column individually too light up, I wont try to light all 64 at once. Its okay when you do find the time I will appreciate it.

OK, here we go. :grinning:

int latchPin = 6;  //Pin connected to groundd // This latch appears to be connected to anodes - rows with resistors
int clockPin = 5;  //Pin connected to  ground // your diagram shows pin 7 as the clock
int dataPin = 7;   //Pin connected to ground // and pin 5 as the data

int latchPin2 = 3;  //Pin connected to vcc // This latch appears to be connected to cathodes - columns
int clockPin2 = 2;  //Pin connected to vcc
int dataPin2 = 4;   //Pin connected to vcc
void setup() {
  //output to control shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
}

All OK so far

void loop() {
  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 132);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

If you are sending 255 to the anodes, why did you make it 132? 0b10000100 ?

  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 145);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);

So since when is 145 - 0b10001001 - equal to zero?

  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 2);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

Or 255 equal to 2?

  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 253);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);
}

or 255 equal to zero?

From where did these random numbers come?

The Diagram isn't exactly the model 1:1, its just a diagram i found that is extremely similar to my circuit, just ignore the buttons,LCD screen and the pot and reverse the ground and vcc pins. I was trying to mess with the code to see if a certain number can represent a LED on the matrix but it didn't really work out as you can tell. Im not sure what kind of code to use correctly to get the correct output from both 595's. For instance, i wanted to see if I can light the very 1st LED, at the top right and then light the very bottom right of the matrix. I only know how to set the output's of the ardunio pins to match the data lines of the 595 (like connecting Clock, latch and data pins and setting them to output on arduino) but from there , i dont know how to use the correct multiplexing code. Is there any other code for controlling the outputs of the 595's?

aimmet:
The Diagram isn't exactly the model 1:1, its just a diagram i found that is extremely similar to my circuit,

Hey, look you must play the game here. If the diagram does not represent the way you wired it, then you are seriously wasting my time in trying to help you. :astonished:

aimmet:
I'm not sure what kind of code to use correctly to get the correct output from both 595's.

Yeah, and if I do not know what your circuit is, I definitely can't help you. :astonished:

aimmet:
I don't know how to use the correct multiplexing code. Is there any other code for controlling the outputs of the 595's?

The code element,

void loop() {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, bitmap);
  digitalWrite(latchPin, HIGH);

Is quite correct. How you use it is what matters. :roll_eyes:

Im sorry if it looks messy im still relatively new to this program. The resistors are 220ohm 1 watt btw


The link provides a much clearer picture, thanks again.

You need 0.1uF ceramic capacitors between the 5V and ground of all chips you use. These are for power supply decoupling and are not optional.

Is there any alternative? I don't have that type of capacitor with me at the moment

Better get some then. :astonished: Larger values, or half the value are OK as long as they are ceramic.

Absolutely essential component if you are using any digital ICs.

It appears you have replicated the arrangement in the original description whereby the sequence of pins for clock, latch and data is reversed for the second shift register. Frankly, it would be a lot easier - and work better - if you chained the shift registers and used only the three pins.

Why would it work better? Because the latch operation would occur simultaneously for both rows and columns, avoiding any intermediate conditions in the multiplexing process which would cause "ghosting" and require additional code to prevent.

aimmet:
Is there any alternative?

No, it has to be a ceramic capacitor, the value is less critical anywhere from 0.1uF to about 20 nF.

Paul__B:
Better get some then. :astonished: Larger values, or half the value are OK as long as they are ceramic.

Absolutely essential component if you are using any digital ICs.

It appears you have replicated the arrangement in the original description whereby the sequence of pins for clock, latch and data is reversed for the second shift register. Frankly, it would be a lot easier - and work better - if you chained the shift registers and used only the three pins.

Why would it work better? Because the latch operation would occur simultaneously for both rows and columns, avoiding any intermediate conditions in the multiplexing process which would cause "ghosting" and require additional code to prevent.

Ill try to see if, I do think i have one ceramic capacitor on me.
Daisy chain all 3 pins? How would the the Arduino know which 595 is grounded then? If i do daisy chain both 595's , can I use the same code as before and just remove the grounded pin set up? Would it still be possible to light up an individual LED of my choice from ardunio? sorry if these questions seem a little dumb im just trying to get as much information as possible. If I do end up daisy chaining them, Do you know the code that can access a certain LED?

Just a general comment on coding style: If you’re representing bit patterns, do NOT write the equivalent number in decimal. Write in hex or binary (or octal, if you must). The issues with 132, 253, 147 etc that were mentioned earlier would have been more immediately apparent.

Looking at your circuit, I guess the idea is to output 0V to the negative side of an LED and 5V to the positive side; the LED will illuminate. An RGBW LED is actually 4 LEDs in one package, so you actually have 256 LEDs to control, hence you need to use all 8 bits of both shift registers. It would be helpful to know exactly what the logical arrangement of the LEDs vs shift registers is. Do you see it as 4 rows of 16 LEDs, with 4 outputs to select the colour? Or an 8x8 grid of LEDs, with a 2x2 combination to select the colour?

But, generally speaking, if you output 0x01 to the positive side of the LED matrix and 0xFE to the negative side, you should illuminate one colour of the LED at the bottom left corner of your matrix.

Beware that turning on more than one LED in a row or column may exceed the current capabilities of a shift register (35mA) and possibly destroy it. Probably you should have 8 transistors controlled by each shift register to deliver the current to the LEDs. But then you somehow need to limit the current flowing through each LED.

So, for the positive side, values you should use are one of: 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80.
For the negative side, you want one of the inverses of those: 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F.

To cycle through bits, the << operator is useful. e.g. the following (untested code!) will cycle through all your LEDs.

for (int x = 1; x < 0x100; x <<= 1) {
  digitalWrite(latchPin, LOW);
  //Send x to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, x);  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

  for (int y = 1; y < 0x100; y <<= 1) {
    digitalWrite(latchPin2, LOW);
    //Send inverse of y to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
    shiftOut(dataPin2, clockPin2, MSBFIRST, ~y);  // shifting out the bits NB: inverse Y
    digitalWrite(latchPin2, HIGH);
    delay(1000);
  }
}

frankvnz:
Just a general comment on coding style: If you’re representing bit patterns, do NOT write the equivalent number in decimal. Write in hex or binary (or octal, if you must). The issues with 132, 253, 147 etc that were mentioned earlier would have been more immediately apparent.

Looking at your circuit, I guess the idea is to output 0V to the negative side of an LED and 5V to the positive side; the LED will illuminate. An RGBW LED is actually 4 LEDs in one package, so you actually have 256 LEDs to control, hence you need to use all 8 bits of both shift registers. It would be helpful to know exactly what the logical arrangement of the LEDs vs shift registers is. Do you see it as 4 rows of 16 LEDs, with 4 outputs to select the colour? Or an 8x8 grid of LEDs, with a 2x2 combination to select the colour?

But, generally speaking, if you output 0x01 to the positive side of the LED matrix and 0xFE to the negative side, you should illuminate one colour of the LED at the bottom left corner of your matrix.

Beware that turning on more than one LED in a row or column may exceed the current capabilities of a shift register (35mA) and possibly destroy it. Probably you should have 8 transistors controlled by each shift register to deliver the current to the LEDs. But then you somehow need to limit the current flowing through each LED.

So, for the positive side, values you should use are one of: 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80.
For the negative side, you want one of the inverses of those: 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F.

To cycle through bits, the << operator is useful. e.g. the following (untested code!) will cycle through all your LEDs.

Well actually its not all in one LED, Rather the pattern is R = red, G = green, W = White and B = Blue
so theres one color LEDs just assorted in the 64 array.
R G B W R G B W
G B W R G B W R
B W R G B W R G
W R G B W R G B
R G B W R G B W
G B W R G B W R
B W R G B W R G
W R G B W R G B
My main issue is im having trouble controlling the ground and and anodes of the LEDs with the 2 74HC595s. I was going to follow what Paul_B said and use 1k ohm resistor to see if it would fix the issue, I can get a row of LEDs to light up but I cant choose which one specifically to light up and only the Red and Green light up, not blue or white, so theres that issue too.

So i used your code, and i even sent the grounded 595 bits to 0 and it didn’t affect it at all. Heres the code for

int latchPin = 6;  //Pin connected to groundd
int clockPin = 5;  //Pin connected to  ground
int dataPin = 7;   //Pin connected to ground

int latchPin2 = 3;  //Pin connected to vcc
int clockPin2 = 2;  //Pin connected to vcc
int dataPin2 = 4;   //Pin connected to vcc

void setup() {
  //output to control shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
  int i = 0;
}

void loop() {




/*  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 5);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);



  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 10);
      delay(250);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);

  digitalWrite(latchPin, LOW);
  //Send 1 1 1 1 1 1 1 1 (255) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

  digitalWrite(latchPin2, LOW);
  //Send 0 0 0 0 0 0 0 0 (0) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
  shiftOut(dataPin2, clockPin2, MSBFIRST, 4);
        delay(500);
  // shifting out the bits
  digitalWrite(latchPin2, HIGH);
}
*/

for (int x = 1; x < 0x100; x <<= 1) {
  digitalWrite(latchPin, LOW);
  //Send x to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
  shiftOut(dataPin, clockPin, MSBFIRST, 0);  // shifting out the bits:
  digitalWrite(latchPin, HIGH);

  for (int y = 1; y < 0x100; y <<= 1) {
    digitalWrite(latchPin2, LOW);
    //Send inverse of y to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
    shiftOut(dataPin2, clockPin2, MSBFIRST, ~y);  // shifting out the bits NB: inverse Y
    digitalWrite(latchPin2, HIGH);
    delay(1000);
  }
}
}

I feel like the the anode portion of the 74HC595 is working but for some reason I cant control the grounded 595, it seems to always have grounded on for all the LEDs no matter what bits i send. Im not extremely knowledged in multiplexing so i think it may be a software issue im doing wrong

This was the results