OP here.
Thank you for responding to my post. To address the points made....
So then, never switch off the LED drivers while the Arduino is powered. This is called "phantom powering" and is overloading the protection diodes in the shift registers. The Mega 2560 and the shift registers should always be powered from the same 5 V power supply.
Ok, thanks for that.
I put a 5V output on my circuit board so, in the future, I can supply the Arduino via its USB input jack from the circuit board (I would ignore the two USB data lines). But right now, as I'm writing the animations for the cube, I need the Arduino connected to my PC so I can upload the new sketches and I need the LEDs to be ON so I can see if my coding works.
After seeing your response, I initially thought I could connect my 5V output to the 5V pin on the Arduino and Bob's your uncle, but then I read that that should NOT be done if the USB jack is being used at the same time - which in my case it would be.
So, it sounds like I have three options. The first is to do lots of plugging and unplugging of wires whenver I want to update my sketch - this isn't really practical because there are many updates during development.
The second is to leave the LEDs ON all the time, as you suggest. This is my preferred option.
The third is to play arround with USB cables. I could take the two data wires in the USB cable from my PC together with +5V and GND wires from my circuit board and combine them into a new USB cable which I could then connect to the Arduino. This would provide power to the Arduino from the same power source as my circuit board while allowing sketch updates to still come from my PC. Except there would be no GND connection to my PC anymore - not sure what the effect of that would be.
Wiring errors aside, "ghosting" is caused by using saturated BJTs to drive the layers. Either you severely restrict the multiplexing speed, or use logic-level FETs instead.
I undertook this project as a learning exercise with a pretty cool endpoint. At the time I started, I'd never heard of Arduino or shift registers, never used a breadboard, transistor or capacitor, never made a circuit board, and never done anything in C. I knew Ohm's Law from high school and I occasionally did some FORTRAN programming a lifetime ago at work. I'd also never heard of a FET or MOSFET.
Now I know a lot more, so my project has been a success. If I were to do it again, I'm pretty sure I would use different components but for now it's working and I hope to avoid having to remake my board. It took me hours and hours and hours make that thing.
Right now there is no ghosting except when I turn on the top layer, the bottom layer also turns on but at a much reduced intensity. I can't for the life of me figure out why that is - I've checked the wiring and the software but I can't find anything - so I'm missing something.
For information, the code snippet that sends information to the cube is shown below:
void displayCube(uint16_t displayTime) {
uint16_t steps = 0;
while (steps <= displayTime) {
steps++;
for (int8_t i = 0; i < 8; i++) {
digitalWrite(SS, LOW);
SPI.transfer(0x01 << i); // Turn on cube vertical layer i.
for (int8_t j = 0; j < 8; j++) {
SPI.transfer(cube[i][j]);
}
digitalWrite(SS, HIGH);
}
}
for (int8_t i = 0; i < 9; i++) { // Turn all layers off once display is complete.
digitalWrite(SS, LOW);
SPI.transfer(0x00 << i);
}
digitalWrite(SS, HIGH);
}
The bottom layer of the cube used to be quite bright when the top layer was on, so I added the i=0; i<9 loop at the end of the above because without it, the bottom layer is ON when the function is exited. This made a considerable difference to the brightness, but didn't entirely get rid of the issue.
For the future, how did you get those images to post? I tried the image tags when I was writing my original post, but when I checked the preview, I didn't see the image so I figured it wasn't working.
That depends on the forward voltage of your LEDs. What colour are they?
I am using blue 5 mm diffuse LEDs. I measured the forward voltage (something else I had never heard of prior to this) at 2.8 V.
In addition to Paul__B's suggestion, it can also be caused by software. Is your sketch using the OE line to disable all outputs until a few microseconds after the latch line has been triggered?
I have posted the software snippet used to update the shift registers above. As noted earlier, I am using the SPI interface. After including the SPI library, initialization of that is shown below.
SPI.begin();
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
Is that a good idea? Why would the transistors in a pair share the collector current, or the base current, evenly between them? I would also suggest logic level MOSFETs. Stp16nf06l for example.
Yes, I agree with you. Without some resistance in there somewhere I wouldn't expect the current flow to be balanced. But, I didn't know that when I started this project, and I had read about / seen examples where other people have used two 2n2222A transistors successfully in a similar manner. According to the datasheet, they can each handle up to 800 ma which is more than than the 560 ma I should get with all 64 LEDs ON in a layer, so I wasn't especially worried about that. I also put them in the same hole in my perf board to encourage current sharing but I know that is no guarantee.
Re MOSFETs, as per my earlier response above, I never heard of MOSFETs when I started this. Thank you for your suggestion though - I have written the number down in case I ever remake the circuit board or if I ever made a RGB cube.