here is the Loop for the LED Routine
}//***end loop***end loop***end loop***end loop***end loop***end loop***end loop***end loop***end loop***end loop***end loop***end loop
void LED(int level, int row, int column, byte red, byte green, byte blue){ //****LED Routine****LED Routine****LED Routine****LED Routine
//This is where it all starts
//This routine is how LEDs are updated, with the inputs for the LED location and its R G and B brightness levels
// First, check and make sure nothing went beyond the limits, just clamp things at either 0 or 7 for location, and 0 or 15 for brightness
if(level<0)
level=0;
if(level>7)
level=7;
if(row<0)
row=0;
if(row>7)
row=7;
if(column<0)
column=0;
if(column>7)
column=7;
if(red<0)
red=0;
if(red>15)
red=15;
if(green<0)
green=0;
if(green>15)
green=15;
if(blue<0)
blue=0;
if(blue>15)
blue=15;
//There are 512 LEDs in the cube, so when we write to level 2, column 5, row 4, that needs to be translated into a number from 0 to 511
//This looks confusing, I know...
int whichbyte = int(((level*64)+(row*8)+column)/8);
// This next variable is the same thing as before, but here we don't divide by 8, so we get the LED number 0-511
int wholebyte=(level*64)+(row*8)+column;
//This will all make sense in a sec
//This is 4 bit color resolution, so each color contains x4 64 byte arrays, explanation below:
bitWrite(red0[whichbyte], wholebyte-(8*whichbyte), bitRead(red, 0));
bitWrite(red1[whichbyte], wholebyte-(8*whichbyte), bitRead(red, 1));
bitWrite(red2[whichbyte], wholebyte-(8*whichbyte), bitRead(red, 2));
bitWrite(red3[whichbyte], wholebyte-(8*whichbyte), bitRead(red, 3));
bitWrite(green0[whichbyte], wholebyte-(8*whichbyte), bitRead(green, 0));
bitWrite(green1[whichbyte], wholebyte-(8*whichbyte), bitRead(green, 1));
bitWrite(green2[whichbyte], wholebyte-(8*whichbyte), bitRead(green, 2));
bitWrite(green3[whichbyte], wholebyte-(8*whichbyte), bitRead(green, 3));
bitWrite(blue0[whichbyte], wholebyte-(8*whichbyte), bitRead(blue, 0));
bitWrite(blue1[whichbyte], wholebyte-(8*whichbyte), bitRead(blue, 1));
bitWrite(blue2[whichbyte], wholebyte-(8*whichbyte), bitRead(blue, 2));
bitWrite(blue3[whichbyte], wholebyte-(8*whichbyte), bitRead(blue, 3));
}//****LED routine end****LED routine end****LED routine end****LED routine end****LED routine end****LED routine end****LED routine end
ISR(TIMER1_COMPA_vect){//***MultiPlex BAM***MultiPlex BAM***MultiPlex BAM***MultiPlex BAM***MultiPlex BAM***MultiPlex BAM***MultiPlex BAM
//This routine is called in the background automatically at frequency set by OCR1A
//In this code, I set OCR1A to 30, so this is called every 124us, giving each level in the cube 124us of ON time
//There are 8 levels, so we have a maximum brightness of 1/8, since the level must turn off before the next level is turned on
//The frequency of the multiplexing is then 124us*8=992us, or 1/992us= about 1kHz
PORTD |= 1<<blank_pin;//The first thing we do is turn all of the LEDs OFF, by writing a 1 to the blank pin
//Note, in my bread-boarded version, I was able to move this way down in the cube, meaning that the OFF time was minimized
//do to signal integrity and parasitic capcitance, my rise/fall times, required all of the LEDs to first turn off, before updating
//otherwise you get a ghosting effect on the previous level
//This is 4 bit 'Bit angle Modulation' or BAM, There are 8 levels, so when a '1' is written to the color brightness,
//each level will have a chance to light up for 1 cycle, the BAM bit keeps track of which bit we are modulating out of the 4 bits
//Bam counter is the cycle count, meaning as we light up each level, we increment the BAM_Counter
if(BAM_Counter==8)
BAM_Bit++;
else
if(BAM_Counter==24)
BAM_Bit++;
else
if(BAM_Counter==56)
BAM_Bit++;
BAM_Counter++;//Here is where we increment the BAM counter
switch (BAM_Bit){//The BAM bit will be a value from 0-3, and only shift out the arrays corresponding to that bit, 0-3
//Here's how this works, each case is the bit in the Bit angle modulation from 0-4,
//Next, it depends on which level we're on, so the byte in the array to be written depends on which level, but since each level contains 64 LED,
//we only shift out 8 bytes for each color
case 0:
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(red0[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(green0[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(blue0[shift_out]);
break;
case 1:
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(red1[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(green1[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(blue1[shift_out]);
break;
case 2:
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(red2[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(green2[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(blue2[shift_out]);
break;
case 3:
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(red3[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(green3[shift_out]);
for(shift_out=level; shift_out<level+8; shift_out++)
SPI.transfer(blue3[shift_out]);
//Here is where the BAM_Counter is reset back to 0, it's only 4 bit, but since each cycle takes 8 counts,
//, it goes 0 8 16 32, and when BAM_counter hits 64 we reset the BAM
if(BAM_Counter==120){
BAM_Counter=0;
BAM_Bit=0;
}
break;
}//switch_case
SPI.transfer(anode[anodelevel]);//finally, send out the anode level byte
PORTD |= 1<<latch_pin;//Latch pin HIGH
PORTD &= ~(1<<latch_pin);//Latch pin LOW
PORTD &= ~(1<<blank_pin);//Blank pin LOW to turn on the LEDs with the new data
anodelevel++;//inrement the anode level
level = level+8;//increment the level variable by 8, which is used to shift out data, since the next level woudl be the next 8 bytes in the arrays
if(anodelevel==8)//go back to 0 if max is reached
anodelevel=0;
if(level==64)//if you hit 64 on level, this means you just sent out all 63 bytes, so go back
level=0;
pinMode(blank_pin, OUTPUT);//moved down here so outputs are all off until the first call of this function
}//***MultiPlex BAM END***MultiPlex BAM END***MultiPlex BAM END***MultiPlex BAM END***MultiPlex BAM END***MultiPlex BAM END***MultiPlex BAM END
//*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE
//*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE
//*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE
//*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE