Noob needs some help with code

hi paul.....made the changes to the code and using the hex representations for the patters now.....unfortunately the cube is still WIP so i thought of doing some debugging using Serial prints. The updated code is here:

#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash
#include <SPI.h>

#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 1111 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 20 // multiplies DisplayTime to get ms - why not =100?
#define LATCHPIN 10
// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation


PROGMEM prog_uint32_t PatternTable[] = {
  // blink on and off

  0x0000ffff,0xffffffff,0xffffffff,0xffffffff, 1,
  0xffff0000,0xffffffff,0xffffffff,0xffffffff, 1,

  // this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
  0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0,
};

/*
** Defining pins in array makes it easier to rearrange how cube is wired
 ** Adjust numbers here until LEDs flash in order - L to R, T to B
 ** Note that analog inputs 0-5 are also digital outputs 14-19!
 ** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
 */
int PlanePin[] = {
  16, 17, 18, 19};

// initialization
void setup()
{
  int pin; // loop counter
  pinMode(LATCHPIN, OUTPUT);
  // set up plane pins as outputs (active LOW)
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( PlanePin[pin], OUTPUT );
  }
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  Serial.begin(9600);
}  

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
  // declare variables
  unsigned long PatternBuf[PLANESIZE]; // saves current pattern from PatternTable
  int PatternIdx;
  byte DisplayTime; // time*100ms to display pattern
  unsigned long EndTime;
  int plane; // loop counter for cube refresh
  int patbufidx; // indexes which byte from pattern buffer

  // Initialize PatternIdx to beginning of pattern table
  PatternIdx = 0;
  // loop over entries in pattern table - while DisplayTime>0
  do {
    // read pattern from PROGMEM and save in array
    memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
    PatternIdx += PLANESIZE;
    // read DisplayTime from PROGMEM and increment index
    DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );
    // compute EndTime from current time (ms) and DisplayTime
    EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;

    // loop while DisplayTime>0 and current time < EndTime
    while ( millis() < EndTime ) {
      for (plane=0; plane<CUBESIZE; plane++) {       // loop over planes
        digitalWrite(LATCHPIN, LOW); //take latchpins low to load data to '595
        SPI.transfer(PatternBuf[plane]); //shift out 4-bytes for the current plane
        Serial.println("Value");
        Serial.println(PatternBuf[plane], DEC);
    
        digitalWrite(LATCHPIN, HIGH); //take latch pin high to display data
        digitalWrite( PlanePin[plane], HIGH ); //activate current plane
        Serial.println("Plane");
        Serial.println(PlanePin[plane]);
        
        delayMicroseconds( PLANETIME );         // delay PLANETIME us
        digitalWrite(PlanePin[plane], LOW); //de-activate current plane
        
        delay(1000);
      } // for plane
    } // while <EndTime
  } 
  while (DisplayTime > 0); // read patterns until time=0 which signals end
}

I think i understand why i keep getting the same value whether i print in HEX/DECIMAL/BINARY for both the patterns for the first plane....my question is, is this going to work as expected meaning the zeros will get loaded to the shift registers in the proper order (in the first case 16- zeros to one 595 and 16- ones to the other one and then the opposite the second time). Also is there a way to print the zeros to the serial monitor to make it easier to debug?

is this going to work as expected meaning the zeros will get loaded to the shift registers in the proper order (in the first case 16- zeros to one 595 and 16- ones to the other one and then the opposite the second time).

Yes, the zeros are present and will get shifted out.

Also is there a way to print the zeros to the serial monitor to make it easier to debug?

You would need to convert the value to a string yourself, using sprintf() with the appropriate format specifier - 0x%016z - will convert a value to hex format, with 16 characters with leading 0s.

i completed the controller yesterday and was testing the code on it....but for some reason my shift registers are not getting updated....when i plug in the power they just stay stuck at the same output.....i have tried a simple shiftout() code to check if it is the code that is somehow an issue but even that does not seem to work...i tried shifting out a single binary value to see if atleast the first shift register was working but with no luck....i have checked the wiring a number of times over but can not seem to find the issue.....i came across another post that mentioned that the '595 should be powered from the arduino 5v pin....my current setup is powering the '595 from the 7805 that i am using to deliver power to the LEDs....could this be the reason?

hi paul....any thoughts... :~

as long as the input voltage is not too high ( 6.0v max I think ) Low voltage will also work fine, just has a slower maximum clock.
Make sure the OE(13) pin is LOW, HIGH will disable the outputs. Use a decoupling capacitor on at least 2 of the four registers.
Also tie DS(14)either HIGH or LOW if it is floating.

Also make sure you don't have the storage/latch clock swapped with the shift clock, These are easy to mix up.

I see you're using SPI, try controlling them using digital pins to verify the wiring.

thanks pyro....turned out to be a really stupid wiring error on my part.....high time i start doing custom PCBs....general purpose vero boards just dont cut it.....but unfot i dont have a laser printer....any chance this can be done using an inkjet or some other way of masking....

Hi, I've been trying to code a 4x4x4 cube with shift registers, Im working with a few programs, and thought I'd try the one you have here.

I modified it to suit my pinout, but my cube is probably just like yours, except I only have one set of 64 leds (not 2).

Here is the mods I did, but I didnt get it working. My cube has pins 11,10,9,6 for planes, and pins 7 data, 12 clock, 13 latch. My cube is common anode, so I may have swapped some things around from what you have.

#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash
#include <SPI.h>

#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 1111 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 20 // multiplies DisplayTime to get ms - why not =100?
#define LATCHPIN 13
// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation


PROGMEM prog_uint32_t PatternTable[] = {
  // blink on and off

  0xffffffff,0xffffffff,0xffffffff,0xffffffff, 10,
  0x00000000,0x00000000,0x00000000,0x00000000, 10,

  // this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
  0xffffffff,0xffffffff,0xffffffff,0xffffffff, 0,
};

/*
** Defining pins in array makes it easier to rearrange how cube is wired
 ** Adjust numbers here until LEDs flash in order - L to R, T to B
 ** Note that analog inputs 0-5 are also digital outputs 14-19!
 ** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
 */
int PlanePin[] = {11, 10, 9, 6};  //Edited for mah plane pins

// initialization
void setup()
{
  int pin; // loop counter
  pinMode(LATCHPIN, OUTPUT);
  // set up plane pins as outputs (active HIGH) Edited
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( PlanePin[pin], OUTPUT );
  }
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  Serial.begin(9600);
}  

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
  // declare variables
  unsigned long PatternBuf[PLANESIZE]; // saves current pattern from PatternTable
  int PatternIdx;
  byte DisplayTime; // time*100ms to display pattern
  unsigned long EndTime;
  int plane; // loop counter for cube refresh
  int patbufidx; // indexes which byte from pattern buffer

  // Initialize PatternIdx to beginning of pattern table
  PatternIdx = 0;
  // loop over entries in pattern table - while DisplayTime>0
  do {
    // read pattern from PROGMEM and save in array
    memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
    PatternIdx += PLANESIZE;
    // read DisplayTime from PROGMEM and increment index
    DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );
    // compute EndTime from current time (ms) and DisplayTime
    EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;

    // loop while DisplayTime>0 and current time < EndTime
    while ( millis() < EndTime ) {
      for (plane=0; plane<CUBESIZE; plane++) {       // loop over planes
        digitalWrite(LATCHPIN, LOW); //take latchpins low to load data to '595
        SPI.transfer(PatternBuf[plane]); //shift out 4-bytes for the current plane
        Serial.println("Value");
        Serial.println(PatternBuf[plane], DEC);
    
        digitalWrite(LATCHPIN, HIGH); //take latch pin high to display data
        digitalWrite( PlanePin[plane], HIGH); //activate current plane
        Serial.println("Plane");
        Serial.println(PlanePin[plane]);
        
        delayMicroseconds( PLANETIME );         // delay PLANETIME us
        digitalWrite(PlanePin[plane], LOW); //de-activate current plane
        
        delay(1000);
      } // for plane
    } // while <EndTime
  } 
  while (DisplayTime > 0); // read patterns until time=0 which signals end
}

Its not working right at all, but I do have the serial monitor to look at, so thats an improvement.