Go Down

Topic: help me improve my code for controlling 64 leds with 2 74HC595N ic's (Read 1 time) previous topic - next topic

Paul__B

Better get some then.  :smiley-eek:  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.

Grumpy_Mike

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.

aimmet

Better get some then.  :smiley-eek:  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?

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.

Code: [Select]

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);
  }
}

aimmet

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

Code: [Select]

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
https://youtu.be/Cc4yfoLEVv4

Paul__B

Daisy chain all 3 pins? How would the the Arduino know which 595 is grounded then?
OK, "daisy chaining" means that you feed the output (pin 9) of the first shift register into the input of the second.  Both have the same clock and latch connection.

You now have a 16 bit shift register.  You load it with two successive shiftOut operations, the first one puts the data into the first register then the second shiftOut moves that same data into the second register as it loads the new data into the first.  Only after both shiftOut operations, do you strobe the latch(es - together).

We can help you with the code to do that, if you show how you have actually wired it.  :smiley-lol:


aimmet

OK, "daisy chaining" means that you feed the output (pin 9) of the first shift register into the input of the second.  Both have the same clock and latch connection.

You now have a 16 bit shift register.  You load it with two successive shiftOut operations, the first one puts the data into the first register then the second shiftOut moves that same data into the second register as it loads the new data into the first.  Only after both shiftOut operations, do you strobe the latch(es - together).

We can help you with the code to do that, if you show how you have actually wired it.  :smiley-lol:


This is how it looks like right now with out daisy chaining, just keep in mind there not all red leds its actually Red, green, blue, white, Red, green, blue, white, repeated 8 times going down. and i could not find a capacitor unfortunately
Picture of set up

aimmet

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.

Code: [Select]

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);
  }
}


I just used a 8 x 8 pre built matrix and your code works! Cycling through each led it cycles through all the leds but for the first 3 seconds its blank but then the top left led lights up and it starts doing down the column then goes to the next row. So can you give a little better explanation on how this works exactly? How do i match the positive and negative side to get a LED that I want? Say I want the LED from the 3rd colmn and 2nd row to light up?

Go Up