Hey everyone,
I'm posting this because i hit a little bit of a brick wall in my programming.
I've got 11 layers controlled by two daisy chained registers, all LEDs on one layer have common cathodes.
As for the "columns", they are (all 121 of them) controlled by another load of daisy-chained registers.
As my registers are 8 bit i adresse columns as single numbers.
My problem is that I don't know how to code it so that i can adresse a single LED at a time... thus making the other part of this project very complicated
I would really appreciate a little help
If you need more info feel free to ask I'll give all i can
Hey, thanks for the quick responses
Here is a capture of the schematics of the control board in attachments,
The 74hc595 registers are daisy-chained up to give me the 121 outputs i need for the cube columns and then I have another two that are also daisy-chained to run the 11 transistors the control the layers.
I need to code my arduino mega so that it can interface with this board via the input and using 2 clocks, and 2 serial outputs give me the possibility to singly adresse any LED in the cube.
Hope that clarifies and thanks again for your help
I would have an array of 121/8 = 16 bytes per layer, and do simple multiplexing where you send out 2 bytes to turn off the current layer driver, send out the 16 bytes, turn on that layer, and then watch millis() or micros() to repeat for the next layer.
I would also send the data using SPI.transfer[array element] with SPI divisor clock set to 2 for 8 MHz clock.
I have no idea how to use SPI outputs, and I did not think of Daisy-chaining all 17 shift registers...
I would like to ask what way could I maintain the brightness of the cube if not using 11 to 1 multiplexing ?
Is there a better component to use for this function rather that the shift register?
Why specifically one resistor per column is one 'bigger' one per layer not enough ?
Thanks for saying about decoupling caps I totally forgot about them, they are between VCC/+5V and the pin right ?
I think i would make the layers common anodes. I would use pnp transistors to switch the layers, or maybe p-channel fets, and use tpic6c595 shift registers to sink current from the columns.
A "bigger" series resistor on the common/layer led pins is not the same as a series resistor on each column pin. For one thing, the brightness will vary depending on how many leds are lit in the layer. Secondly, no two leds have the the exact same forward voltage, even if manufactured in the same batch. This will lead to uneven brightness and uneven life between the leds.
"I would use pnp transistors to switch the layers, or maybe p-channel fets, and use tpic6c595 shift registers to sink current from the columns."
That would allow higher bursts of current than you can achieve with HC595, thus higher brightness.
Falawk_Iring_Rogue:
I can no longer change the way the cube' LEDs are connected so columns have common anodes and layers common cathodes.
The classic mistake when building a cube. What I can't understand is, the effort it takes to build an 11x11x11 cube is enormous. Completing just one layer teaches you that. So why do people not take just a little more time to research how it is going to be driven, before they commit themselves to all that work?
Falawk_Iring_Rogue:
I do like the idea of using the tpic6c595 shift registers, could I use them on the layers ?
If I do it this way what transistors should use ?
No, I don't think so. Too much current flows through each later. 121 leds @ 20mA each would be 2.4A, which is too much for even tpic6a595, and too much for your 2N2222. But if you are sticking with 74hc595 to drive the column anodes, then 15 chips can only source around 1A in total, which is still too much for tpic6a595 or 2n2222, so you will need to look at alternative transistors. I would suggest some power fets with logic-level gates, in which case they can be driven by 74hc595 and there would be no advantage to tpic6*595.
By the way, should it not be 16 shift registers for the columns and another 2 for the layers? EDIT: ah, sorry, you are using an Arduino pin for that last column.
Falawk_Iring_Rogue:
What value resistor is needed before each column of LED? (approximately)
Normally this would depend on your leds, but in your case the limiting factor would be the 74hc595 chips. Their max current of 70mA across all outputs means you need to limit the current to around 8mA per led, which means series resistors of around 500R, but it might be less because the '595 may not be able to maintain its outputs at the full 5V when current is at maximum. Also the transistors will drop a little voltage, depending which type you use. Sorry that's not a very definitive answer. Crossroads is building a 9x9x9, so perhaps he has more advice on this.
The classic mistake when building a cube. What I can't understand is, the effort it takes to build an 11x11x11 cube is enormous. Completing just one layer teaches you that. So why do people not take just a little more time to research how it is going to be driven, before they commit themselves to all that work?
Sadly I'm only one member in groupe for this project and the person building the cube did not exactly listen when I told him to wait a bit ...
I can easy change the transistors used that is not a problem, what do you recommend here? Only higher current drain?
I would like to run the transistors with two shift registers (if possible 74hc595 to reduce the difficulty of the odder to get the components)
I'll have the possibility to run each columns via resistors that's also doable.
My main problem is how do I actually get the arduino to control this system?
Falawk_Iring_Rogue:
I can easy change the transistors used that is not a problem, what do you recommend here?
There are many that will be suitable. Unfortunately anything in a TO-92 package (like I assume your 2N2222 is) probably won't take the current. So I would suggest a power MOSFET with a logic-level gate and thru-hole connections for easy soldering. It will only have to deal with 5V and 5A at most, so almost anything in a TO-220 package should be ok. One example would be IRL520. You can connect their gates directly to the shift register outputs, but also put a 10K pull-up resistor from the gates to 5V.
Falawk_Iring_Rogue:
My main problem is how do I actually get the arduino to control this system?
The hardware interface between the Arduino and shift registers is easy. Just 3 lines from the Arduino, the MOSI (pin 11 on Uno) and SCK (pin 13 on Uno), plus any other pin you like as the "latch" line, but its common to use the SS pin (pin 10 on Uno) for this. Also that extra pin for the 121st led column of course!
The software representation of the cube is also easy, you just need an array of 11 x 16 bytes. Each byte has 8 bits to control 8 leds and can be sent out with SPI.transfer() (except that last bit that you will use to set the Arduino pin controlling the 121st column).
Tricky part could be programming the animations. If you attempt to represent each "frame" as a pre-defined data block, its going to require a lot of storage, so you will probably have to use an SD card. Alternatively you could perform the animations programatically (i.e. write code functions for each of the animation sequences you want). This will use much less space but requires more programming skills.
Like I said above, when time for an update, send out anode, send out cathode, hold until next time check.
See if you can follow the looping and the data structures below.
void loop(){
currentMillis = millis(); // maybe use micros() for more finetuning of duration vs 1mS, 2mS, etc
if ((currentMillis - previousMillis) >= onDuration){
previousMillis = previousMillis + onDuration; // set next time check
x=x+1; // next layer select
if (x==11){x = 0;} // reset layer count, 0 to 10
digitalWrite (ssPin, LOW);
// setup up anode information
SPI.transfer (dataArray[(x*16)+0]); // first 8 columns 0, 16, 32, 48, etc
SPI.transfer (dataArray[(x*16)+1]); // 2nd 8 columns 1, 17, 33, 49, etc
SPI.transfer (dataArray[(x*16)+2]); // 3rd 8 columns 2, 18, 34, 50, etc
SPI.transfer (dataArray[(x*16)+3]);
SPI.transfer (dataArray[(x*16)+4]);
SPI.transfer (dataArray[(x*16)+5]);
SPI.transfer (dataArray[(x*16)+6]);
SPI.transfer (dataArray[(x*16)+7]);
SPI.transfer (dataArray[(x*16)+8]);
SPI.transfer (dataArray[(x*16)+9]);
SPI.transfer (dataArray[(x*16)+10]);
SPI.transfer (dataArray[(x*16)+11]);
SPI.transfer (dataArray[(x*16)+12]);
SPI.transfer (dataArray[(x*16)+13]);
SPI.transfer (dataArray[(x*16)+14]);
SPI.transfer (dataArray[(x*16)+15]); 16th 8 columns - 15, 31, 47, 63, etc. only 1 bit used
// setup cathode information
// maybe these 2 first depending on daisychain
SPI.transfer (cathodeArray[(x*2)+0]); first 8 layer drives 0,2,4,6,8,10,12,14,16,18,20
SPI.transfer (cathode[(x*2)+1]); next 3 layer drives 1,3,5,7,9,11,13,15,17, 19,21
digitalWrite (ssPin, HIGH);
} // end time check
} // end loop
byte cathodeArray[] = {
0x00, 0x01, // cathode layer control info, 1 layer on at a time
0x00, 0x02,
0x00, 0x04,
0x00, 0x08,
0x00, 0x10,
0x00, 0x20,
0x00, 0x40,
0x00, 0x80,
0x01, 0x00,
0x02, 0x00,
0x04, 0x00,
};
I am looking for a cheaper equivalent of the transistor as I can't find it here in France
Thanks for the code example, I did understand it I just don't quite understand the values you used ....
Why 0x80 /0x * * .. I don't understand how this works as I've never used it before.
I'll be redesigning the control circuit that has the registers on it
As for coding the animations, I'm running on a Arduino mega 2560 so I do have a bit of memory
i'm currently working on a converter to create the "register" codes from coordinates.