Go Down

Topic: 8x8x8 multiplexed LED cube with an Arduino Mega 2560 (Read 117486 times) previous topic - next topic

Un4Seen

Thank you :)
I predict it will be at least two months before I can write all the articles and the software one will be last. If you cannot wait until then, you're welcome to download the current version of my code from here:
http://iqjar.com/download/jar/LED_Cube/4x4x4/LEDQB_v0.4.ZIP

In the software article I'll go into details about how and why I've done things the way I've done them. Until then you can try to figure it out yourself and I can answer your questions, should there be any.

Un4Seen

#241
Mar 24, 2013, 12:46 am Last Edit: Mar 24, 2013, 12:49 am by Un4Seen Reason: 1
Those of you who have been following this thread probably remember that I've build my 4x4x4 test cube on some solderless breadboards and that I've used 3 shift registers in total (1 for the anode planes, using only 4 of its outputs) and 2 for the cathode columns, using all their 8 outputs (16 in total). You may also remember that I had some strange ghosting that I could not fix in the hardware so I got around the problem by introducing a 75 microseconds delay in the software between  the switchwing between two layers.

These days I've ordered the printed circuit that I've designed for the driving circuit and today I have soldered the components onto it, replacing the solderless breadboard solution with a final, soldered one. But I have done something a little bit differently. This time I have used 5 shift registers in total for the very same 4x4x4 cube: 1 shift register for the anode planes and 4 shift registers for the cathode columns, using only 4 outputs from each shift register. So now, instead of only 3, I have 5 shift registers chained.

The good news is that the printed circuit design is flawless. It worked immediately during the first attempt to fire it up.
The bad news is, that the ghosting has become magnitudes worse. Now that 75 microseconds delay between switching layers is not enough anymore. Now I can only get rid of the ghosting by introducing a 600 microseconds delay. That's unacceptable. For an 8x8x8 cube it would probably be around 4-5 milliseconds, which would kill the whole multiplexing mechanism and the cube would flicker like hell. So I have no choice but to figure out what is wrong with the hardware and fix it. What makes things even more complicated is that now the components are soldered in, so it will be more difficult to experiment.

I did draw an important conclusion today. The ghosting appears because the anode layers turn off too slowly, not because the cathode columns turn off too slowly. Or at least that's what the experiments suggest. It also seems that the ghosting becomes exponentially worse with more shift registers chained. Does anybody have any idea at all what could be wrong? Could it be because of those 220 Ohm resistors at the gates of the MOSFETS which turn the anode layers on/off?

Remember the schematic:


I guess I could find that out by shorting the 220 Ohm resistors temporarily. I hope that will not damage the MOSFETS...

Hippynerd

Do you need those 220 resistors on the gates? I am curious about that, as I have a couple cubes that will need fets for switching planes. I have 5k's for the gate/source, and in my testing, I think that the gate drew like 1ma. If the function of that resistor is to limit the current on the arduino, then It didnt seem necessary during my experiments.

Do you have a video of the ghosting, I dont know if I've seen that issue before this thread.
https://sites.google.com/site/rgbledcubes

Un4Seen

#243
Mar 24, 2013, 09:37 am Last Edit: Mar 24, 2013, 09:39 am by Un4Seen Reason: 1
Hi there again! :)

I'm afraid still no video, as my old camera is still broken and I still didn't make the decision to buy a new one. But It's very simple to imagine it with the following test:

First step: write all 0s into all cathodes to keep them all off and write a 1 into one of the anodes to turn it on. As the cathodes are off, no LED will light, so far so good:

Code: [Select]

digitalWrite (53, LOW); //Start transferring data
SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); //All cathodes OFF
SPI.transfer (B00001000); //One anode ON
digitalWrite (53, HIGH); //Done transferring data
delay (600);


Keep it like this for 600 milliseconds (all LEDs OFF even though one of the anodes is ON).

Second step: write a 1 bit into one of the cathodes and a 1 bit into a different anode:
Code: [Select]
http://digitalWrite (53, LOW); //Start transferring data
SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000001); //One cathode ON, the rest OFF
SPI.transfer (B00000001); //A different anode ON, previous anode OFF
digitalWrite (53, HIGH); //Done transferring data
delay (600);


What should happen here is that the LED corresponding to the turned on cathode and to the NEWLY turned on anode should light up for 600 milliseconds. This does happen, but at the beginning of those 600 milliseconds the LED which is in the turned on cathode column and in the OLD anoe plane, also turns on briefly. Tests show that it turns on for 600 microseconds.

BUT here comes the interesting part!
You know that I wrote last night that the only thing that I did differently with the soldered printed circuit compared to the solderless breadboard solution is that now I have more shift registers chained. Well, I just remembered that it's not true! I have also replaced the 5.6K pullup resistors between the MOSFET gates and sources with 47K resistors with the intention to make the circuit consume less power when the anode layers are off. I have the feeling that this is what made the ghosting so much worse. I did not try changing those resistors back yet, but my hunch seems to be backed by the fact that the old ghosting time with the 5.6K resistors was 75 microseconds and the new ghosting time with the 47K resistors is 600 microseconds. The 75/5.6 and 600/47 ratios are both roughly 8, so I guess the ghosting (the anode turn-off lag) increases linearly with the value of those base-gate resistors.

Now comes the hard part! How low can I go with the values of those base-gate resistors without damaging anything and without having my circuit eat too much power in passive mode? Even if I go really low, I doubt that I'll be able to make the ghosting go away completely. For that to happen I think some other solution is needed. But what, I wonder?  :~

Un4Seen

Interesting, very interesting...
I've put back the 5.6K resistors in parallel with the 47K ones. This should result in an overall resistance of 5K between the gates and sources.
Now I can get away with a delay of only 10 microseconds between switching. Perhaps in the solderless solution there was no proper contact somewhere and the resistance was actually higher than 5.6K. Or perhaps 5K is near the limit where the resistors are weak enough for the ghosting to go away. I'll try desoldering the 47K ones and soldering some 3.3K ones instead. Hopefully that will make everything OK.

Un4Seen

I've soldered in the 3.3K resistors between the gates and sources of the MOSFETS. The result is not what I was expecting. Now the ghosting seems to show up a bit more differently. Now when a cathode is on and multiplexed, not just the previous layer is ghosting, but all the layers. The ghosting is dimmer now, but instead of only one ghosting layer, now all the layers are ghosting. Also, no matter how much software lag I introduce, it's not going away. I need a wall to hit my head against  =(

Hippynerd

I dont know if it was this thread, or another, or what, but I think I remember reading about toggling the OE or CLR to help prevent ghosting or something similar.
Sometimes when you can see what its doing, you can make a better guess, but even then, this stuff is doing things way beyond our ability to see.
https://sites.google.com/site/rgbledcubes

Un4Seen

Hi, Hippynerd! :)

Yepp, it was this thread.
I did try to experiment with that (disabling output while transfering data), did not help.

You're right, this is doing stuff which is a bit hard to understand, you're certainly right about that :) But at least now I knwo for sure that the ghosting is related to the parts of the circuit around the MOSFETS. And I know that the problem is that the anode layers are not turning off fast enough. I've also found out that the gravity of this lag (of the anode planes) depends on the value of the resistors between the gate and source legs of the MOSFETS. The higher the resistor value, the longer the lag. Maybe the value of the 220 Ohm resistors between the anode driving shift register and the gates of the MOSFETS might also have a say in it, I did not experiment with that yet.

I'm kind of hoping CrossRoads is still reading this. He might be the only one who understands what is going on.

Hippynerd

I think it was crossroads that said that the gate/source resistor helps the fet switch faster (this is where the math gets scary, with all that RDS on, and gate capacitance and stuff factor in).

I've also read that it helps prevent ringing, which can damage and prematurely wear out your FET.

I dont understand the reason for the resistors that are on the shift registers that dont connect directly to LEDs.

I was also thinking, that if you are going to run your LEDs at less than 1ma, you could use 74hc595s instead of tpic shift registers. You could even go up to 8ma each LED.

I suspect he will chime in, but its sunday, he might take a break from the forum to you know, do real life things once in a while...
https://sites.google.com/site/rgbledcubes

Un4Seen

Yeah, real life tends to need attention :P

God forbid giving the LEDs 8mA! I'm running them at around 1.5 mA and they are still way too bright!

I've done some further experiments and I can now explain as clearly as possible the ghosting effect, through some short pieces of code. No multiplexing involved, nothing funny, just plain old turning on/off cathodes and anode layers using SPI transfers:

Code: [Select]

void loop ()
{
    //Step A: turn on all the 16 cathodes and turn off all the 4 anodes
    digitalWrite (53, LOW);
    SPI.transfer (B00001111); SPI.transfer (B00001111); SPI.transfer (B00001111); SPI.transfer (B00001111); //All cathodes ON
    SPI.transfer (B00000000); //All anodes OFF
    digitalWrite (53, HIGH);
    delay(1000);
   
    //Step B: turn off all the 16 cathodes and turn on 1 anode
    digitalWrite (53, LOW);
    SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); //All cathodes off
    SPI.transfer (B00000001); //One anode layer ON
    digitalWrite (53, HIGH);
    delay(1000);
}


The expected behavior here is that no LED turns on ever, because there isn't any moment of time when both a cathode and an anode layer are simultaneously ON. Well, unfortunately that's not what happens. The LEDs in the layer which is ON at step B keep lighting up briefly and dimly after each full cycle (step A + step B). I'm not sure whether this happens between step A and B or between step B and A, but it only happens once during a full cycle. My bet is that it happens between step B and A (and not between A and B) because the anode layers turned on at step B don't turn off quickly enough. But I'm not sure that this is what really happens because I tried adding some code both between step A and B and between step B and A which turns off everything (all cathodes and all anodes) and waits for the turn-off to happen (software delay). No matter how much delay I added, the blinking didn't even get shorter, it remained the same. I even added 600 ms delays (which is extremely much!), nothing changed.
The way I see it, what happens is that when you turn on an anode layer, some small amount of current gets into that layer and it somehow stays there until it can get away somehow. It only seems to be able to get away through the LEDs when some cathodes are turned on. And while it gets away through the LEDs, the LEDs light up. This is my best explanation so far.

Hippynerd

recently, I've been working on a 4x4x4 cube that uses transistors to switch lines (not planes, lines, one plane is line * cubesize. Instead of using 4 transistors to swtich 4 planes, I using 20 transistors to switch 16 lines of LEDs (16 lines = 4 planes).
To do this, I have to cascade the transistors, so that you turn on 1 transistor, to turn on another bank of 4 transistors.
When writing the code, I cycle bits through the anodes pins, but I dont need to turn them off or clear them. i originally wrote the it so that it turns on the 2 that it needs, then delay, then turn off all transistors. I recently changed it to just turning off the second transistor (leaving the first transistor on, until its time to turn it off, and the next one on.)

I dont know if it makes any difference, but it seems like its must be better that way. Im wondering if your ghosting issue has something to do with 2 transistors being on at one time, when maybe only one should be on? are you turning off one layer before turning on the next?

https://sites.google.com/site/rgbledcubes

Un4Seen

When multiplexing. I only turn off a layer before turning on the next one because of this ghosting. In the past, when I had the 4x4x4 test cube's circuit on solderless breadboards, turning the previous layer off and aiting 75 microsecs before turning the next layer on, helped. But in theory, there should be no need for this.

Un4Seen

I've just tried again one of CrossRoads' older suggestions: ground the anode layers through some resistors. I used 5.6K. No change. The ghosting persists :(

Un4Seen

Some other things I've tried tonight:
1. Added one more 3.3K resistor in parallel with the existing one between the MOSFETs' gate and sources.
2. Shorted the 220 Ohm resistor at the MOSFET gate.

None of these made any difference.

One more thing I found: the dim flickering (or ghosting or whatever) appears between step B and A in my previously shown code, just as I thought. In other words, the anode planes are just not shutting down quickly enough, so when some cathodes are switched on, the LEDs briefly turn on in the previously turned on anode plane (which is turned off before or simultaneously with the cathodes being turned on). I'm saying before or simultaneously, because if I turn the anode plane off and turn on the cathodes immediately (right after), then I get some quite visible ghosting-flickering. But I've tried to add a delay between step B and A, like this:

Code: [Select]

    //Step B: turn ON one anode plane, keep all cathodes OFF
    digitalWrite (53, LOW);   
    SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); //All cathodes OFF
    SPI.transfer (B00000001); //One anode plane ON
    digitalWrite (53, HIGH);
    delay(1000);
   
    //Delay step (C): turn everything OFF (all anodes and cathodes)
    digitalWrite (53, LOW);
    SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); //All cathodes OFF
    SPI.transfer (B00000000); //All anode planes OFF
    digitalWrite (53, HIGH);
    delayMicroseconds(25);
   
    //Step A: turn all anode planes OFF, turn one cathode ON
    digitalWrite (53, LOW);
    SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000000); SPI.transfer (B00000001); //One cathode ON
    SPI.transfer (B00000000); //All anode planes OFF
    digitalWrite (53, HIGH);
    delay(1000);


With that intermediate step C, after which I wait 25 microseconds, letting the previously turned on anode plane turn off, the flickering-ghosting (which occurs at the intersection of the anode plane turned on in step B and cathode column turned on in step A) is much less visible. Barely visible. But here's where it gets interesting! I tried increasing that 25 microseconds delay, even up to 100.000 microseconds, but the situation didn't get any better compared to when the delay was just 25 microseconds. However, if I reduce the delay to 0, then the flickering-ghosting gets much worse.

What is going on here?  :smiley-roll:

Un4Seen

When I started feeling that the ghosting problem just beats me and felt like giving up, somebody really nice has sent me a link to an article written by a guy who was struggling with the same issue:
http://scriptkiller.de/en/a55/computer_electronics/10%25C2%25B3_(10x10x10)_led_cube/
I don't know why I haven't found this article myself, because I did search a lot for ghosting in LED cubes. Anyway, thank you, Robert, for sending this to me!

The guy who had the same ghosting issue states the following:
Quote
"Eliminating Ghosting
Problem: If high-side layer switches are (almost) unloaded, they will take a long time to completely switch off (due to capacitances at the drain of the FET, I guess and in the wiring).
It can clearly be seen that the voltage does not reach 0V during one multiplexing cycle. Thus some LEDs may be switched on very dim although they should not. The solution is to add a load-resistor of 1kOhm between the drain of each high-side P-FET and ground. At 5V there will only be 5V/1kOhm = 5mA flowing through each of these load resistors, but the effect is magnificient"


Now, this solution in itself is nothing new. It's kind of what CrossRoads has suggested many days ago. I tried it back then and it didn't work. I tried it today, it didn't work either. BUT it has lead me to an acceptable solution. The reason it did not work in the past or today is that I expected this resistor to magically make the excess current vanish instantly. Obviously, that's not the case. You have to give it time. In other words, you have to combine this hardware solution with the software solution of switching everything (all anodes and cathodes) off and waiting a bit. Luckily I was inspired enough today to try this.

So, I added 1K resistors between the drains of the MOSFETS and ground (in other words I've grounded the anode layers through 1K resistors). It's important to really use 1K resistors, not higher, my experiments have shown that higher value resistors are beneficial, but don't work as well as 1K resistors. Unfortunately this means 5mA power usage per anode layer in passive mode (that's about 40 mA for a 8x8x8 LED cube), but it seems that it's the price that needs to be paid. After adding these resistors I've added an intermediary software step between switching layers, which turns all anodes and cathodes off and waits a little (as little as 30 microseconds).

After this the ghosting was almost completely gone, but I've noticed a second ghosting, out of sync with the one that I've just eliminated. This second ghosting was extremely dim, but it was there. The solution I've found for this second one was to add 10K resistors between each cathode column and the positive 5V rail. Unfortunately in a 8x8x8 LED cube with 64 cathode columns this adds another 32 mA power usage in passive mode. I guess it's something I'll have to live with. I can't say I'm happy about all this passive power usage, but I don't know a better solution.

With all these resistors added, the ghosting is almost almost almost completely gone. There is still an extremely faint, dim ghosting, but it is almost impossible to notice. You have to look at the LEDs from their top, where they give off most light and in perfect darkness and even so you can barely see it. It's not perfection, but it's quite close. In a working LED cube with real animations there will rarely be darkness. The light of the lit LEDs will make this last trace of the ghosting unnoticeable.

I hope this helps everybody who might bump into the same problem.
Thank you guys, for helping me!

Go Up