I'm as good as new to Arduino and only have a basic electronics background, but I thought a fun first project to do, would be a 4x4x4 LED cube. So far, I have created my first level: a grid of 4 by 4 LED's (16 in total). I am working with two 8bit shift registers (the 74HC595) and just want to have a basic LED chase to see if all LED's are connected properly.
At the moment, this is my code:
int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int values[] = {1, 2, 4, 8, 16, 32, 64, 128};
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
// count from 0 to 255 and display the number
// on the LEDs
int index;
int value1, value2;
for (int i = 0; i < 16; i++) {
// take the latchPin low so
// the LEDs don't change while you're sending in bits:
digitalWrite(latchPin, LOW);
// shift out the bits:
index = i%8;
if(i < 8)
{
value2 = values[index];
value1 = 0;
} else {
value2 = 0;
value1 = values[index];
}
shiftOut(dataPin, clockPin, MSBFIRST, value1);
shiftOut(dataPin, clockPin, MSBFIRST, value2);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
// pause before next value:
delay(100);
}
}
Since I am working with two shift registers, I have to shiftout twice, but seeing as I want to do a LED chase (where one shift register is only needed for half the for-loop), I have to shift 0 out as well? I come from a webdevelopment background and I'm still trying to wrap my ahead around the Arduino logic. The way I'm switching value1 and value2 feels very clumsy. Is there any better way of doing this?
Instead of shifting out a zero, should I use the master reset pin?
Brammm:
Since I am working with two shift registers, I have to shiftout twice, but seeing as I want to do a LED chase (where one shift register is only needed for half the for-loop), I have to shift 0 out as well? I come from a webdevelopment background and I'm still trying to wrap my ahead around the Arduino logic. The way I'm switching value1 and value2 feels very clumsy. Is there any better way of doing this?
Instead of shifting out a zero, should I use the master reset pin?
Firstly I want to clarify how you have the shift registers wired up - normally you'd run the shift out of one into the shift in of the other (pin 9 of one to 14 of the other. Then you always shift 16 bits at a time before pulsing the RCLK line. So have you connected your "latchpin" to RCLK (pin 12 on each shift register)? If you've connected to pins 13 (OE) instead you'll get unnecessary flicker.
As for you loop, I think its best to pass one 16 bit value to your output code (which will work with any pattern). so something like
void update_LEDs (int patt) // general LED update with 16 bits
{
shiftOut (dataPin, clockPin, MSBFIRST, patt >> 8); // shift 16 bits into registers
shiftOut (dataPin, clockPin, MSBFIRST, patt & 0xFF);
digitalWrite (latchPin, HIGH) ; // toggle RCLK to update outputs
digitalWrite (latchPin, LOW) ;
}
void loop ()
{
for (int i = 0 ; i < 16 ; i++)
{
update_LEDs (1 << i) ; // create a pattern with a shift left - no table needed for a simple pattern like this
delay (100) ;
}
}
There's no need to waste storage for a simple pattern like that as it can be generated on the fly simply (1 << i). int or unsigned int are 16 bit which is just what you need for 2 shift registers - use long int if 4 shift registers
You can daisy-chain the shift registers, every bit you shift in moves the rest up overflow from the first goes to bit zero of the second and overflow from that goes back MISO to the Arduino.
IMO, you want to latch on every bit transferred instead of bytes and then your leds will scroll.
And you have plenty of time between changes if you want to run it slow enough for eyes (not just make dim lit leds). Heck you could SCK real slow, 1 bit per 1/10th second would move 10 pixels per second. They're shift registers, bits shift in and bits shift out. The pattern is in the bits.
You can move 1 bit per interval or you can move 16 to do the same thing. You wouldn't need the SPI port at all if you don't mind shifting your own bits. Best way IMO is all 4 pins on the same PORT to operate on using PORT reads and writes to get/set data all at once.
MarkT:
Firstly I want to clarify how you have the shift registers wired up - normally you'd run the shift out of one into the shift in of the other (pin 9 of one to 14 of the other. Then you always shift 16 bits at a time before pulsing the RCLK line. So have you connected your "latchpin" to RCLK (pin 12 on each shift register)? If you've connected to pins 13 (OE) instead you'll get unnecessary flicker.
As for you loop, I think its best to pass one 16 bit value to your output code (which will work with any pattern). so something like
...
There's no need to waste storage for a simple pattern like that as it can be generated on the fly simply (1 << i). int or unsigned int are 16 bit which is just what you need for 2 shift registers - use long int if 4 shift registers
I'm going to have a look at this tutorial here: http://www.arduino.cc/playground/Code/BitMath and bitmath in general as this is complete magic for me at the moment. Your code works like a charm and I've found that if I change the code to update_LEDs (3 << i), two leds chase (as expected), but I have no clue or how
edit: I've now editted Mark's code a little to suit my LED cube: