Thank you, CrossRoads It may not seem like it, but there's a lot of work in that dual layer design That's why I would happily share it with anybody who wants to use it. Of course, it would be nice if I could first prove that it's correct by building a board myself. I'm afraid that's going to take months, because soldering the 8x8x8 cube together is a tedious task. But it will be done one day and I'll be back here to inform you about it!

In the meantime, I've finished putting together the circuit today for the 4x4x4 test cube. I've done it on 3 solderless prototyping boards, without any soldering. I hope it will work. It also includes variable resistors to the LED cathode columns, so we'll know exactly just how much current we'll need for the big cube.The 4x4x4 test cube is also soldered together and ready to go. It will take a few more days to write some basic software for it. I'm hoping that in about one week from now I will be able to show you some nice video about the 4x4x4 cube working. Perhaps I'm too optimistic, it will be a miracle if everything will work on the first go. Actually, I'm hoping that at least it will do something, even if not exactly what is expected and I'll be able to debug it. If no LED will light at all, that won't be funny... let's hope it does not happen.

I've started writing the code for the LED cube and I've bumped into a question which might be very basic, but it's also important. An SPI transfer begins by setting the SS pin to LOW and ends by setting it back to HIGH. In between you transfer the bytes with calls to SPI.transfer(). My question is: when exactly does the transferred data become live on the cube? Immediately after it's written with SPI.transfer(), or only after the SS pin is set back to HIGH?

I'm planning on transferring the data of an NxN horizontal plane like this:

You have a loop for the plane, and then 1 more for the layer. As long as the layer shift register is last in line I guess the 2nd part would work. How is cubeData [currentPlaneIndex] organized? as 1 byte/LED, so you have 64 byte altogether representing the cube?

Yes, the N+1 shift registers (where N is the size of the cube in one dimension) are daisy chained, one for the anode planes and N for the cathode columns. The first shift register on the line controls the anode planes and the rest of N shift registers control the cathode columns.

digitalWrite (PIN_SS, LOW); //Start transferring dataSPI.transfer (0xFF); //Turn off the current plane (in fact all planes)(all 1s)digitalWrite (PIN_SS, HIGH); //Done transferring dataThat should be enough to turn everything off, because the value (all 1s) gets into the first shift register and turns off all the anode planes, so it does not matter what is left in the next N shift registers, which control the cathode columns. Or at least, that's how I imagine it...

cubeData is a matrix consisting of NxN bytes. The first index is the plane index, the second index is the row index inside the plane. Each element of the matrix contains one byte, which holds the data for one column inside the horizontal plane. In other words cubeData has NxN elements and each element contains N bits (obviously N cannot exceed 8 ).

Did I understand correctly that when you have X pieces of shift registers daisy chained, the first byte sent out via SPI.tansfer() goes into the first shift register, then the second SPI.transfer() pushes it into the second shift register, and so on?

Tonight I've "fired up" the LED cube. For about 2 hours it did not work at all. Turned out I had one short plus some misunderstanding about how my solderless breadboard's +/- rails work. I've solved these and the cube started working

Unfortunately it doesn't quite work as I would have expected it to. There are some mysteries that I can't explain:1. In theory we have discussed that a cathode column can be turned on by setting its bit to 1. This works as expected. We have also discussed that an anode plane can be turned on by setting its bit to 0. Instead of this it turns on when I set its bit to 1, not to 0. I have followed CrossRoads circuit design 100%.2. When I turn an anode plane on (by setting its bit to 1) some other planes also turn on (one or two planes above/below it), but much more faintly than the plane that actually needs to be turned on.3. When I set all anode planes to off (by setting all bits to 0), the middle two planes turn on at full brightness.

For the anode/layer, writing a 1 into the shift register bit makes the output go low & turns on the PNP to make the anodes High.For each cathode, writing a 1 into the shift register bit to make the output go low and turn on the LED.

Ok, so in order to turn on an LED situated at the intersection of the layer X and column Y, you need to write 1 into the Xth bit of the anode shift register and 1 into the appropriate bit of the appropriate cathode shift register. The main idea is that both the anode and cathode shift registers need to receive a 1 bit in order to turn on the LED. That's nice. It seems that I misunderstood it earlier, but now everything is clear.

I'm not so worried at the moment about how exactly I write those bits into the shift registers, as that seems to be working. On the other hand I'm very much worried about the fact that turning a layer on also turns on 1 or 2 other layers below and/or above it, but not as brightly as the targeted layer. Also, if I turn off all the layers, the two middle layers turn on at full brightness. That's very worrying... seems like a hardware bug...

For testing purposes I have disabled the whole multiplexing and everything that can make debugging hard. My whole loop() function is empty now, I just test things in the setup() function.

The code cannot get simpler than this. There's clearly no error in it and yet anode planes 1 and 2 also turn on in a dim manner next to anode plane 0 which turns on at full brightness, as instructed.

If in the last SPI.transfer(), which sets the anode planes, I transfer all 0 bits, the two middle anode planes (1 and 2) turn on.

Remember that I have a 4x4x4 cube driven by 3 daisy chained shift registers. The first 4 outputs of the first shift register on the line control the 4 anode layers through the MOSFETS and the next two shift registers on the line use all their 8 outputs to control the 16 cathode columns.

At the moment I don't have the slightest clue, what can be wrong, but it smells like a hardware problem to me...Let me know if you suspect anything.

I suspect hardware problem also. If you put a meter on the anodes for the other layers, what do you measure?Perhaps a small pulldown (5k) is needed to keep the anodes low when the PNP is turned off, or a stronger pullup is needed on the PNP bases.

When I'll arrive home tonight, I'll take some current measurements on the other anode layers. I plan to do this by inserting a multimeter between these other anode layers and the drain of the MOSFET which drives them. I hope that's right...

Honestly the thought that some layers turn on in addition to the layer which is really supposed to be on, has planted the feeling in me too that there's something wrong with the pullup resistors that I have today between the gate and the source of the MOSFETS (I have 5.6 KOhm there today). I'll try replacing them with some stronger resistors. I think I have 220 KOhms lying around, I'll give them a try. I hope that's not too much. I wonder if this can also explain why the two middle layers turn on when no layer is supposed to be on.

You mentioned that if I don't manage to solve the problem with bigger pulllups, I might need some pulldowns. From what I've read on Wikipedia, I understood that a pulldown is a resistor which you connect between the gate of the MOSFET and the ground. Is this correct? Also, is it good practice to use pullups and pulldowns combined, or you need to decide which one and use just one?

OK, so I started experimenting with pullups and pulldowns. First I replaced the 5.6K pullups with 220K pullups (I didn't have anything in between 5.6K and 220K). Nothing has changed really... Then I took out the pullups and replaced them with 5.6K pulldowns (instead of having the resistors between the gate and the 5V I put them between the gate and the GND). The situation became worse. Now all the planes are lit all the time.

Some interesting things I've noticed:1.When I plug in the cube, but the Arduino is not connected, it starts up with all LEDs off. But if I put my hand near the 5V rail (I don't touch anything, I just take it 1-2 cm close tot he 5V rail), the LEDs start lighting up. The closer my hand, the more LEDs light up. I take my hand away, the LEDs go off...2. When I unplug the cube, the LEDs stay on for 5-10 seconds (Depending on homw many are lit up). I guess that's because the power supply has some capacitor in it...

If I take out all pullup and pulldown resistors, then planes 1 and 4 are always on at full brightness, planes 2 and 3 behave as instructed. This is kind of the opposite of the case when I have the pullups in place and set all planes to off. In that case planes 2 and 3 are on at full brightness.

It's got to be something related to the pullups/pulldowns, but I can't figure out what is wrong...

I would start by putting the resistors back the way you think they should be (5.6k gate/source I think). Then with the arduino completely disconnected, try to manually light up an LED by connecting the approprate voltage to the appropriate pins to turn on an LED.

I think your case this would be to hook up a ground, and have a couple 5v probes. hook one probe to the gate on one mosfet, and another on the leds anode lead (make sure to connect it before the resistor, so that you are using a resistor in circuit with the LED, or you may blow an LED. If you can manually light each LED one at a time, your LED setup is fine, you need to look at your programming or other circuitry.