74HC595 > More than one output at a time

Hi,

I searched for more than one hour now, reading many codes and many tutorial, but still can’t understand how to output many pins at the same time.

I have my basic circuit with 8 leds connected to a 74HC595, and I am able to light one led at a time, light none, or light all (using 0xFF).

But I don’t understand how to light for example:
Pin 0, 2 and 4 at the same time (or any other combination). Anybody could explain to me how to do that?

Thanks!

The best thing for you to do is show the code you use for lighting one LED, no LEDs, and all LEDs.

If you can light a specific LED (say #7 or #3), then you should be able to combine that code/value to light multiple LEDs.

I am able to light one led at a time, light none, or light all (using 0xFF).

How are you able to do that, but not other patterns (like 0x15, as per your other example, pin 0,2 and 4)? How do you connect the shiftregister to the arduino, and what code do you use?

Anyway, the function shiftOut() will do what you want: http://arduino.cc/en/Reference/ShiftOut There is even a link to a 74HC595 tutorial there: http://arduino.cc/en/Tutorial/ShiftOut

PS! You do have current limiting resistors in series with each LED of course?

Hi,

I have the exact same circuit as on the tutorial. 8 leds with resistor, the shiftregister, the arduino.

Here is the code:

void light(int n) {
  digitalWrite(latch, LOW);
  shiftOut(data, clock, MSBFIRST, n);  
  digitalWrite(latch, HIGH);
  delay(500);
}

To light all: light(0xFF);

To light none: light(0x00);

To light only led 1: byte bitBuffer = 0; bitWrite(bitBuffer, 1, HIGH); light(bitBuffer);

I don't understand how to calculate the hex value to light more than one pin. I don't want to use defined values, I want to be able to calculate the hex. Can't find this anywhere...

0xFF = B11111111 0x00 = B00000000

To light only led 1: byte bitBuffer = 0; bitWrite(bitBuffer, 1, HIGH); light(bitBuffer);

This results in bitBuffer containing

B00000001 = 0x01

The 2nd argument to bitWrite is the bit position to set/LED # to light.

The light 3 LEDs - 1, 4 , & 7:

To light only led 1: byte bitBuffer = 0; bitWrite(bitBuffer, 1, HIGH); bitWrite(bitBuffer, 4, HIGH); bitWrite(bitBuffer, 7, HIGH); light(bitBuffer);

B01001001 = 0x49

To light only led 1: byte bitBuffer = 0; bitWrite(bitBuffer, 1, HIGH); light(bitBuffer);

This results in bitBuffer containing

B00000001 = 0x01

No it doesn't ; bitWrite(bitBuffer, 1, HIGH); results in bitBuffer == B00000010 == 0x02.

byte bitBuffer = 0;
bitWrite(bitBuffer, 1, HIGH);
bitWrite(bitBuffer, 4, HIGH);
bitWrite(bitBuffer, 7, HIGH);
light(bitBuffer);

B10010010 = 0x92

So simple. i tried many things but not this. Thanks!

Groove is correct, as usual. It was too early in the morning...

Thanks guys for your help!

My code is working.

For people who are searching a solution to this problem, here is my code that allows to control 8 leds easily with a 74HC595. It is working with the simple circuit displayed on http://arduino.cc/en/Tutorial/ShiftOut (the one using only one 74HC595 and 8 leds)

// pins for the 74HC595
int data = 2;
int clock = 3;
int latch = 4;

void setup()   {
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
}

void loop() {
  // create the light patterns
  light(x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,LOW,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,LOW,LOW,HIGH,HIGH,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,LOW,LOW,LOW,HIGH,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,LOW,LOW,LOW,LOW,HIGH,HIGH,HIGH));
  light(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,HIGH,HIGH));
  light(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,LOW,HIGH));
  light(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW));
  light(x8sprite(HIGH,LOW,LOW,LOW,LOW,LOW,LOW,LOW));
  light(x8sprite(HIGH,HIGH,LOW,LOW,LOW,LOW,LOW,LOW));
  light(x8sprite(HIGH,HIGH,HIGH,LOW,LOW,LOW,LOW,LOW));
  light(x8sprite(HIGH,HIGH,HIGH,HIGH,LOW,LOW,LOW,LOW));
  light(x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,LOW,LOW,LOW));
  light(x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,LOW,LOW));
  light(x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,LOW));
}

// convert 8 states into a byte
byte x8sprite(int b1,int b2,int b3,int b4,int b5,int b6,int b7,int b8) {
  byte bitBuffer = 0;
  bitWrite(bitBuffer, 0, b1);
  bitWrite(bitBuffer, 1, b2);
  bitWrite(bitBuffer, 2, b3);
  bitWrite(bitBuffer, 3, b4);
  bitWrite(bitBuffer, 4, b5);
  bitWrite(bitBuffer, 5, b6);
  bitWrite(bitBuffer, 6, b7);
  bitWrite(bitBuffer, 7, b8);
  return bitBuffer;
}

// send a byte to the 74HC595
void light(int n) {
  shiftOut(data, clock, MSBFIRST, n);
  digitalWrite(latch, LOW); 
  digitalWrite(latch, HIGH);
  delay(500);
}

:)

There is one little error:

// send a byte to the 74HC595
void light(int n) {
  digitalWrite(latch, LOW);   //should be here
  shiftOut(data, clock, MSBFIRST, n);
  // digitalWrite(latch, LOW);// not here, i think..
  digitalWrite(latch, HIGH);
  delay(500);
}

If you put digitalWrite(latch, LOW); before sending the data, all the leds are gonna be shut-down while the data is sending, creating an annoying blinking effect. By putting it after, it's working well without any blinking effect.

To control the 16 leds circuit with 2x 74HC595: (just finished it and tested it successfully)

// pins for the 74HC595
int data = 2;
int clock = 3;
int latch = 4;

void setup()   {
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
}

void loop() {
  light16(x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH),x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW));
  light16(x8sprite(LOW,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH),x8sprite(HIGH,LOW,LOW,LOW,LOW,LOW,LOW,LOW));
  light16(x8sprite(LOW,LOW,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH),x8sprite(HIGH,HIGH,LOW,LOW,LOW,LOW,LOW,LOW));
  light16(x8sprite(LOW,LOW,LOW,HIGH,HIGH,HIGH,HIGH,HIGH),x8sprite(HIGH,HIGH,HIGH,LOW,LOW,LOW,LOW,LOW));
  light16(x8sprite(LOW,LOW,LOW,LOW,HIGH,HIGH,HIGH,HIGH),x8sprite(HIGH,HIGH,HIGH,HIGH,LOW,LOW,LOW,LOW));
  light16(x8sprite(LOW,LOW,LOW,LOW,LOW,HIGH,HIGH,HIGH),x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,LOW,LOW,LOW));
  light16(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,HIGH,HIGH),x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,LOW,LOW));
  light16(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,LOW,HIGH),x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,LOW));
  light16(x8sprite(LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW),x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH));
}

// convert 8 states into a byte
byte x8sprite(int b1,int b2,int b3,int b4,int b5,int b6,int b7,int b8) {
  byte bitBuffer = 0;
  bitWrite(bitBuffer, 0, b1);
  bitWrite(bitBuffer, 1, b2);
  bitWrite(bitBuffer, 2, b3);
  bitWrite(bitBuffer, 3, b4);
  bitWrite(bitBuffer, 4, b5);
  bitWrite(bitBuffer, 5, b6);
  bitWrite(bitBuffer, 6, b7);
  bitWrite(bitBuffer, 7, b8);
  return bitBuffer;
}

// send a byte to the 74HC595
void light16(int n, int n2) {
  shiftOut(data, clock, MSBFIRST, n);
  shiftOut(data, clock, MSBFIRST, n2);
  digitalWrite(latch, LOW); 
  digitalWrite(latch, HIGH);
  delay(500);
}

Ups, but you could simplify alot your code, because: x8sprite(HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH,HIGH) is the same as: byte sprite = 0x11111111 For every high you just put one 1, and for a low you put one zero, the 0x means that it is an hexadecimal number.

@Senso, that won't work, because 0x11111111 is a 32 bit number, and a byte is only 8 bits wide. You need to use "byte sprite = B11111111;"

I'm so used to using 0xsomething that i forgot that it should be Bsomething, he can always use 0x00 to 0xFF but maybe thats over him.

Thanks for posting the code. i was searching for it, can i add more shift registers to it??

About that same question: you can use the binary constants found in "binary.h" header file, inside the arduino core folder. That might help you.