Go Down

Topic: 3x3 Cube light wont light :/ (Read 1 time) previous topic - next topic

TheColdest

Thanks for responding to my forum post Robert, I did re-wire and set up the cube with the schematics you uploaded on my post. I did move the middle row to A, 14, 24, and 34... were they supposed to be offset from the other two that are one 15, 25, and 35?

With the ULN2003A should I be connecting the 3 levels, or the 9 columns vs both? I was also playing around with the example of 'BlinkWithoutDelay' and it seemed to do the trick of turning on one single light at a time, except I do not understand how to add more less into the example code, any tips/ recommendations?

I added a attachment of the rewire and I'm using the same code from my post earlier, thanks again! You're fine to reply back to my email here or on my post in the Arduino forums.

my goal here is to multiplex these lights, how should I be starting my program?

Hippynerd

The ULN2003 has 7 arrays, so you would need 2 chip to run the columns.
Have you tested your cube to make sure each LED lights, and only one LED lights at a time?

You may want to write a simple test program that lights 1 LED, then pauses, then turns off the LED, then lights the next LED, until it sequences all the LEDs. 2 loops (1 to 3, and 1 to 9) would be nice, but you can do it any way you like.

Once you have the wiring setup right, everything seems to light properly, you can go back and add your other components if you want, then make sure it still works.


From :
http://arduino.cc/playground/Main/LEDCube3x3
I found this 3x3x3 cube code, Ive modified it to work with your cubes pinout.
It uses pins 0-8 and 11,12,13 (i didnt know there was a pin0, but I did put it in the code, to match the pins used in your code.


Code: [Select]
/*
Based on ledcube.c from Make: September 7, 2007 weekend podcast 
http://blog.makezine.com/archive/2007/09/make_a_pocket_led_cube_we.html

Custom animation programmed by Mark Boszko, http://stationinthemetro.com
*/

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

#define CUBESIZE 3
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 3333          // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 20          // multiplies DisplayTime to get ms - why not =100?

// 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
prog_uchar PROGMEM PatternTable[] = {
  // blink on and off
    B111, B111, B111, B111, B111, B111, B111, B111, B111, 5,
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B111, B111, B111, B111, B111, B111, B111, B111, B111, 5,
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 1,
  // flash each LED in sequence:
  // Left->Right column, then Top->Bottom row, then Upper->Lower plane
    B100, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B010, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B001, B000, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B100, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B010, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B001, B000, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B100, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B010, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B001, B000, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B100, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B010, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B001, B000, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B100, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B010, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B001, B000, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B100, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B010, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B001, B000, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B100, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B010, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B001, B000, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B100, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B010, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B001, B000, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B100, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B010, 1,
    B000, B000, B000, B000, B000, B000, B000, B000, B001, 10,

  // this is a dummy element for end of table (duration=0)
    B000, B000, B000, B000, B000, B000, B000, B000, B000, 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
*/

//TheColdest's cube uses pins 0-9, 11-13, I would suggest using

//int LEDPin[] = {16, 3, 1, 15, 4, 6, 14, 5, 7};
// Using pins 0-8 for columns
int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};

//int PlanePin[] = {19, 18, 17};
//using pins 11,12,13 for planes
int PlanePin[] = {11, 12, 13};

// initialization
void setup()
{
  int pin;      // loop counter
  // set up LED pins as output (active HIGH)
  for (pin=0; pin<PLANESIZE; pin++) {
    pinMode( LEDPin[pin], OUTPUT );
  }
  // set up plane pins as outputs (active LOW)
  for (pin=0; pin<CUBESIZE; pin++) {
    pinMode( PlanePin[pin], OUTPUT );
  }
}

// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
  // declare variables
  byte 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
  int ledrow;    // counts LEDs in refresh loop
  int ledcol;    // counts LEDs in refresh loop
  int ledpin;    // counts LEDs in refresh loop

  // 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 ) {
      patbufidx = 0;    // reset index counter to beginning of buffer
      // loop over planes
      for (plane=0; plane<CUBESIZE; plane++) {
        // turn previous plane off
        if (plane==0) {
          digitalWrite( PlanePin[CUBESIZE-1], HIGH );
        } else {
          digitalWrite( PlanePin[plane-1], HIGH );
        }

        // load current plane pattern data into ports
        ledpin = 0;
        for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
          for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
            digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
          }
          patbufidx++;
        }

        // turn current plane on
        digitalWrite( PlanePin[plane], LOW );
        // delay PLANETIME us
        delayMicroseconds( PLANETIME );
      }    // for plane
    }    // while <EndTime
  } while (DisplayTime > 0);        // read patterns until time=0 which signals end
}



CrossRoads

The ULN2003A connects to the 3 cathode layers.
Write the 9 anodes for a layer, turn on its cathode, after 4-5mA turn it off.
Write the 9 anodes for the next layer, turn on its cathode, after 4-5mA turn it off.
Write the 9 anodes for the next layer, turn on its cathode, after 4-5mA turn it off.
Repeat.

During the 4-5mS, be doing something else, like checking for button inputs, incrementing pointers into the array you are pulling data from to create the anode patterns, receiving serial data to update the array with, etc. Which describes the code above if you had fied patterns stored on progmem.

You could use 3 int variable, 1 for each layer, and do two direct port writes for each layer to write the anodes, one more for the cathodes, and just manipulate the data at the bit level in the 9 bits that make up the anode variables.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

TheColdest

CrossRoads, I have the cube made in the exact opposite way, I'm driving the layers with anodes, and the columns/rows with cathodes. SO can I still just reverse what you're saying and have it work? Or do I have to remake a cube?

as with writing the array, like a said before I've never done this before could you give me an example as to how you digitalWrite a specific amount of milliAmps?

CrossRoads

So you have this then.

"how you digitalWrite a specific amount of milliAmps"

You don't - that was a typo on my part, should have been mS, not mA. The current will be limited by the resistors.

Write the 9 cathodes for a layer, turn on its anode, after 4-5mS turn it off.
Write the 9 cathodes for the next layer, turn on its anode, after 4-5mS turn it off.
Write the 9 cathodes for the next layer, turn on its anode, after 4-5mS turn it off.
Repeat.

code snippet - define all the variables, etc. All time elements are unsigned long.
Code: [Select]

void loop()

{

  currentmicros = micros(); // read the time. can be millis also, interval is then 5, vs 5000

  if ((currentmicros - nextmicros) >= interval) // 5 milliseconds have gone by, display the next layer

  {
nextmicros = nextmicros + interval;
// do the cathode/anode driving
// keep track of which layer is being driven
anodelayer = anodelayer +1;
if (anodelayer == 3){ anodelayer = 0;}  // layers 0,1,2
    }
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Go Up