Go Down

Topic: LED Cube 5x5x5 6 Shift Registers Code Help (Read 550 times) previous topic - next topic

V3N0M_arduino

Feb 12, 2018, 05:57 pm Last Edit: Feb 12, 2018, 07:57 pm by V3N0M_arduino
Hello everyone! I followed this instructable to build a 5x5x5 LED Cube:

www.instructables.com/id/LED-CUBE-Arduino-5x5x5/

I used 5 SN74HC595N shift registers wired to the anode columns (aka "rows" in the picture) and 1 extra Shift Register (the 6th one) to control the cathode layers (aka floors) - see picture below:



So this is the simplified schematic for the first Shift Register.



I use Arduino Due (3.3V) to control 25 anodes (rows) and 5 cathodes (layers) through NPN transistors.
The LEDs voltage drop on 3.3V supply is ~2.8V => with 100 Ohm resistor ~ 5mA / LED

Arduino Due connections:
Data Pin: 11
Latch Pin: 8
Clock Pin: 13
3.3V Vcc to the Registers
GND to Registers + NPN Emitters


For the LEDs I used 25x100 Ohm resistors and for the layers I put 2KOhm resistors in the base of a 2n2222a NPN transistor. The collector is connected to the LEDs cathode and their emitters are connected to GND.

The problem comes with the code. It does upload on my Due but I can't manage to make it work. No LEDs light up, none at all.

I tried other codes as well (4x4x4 pattern) and they worked but the patterns were not displaying correctly of course. Can you offer me some help in order to understand how to make a code to light up one LED from 1 to 25 on the first layer and then go to the second layer (led 26 to 50) and so on get to light up every LED from the cube in the end.

In my opinion it should be something like this

Code: [Select]
B10000 00000 00000 00000 00000 B10000
B01000 00000 00000 00000 00000 B10000
B00100 00000 00000 00000 00000 B10000
B00010 00000 00000 00000 00000 B10000
B00001 00000 00000 00000 00000 B10000

B00000 10000 00000 00000 00000 B10000
B00000 01000 00000 00000 00000 B10000
B00000 00100 00000 00000 00000 B10000
B00000 00010 00000 00000 00000 B10000
B00000 00001 00000 00000 00000 B10000

etc...


where the last Byte (6th shift register) is the T1 lightning up the first layer. But I might be wrong, that's why I need someone to clarify this for me.


I've read the forum rules about posting the code...but because the code is a bit long I can't post it inside. So it's attached below. Any help from you guys to make the code work would be amazing.

Thank you in advance!


sunlitho

I cannot for the life of me make Any array load to my Arduino Uno.  I've used the code from their site and that won't compile.  If I take out the array lines, it's fine.  WHy?

PaulRB

#2
Feb 14, 2018, 07:58 am Last Edit: Feb 14, 2018, 07:59 am by PaulRB
If you want us to look at your code, please post it according to form guidelines in the sticky post. Most forum members read the forum on phones & tablets and cannot open .ino attachments.

V3N0M_arduino

Code: [Select]
     
#include <avr/pgmspace.h>
#include <SPI.h>
int latchPin = 8;
int clockPin = 13;
int dataPin  = 11;
void GrowingCube();
void  CubeDiman();
void ClearOut();
void shift_out(const byte  animation[5][6], int animationTime);

void setup()
{
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.begin();
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(latchPin, OUTPUT);
//  ClearOut();

}

void loop(){

         CubeDiman();
  GrowingCube();
       CubeDiman();

      ClearOut();

  int randomAnimation = random(2);
  switch(randomAnimation){
    case 0:
      CubeDiman();
      break;
    case 1:
      GrowingCube();
   
  }
}


void CubeDiman(){
   const byte cubeD1 [5][6] PROGMEM = {{B00001, B11111, B10001, B10001, B10001, B11111},
                                      {B00010, B10001, B00000, B00000, B00000, B10001},
                                      {B00100, B10001, B00000, B00000, B00000, B10001},
                                      {B01000, B10001, B00000, B00000, B00000, B10001},
                                      {B10000, B11111, B10001, B10001, B10001, B11111}};
                                     
                           
                                     
                                       
  shift_out(cubeD1, 4000);

  ClearOut();
}




void GrowingCube(){
  const byte cube1 [5][6] PROGMEM =  {{B00001, B00000, B00000, B00000, B00011, B00011},
                                      {B00010, B00000, B00000, B00000, B00011, B00011},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                       
  const byte cube2 [5][6] PROGMEM =  {{B00001, B00000, B00000, B00111, B00111, B00111},
                                      {B00010, B00000, B00000, B00111, B00111, B00111},
                                      {B00100, B00000, B00000, B00111, B00111, B00111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                     
  const byte cube3 [5][6] PROGMEM =  {{B00001, B00000, B01111, B01111, B01111, B01111},
                                      {B00010, B00000, B01111, B01111, B01111, B01111},
                                      {B00100, B00000, B01111, B01111, B01111, B01111},
                                      {B01000, B00000, B01111, B01111, B01111, B01111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                     
  const byte cube4 [5][6] PROGMEM =  {{B00001, B11111, B11111, B11111, B11111, B11111},
                                      {B00010, B11111, B11111, B11111, B11111, B11111},
                                      {B00100, B11111, B11111, B11111, B11111, B11111},
                                      {B01000, B11111, B11111, B11111, B11111, B11111},
                                      {B10000, B11111, B11111, B11111, B11111, B11111}};
                     
  const byte cube5 [5][6] PROGMEM =  {{B00001, B11111, B11111, B11111, B11111, B11111},
                                      {B00010, B11111, B11111, B11111, B11111, B11111},
                                      {B00100, B11111, B11111, B11111, B11111, B11111},
                                      {B01000, B11111, B11111, B11111, B11111, B11111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                     
  const byte cube6 [5][6] PROGMEM =  {{B00001, B11111, B11111, B11111, B11111, B11111},
                                      {B00010, B11111, B11111, B11111 ,B11111, B11111},
                                      {B00100, B11111, B11111, B11111, B11111, B11111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                     
  const byte cube7 [5][6] PROGMEM =  {{B00001, B11111, B11111, B11111, B11111, B11111},
                                      {B00010, B11111, B11111, B11111, B11111, B11111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
 
  // To avoid different brightness I always shiftout an array with a 5*6 dimension                   
  const byte cube8 [5][6] PROGMEM =  {{B00001, B11111, B11111, B11111, B11111, B11111},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000},
                                      {B00000, B00000, B00000, B00000, B00000, B00000}};
                     
  shift_out(cube1, 1000);
  shift_out(cube2, 1000);
  shift_out(cube3, 1000);
  shift_out(cube4, 1000);
  shift_out(cube5, 1000);
  shift_out(cube6, 1000);
  shift_out(cube7, 1000);
  shift_out(cube8, 1000);
  ClearOut();
}

void ClearOut(){
  digitalWrite(latchPin, LOW);
  for(int b=0; b<6; b++){
    SPI.transfer(B00000);
  }
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
}

void shift_out(const byte  animation[5][6], int animationTime){
  for(int i=0; i<(animationTime*0.2);i++){
    for(int a=0; a<5; a++){
      digitalWrite(latchPin, LOW);
      for(int b=0; b<6; b++){
        SPI.transfer(animation[a][b]);
      }
      digitalWrite(latchPin, HIGH);
      delay(1);
    }
  }
}


   


Sorry about the ino file  ;D
I deleted some of the functions(animations/patterns) from the original code to be able to upload it here.

PaulRB

So this code lights nothing? Not even flickering?

But the code for the 4x4x4 cube you tried out at least lit some LEDs, even if it was flickery and random? Can you post that code? There must be some key difference...

V3N0M_arduino

#5
Feb 14, 2018, 09:24 pm Last Edit: Feb 14, 2018, 09:37 pm by V3N0M_arduino
The code I posted didn't light anything at all, not even flickering. It's weird because the code didn't work for anybody (see the instructable comments)

This code worked for me but the patterns were for 4x4x4:

Code: [Select]
// Code corrected and amended by John Longworth BSc Hons October 2015  jlongworth55@yahoo.co.uk
// OCT32012 editing changes to adapt this program to work with shift registers,
// and to work with Common Cathode LED cube.

// Pins for UNO & MEGA with 4x4x4 ICStation shield
// Pins D0 - D15 are connected to the outputs of the 2 595 ICs

#include <avr/pgmspace.h>      // allows use of PROGMEM to store patterns in flash
#define LatchPin 8            // Pin connected to Pin 12 of 74HC595 (Latch STCP)
#define ClockPin 13             // Pin connected to Pin 11 of 74HC595 (Clock SHCP)
#define DataPin  11             // Pin connected to Pin 14 of 74HC595 (Data DS)
unsigned long endTime;         // Duration of pattern display
int displayTime = 100;         // Time to display pattern
byte planePin[] {7,6,5,4};     // D16 - D19 Ground for each plane  D16 - Top plane  D19 Bottom plane
int p[8] = {0,0,0,0,0,0,0,0};  // Passes pattern values to patDisplay()

// LED Pattern Table in PROGMEM - last column is display time in 100ms units
const unsigned char PROGMEM patterns[] = {
//1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    16 
B0001,B0000,B0000,B0000,B0001,B0000,B0000,B0000,B0001,B0000,B0000,B0000,B0001,B0000,B0000,B0000,5, //start stairs up down and around outside
B0010,B0000,B0000,B0000,B0010,B0000,B0000,B0000,B0010,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B0100,B0000,B0000,B0000,B0100,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,5,
B0000,B1000,B0000,B0000,B0000,B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,


...(deleted patterns to fit the forum)


// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000,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

   Just a note to say we dont do things this way anymore. Data is serialized
   to pin 7 via 74hc595 shift registers, and the planes(layers) are controlled
   by pins 11,10,9,6. The first shift register controls the first 8 pins, the
   second shift register controls pins 9-16.
   Looking down on the cube, the column pin matrix looks like this:

   16 15 14 13
   12 11 10  9
    8  7  6  5
    4  3  2  1
This code is for a cube with common cathode, meaning send 5 volts to illuminate the individual led, and ground the plane(layer)
*/

void setup() {
  //Serial.begin(9600);  // Do not use in program
  pinMode(LatchPin, OUTPUT);
  pinMode(ClockPin, OUTPUT);
  pinMode(DataPin, OUTPUT);
  for (int i = 0;i < 4; i++) {
    pinMode(planePin[i], OUTPUT);
    digitalWrite(planePin[i], LOW);     
  }
  endTime = millis() + 10;
}

void loop() {   
  byte patBuffer[16]; // saves current pattern from PatternTable
  int patIndex = 0;
  do { 
    patDisplay(p);   
    if (millis() > endTime) {
      memcpy_P(patBuffer, patterns + patIndex, 17);
      patIndex+=17;
      for (int i = 0; i < 8; i++) {         
        p[i] = patBuffer[(i*2)] + patBuffer[(i*2)+1];         
      }
      displayTime = patBuffer[16];
      endTime = millis() + (displayTime * 20);                     
    }
  } while (displayTime > 0);     
}

void patDisplay(int p[8]) {
  allOff();   
  for (int i = 0;i < 4; i++) {
    digitalWrite(planePin[i], LOW);    // Turn plane on
    displayMatrix(p[i*2],p[(i*2)+1]);  // Display LEDs on the selected plane
    delayMicroseconds(4000);           // Wait
    digitalWrite(planePin[i], HIGH);   // Turn plane off
    displayMatrix(0,0);                // Turn all LEDs off
  }
}

void allOff() {
  displayMatrix(0,0);  // Turn off all 16 LEDs
  for (int i = 0;i < 4; i++) digitalWrite(planePin[i], HIGH);
}

void displayMatrix(int first8, int second8) {  // Write data to the 595 ICs
  digitalWrite(LatchPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, second8);  // D15 to D8
  shiftOut(DataPin, ClockPin, MSBFIRST, first8);   // D7 to D0     
  digitalWrite(LatchPin, HIGH);       
}
// The code above is my version
// The code below is the original that I found on the internet


I managed to make the cube work in the end by removing the transistors connections from the output  of the 6th Shift Register and adding them to pins 7,6,5,4,3 on Arduino. I defined them as planePins while using a similar type of code to the 4x4x4 cube.

I just wanted to clarify what can be wrong with the original code that doesn't work... for anyone.

Go Up