Go Down

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

I've now tried 1K pullups instead of the 5.6K pullups. The behavior is pretty much the same, except that the planes which are "ghosting" (slightly lit up besides the planes that really should be on) are now brighter, but still not fully bright.

I've managed to figure out one more important detail: The planes which are "ghosting" are always planes 2 and 3 (planes 1 and 4 are fine). When I turn all planes off, the "ghosting" planes (2 and 3) turn on at full brightess.

There's definitely something wrong around the anode planes 2 and 3...
Andras
http://iqjar.com

@Hippynerd: My LEDs (the cube itself) is defintely fine. I've tested it throughly before connecting it up to anything. The devil is hiding somewhere in the driver circuit. It seems to me that it's impossible for the software to be wrong as I'm only writing out 3 bytes to the 3 shift registers in the setup() function, loop() is completely empty, there's no sorcery in the software (yet :) )
Andras
http://iqjar.com

The mystery has been solved! It was clear that the problem was around the anode planes, so I started changing the components around that part, thinking that maybe something is defective. I first changed the anode driving shift register, that did not change anything. Than I changed the MOSFETS of planes 2 and 3 and... surprise! Now everything works well. They must have become damaged in the first phase when I had some wrong connections... I truly hope that they did not arrive damaged form Farnell, because 2 bad out of 4 would be very concerning.
Andras
http://iqjar.com

CrossRoads

Congrats! Glad to  hear it wasn't my circuit design ;)
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Ladies and gentleman, it's alive! It works! 100%!
I've even  tried multiplexing and that also works well. At 4 ms multiplexing cycles it looks nice, at 6 ms my eye can already see the "trick" (it starts vibrating). I'll probably aim for 4 ms or lower.

I would like to thank you all for all the help you've given me with this project. I wouldn't have done it in a thousand years by myself, without your answers. My thanks are aimed especially at you, CrossRoads! Your design and your help is something that MasterCard cannot buy (priceless!). Seriously, I cannot thank you enough for having the patience to assist me across the steps of building the cube. If there's any way ever I can hep you back with anything, don't hesitate to let me know!

Now that the 4x4x4 cube works, I'll continue experimenting with writing software for it. After I'll have something usable, I will start putting together a 8x8x8 cube :D I'll start by turning that printed circuit design into something real and transferring the current 4x4x4 cube onto that board, populating only part of it.

@Hippynerd: It's very late at night again here, so I'm going to sleep now, but if you're still interested in that BOM, let me know and I'll gather my notes and write you a comlete list with stuff that you need for the cube and the approximate prices for which I've bought the components.

The 4x4x4 cube is just a test cube, but it's a great success for me. From here to the 8x8x8 cube it's just an immense amount of soldering. The knowledge is in my head and it's all tested now. This is a great day for me :) I've wanted to build a LED cube for 2-3 years now, but I didn't have the necessary knowledge. I've learned a lot from this 4x4x4 test cube. Now I can build the real thing. This is a dream come true.

Thank you all for everything again! I am most grateful for your help.

I'll borrow a camera soon (mine got broken) and I'll be back with a demo video of the 4x4x4 cube in a few days! Also, I make it my goal to thoroughly document the process of building the big cube. I will write a series of articles on my blog about it, which will help other people achieve the same result.

Hooray! :)
Andras
http://iqjar.com

CrossRoads

Can you add on to the 4x4x4 to expand it into the 8x8x8? If so, then you're already 25% done.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

:) I've thought of extending the 4x4x4 cube into an 8x8x8 one... but I've reached the conclusion that I'll start fresh with the big one. With the little one I've learned how to solder nd how not to solder the LEDs together, so it has some minor aesthetic flows. The big one is planned to be a work of art :)
Andras
http://iqjar.com

Hippynerd

That would be great if you could put together a little document. I dont need source or price of parts, but listing the specific parts, and the specific calculations and schematics would be great.
https://sites.google.com/site/rgbledcubes

Hey there, Hippynerd!

Here's the BOM that I've promised, in form of a Google spreadhseet:
https://docs.google.com/spreadsheet/ccc?key=0An4wEyr8LJXZdFR4MjhVXzNBZ2R3WWFkQzFYeWlCa0E&usp=sharing

I tried to make it as complete as possible, so there might be some things there that you don't need. The included prices are estimations of the prices that I have paid myself. My own total is 189$, but in reality it's probably 30% more because from several components I've bought more than needed, just to be safe.
Andras
http://iqjar.com

#204
Feb 23, 2013, 12:03 am Last Edit: Feb 23, 2013, 12:07 am by Un4Seen Reason: 1
I have bumped into a very interesting (and annoying effect) with the LED cube.

Let's say that we turn on one LED on the lowest anode plane, the corner LED which is leftmost and frontmost, like this:

Code: [Select]

   digitalWrite (PIN_SS, LOW); //Start transferring data

   SPI.transfer (B00000000);
   SPI.transfer (B00000001); //leftmost, frontmost corner cathode column
   SPI.transfer (B00000001); //bottom anode plane

   digitalWrite (PIN_SS, HIGH); //Done transferring data


Then we turn that LED off and instead we turn on another LED on the top layer, in the opposite (rightmost, backmost) corner, like this:

Code: [Select]

   digitalWrite (PIN_SS, LOW); //Start transferring data

   SPI.transfer (B10000000); //rightmost, backmost corner cathode column
   SPI.transfer (B00000000);
   SPI.transfer (B00001000); //top anode plane

   digitalWrite (PIN_SS, HIGH); //Done transferring data


The extremely strange thing that happens is that at the moment when we switch from the first LED to the second, for a very brief moment we can see a ghosting (a pale turn-on, but still visible) of a third LED, which is in the newly turned on anode plane but in the old cathode column, in other words in our example, the LED in the top plane, in the leftost, frontmost column.

This becomes very bothering as soon as we start using multiplexing (and that's the goal here). The way it manifests itself during multiplexing is that the image shown in the current multiplexed plane is ghosted in the previously multiplexed plane.

I can't find an explanation for this. It's like the cathode column that was turned on first is not turning off fast enough and when the second anode plane is turned on in combination with another cathode column, for a brief moment the intersection of the new plane and the old column is lit up. But why is the old cathode column not turned off fast enough? Could it be due to some characteristic of the TPIC6B595 shift registers? Some weird latency? Or maybe it's something related to how the data is pushed from one shift register to the next one?

I've tried CrossRoads' suggestion and separated the SS pin for the anode layers from the cathode SS pins. I turned off the anode planes first, then I set up the cathodes and finally I turned the anode planes back on. It doesn't help. The ghosting remains.

I got around the problem in the software by doing this: first I turn off everything by pushing all 0s into all shift registers, then I wait for 100 microseconds (1/10 milliseconds), after that I push the new data into all shift registers (including cathode and anode shift registers). This makes the ghosting go away by allowing the old cathode column to turn off before a new cathode column is turned on in a new anode layer. The only problem is that this approach introduces a barely noticeable tiny flickering in the LEDs when they are constantly on (through multiplexing). It's not a very big problem, because usually the LEDs won't be constantly on and the flickering is very hard to notice, but it still bothers me a little. And I'm curious what is behind that latency in turning off the cathode columns. I'm also worried that if this is somehow caused by some delay in the shift registers, the problem will be more severe in the 8x8x8 cube, where there will be 9 shift registers instead of the current 3 and the flickering will become more visible...
Andras
http://iqjar.com

CrossRoads

Try this: use the TPIC6B595 OE to disable the outputs when switching.

Use direct port manipulation to make it go faster.
So that OE is bit 2 and SS/Latch is bit 3, both on port D:
Code: [Select]

PORTD = PORTD | B00000010; // bring OE/ high
// xfer data
    SPI.transfer (B00000000);
    SPI.transfer (B00000001); //leftmost, frontmost corner cathode column
    SPI.transfer (B00000001); //bottom anode plane
PORTD = PORTD & B11111011; // bring SS/latch low
PORTD = PORDT | B00000110;  //  bring OE/ an SS/latch high
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

So... basically your are suspecting that the latency is introduced by the Arduino itself! Interesting thought!
Does this require any rewiring in the physical circuit? Do I need to connect anything from the Arduino to the circuit?
Andras
http://iqjar.com

#207
Feb 23, 2013, 01:54 pm Last Edit: Feb 23, 2013, 01:57 pm by Un4Seen Reason: 1
I've read about the direct port manipulation and I think I understand what it's about and I have also come to the understanding that OE means output enable. I'm still struggling to understand the following:

1. Looking at the datasheet of the TPIC6B595, I can't find an OE pin on it. How can I set the OE on the shift register? My current understanding is that I should use two pins on the Arduino to control when and how data is transferred to the shift registers: SS and OE, instead of the currently used SS only. The SS should remain connected as it is now, but where on the shift registers is the OE pin?
2. The direct port manipulation section of the Arduino documentation states that PORTD is mapped to pins 0-7, but they only say that it is so on ATmega8, ATmega168 and ATeega328 chips. Mine is ATmega2560. Nobody seems to write anything about which pins PORTD maps to on the Mega2560... I think I would have to disconnect the SS from the current Arduino pin 53 and connect it to where bit 2 of PORTD is mapped. I should connect the OE to where PORTD's bit 3 maps... But which pins are the bits of PORTD mapped to on my Mega2560? :)
3. There are a few things I'm not sure I understand in the example code:
Code: [Select]

PORTD = PORTD | B00000010; // bring OE/ high
// xfer data
   SPI.transfer (B00000000);
   SPI.transfer (B00000001); //leftmost, frontmost corner cathode column
   SPI.transfer (B00000001); //bottom anode plane
PORTD = PORTD & B11111011; // bring SS/latch low
PORTD = PORDT | B00000110;  //  bring OE/ an SS/latch high


a) PORTD = PORTD | B00000010; //bring OE HIGH
   Didn't you mean to bring EO low here (in the beginning, before the SPI transfers)? Isn't the goal to disable the outputs during the next lines, which do the transfer?
b) PORTD = PORTD & B11111011;
   PORTD = PORTD | B00000110;
   There's nothing in between bringing the SS/latch LOW and bringing it back HIGH. Is that correct and is that so in order to keep the time between the point when the data transfer starts and the data transfer ends to a minimum?

Thank you!
Andras
http://iqjar.com

#208
Feb 23, 2013, 04:09 pm Last Edit: Feb 23, 2013, 04:45 pm by Un4Seen Reason: 1
I've found a good resource here: http://www.henningkarlsen.com/electronics/pm_arduino.php
If you open the PDF that corresponds to the Arduino Mega 2560 Rev3, you'll see the port labels there. For example PORTD 0-3 is mapped to digital pins 18-21. I hope that's right. I don't exactly know which revision of the Mega2560 I have, but hopefully the Rev3 mapping will apply to my device too.

The sad conclusion is that if people will try to use my code on other type of Arduinos (not Mega2560), they'll have to figure out where PORTD is mapped on their device.

So now what remains to be figured out is what is OE on the TPIC6B595 shift registers and how I can control it. Also, the questions a) and b) referring to CrossRoads' example code still puzzle me...
Andras
http://iqjar.com

#209
Feb 23, 2013, 11:41 pm Last Edit: Feb 23, 2013, 11:43 pm by Un4Seen Reason: 1
OK, I have figured it out! OE (output enable) is pin 9 (marked G) on the TPIC6B595. So I disconnected the OE pins of the shift registers from the GND (that's how it originally was) and connected them in chain and to the Arduino pin 49. I left SS on Arduino pin 53, as it was before. And I started using this code:
Code: [Select]

   PORTL |= B00000001; //Output enable (pin 49) disabled
   SPI.transfer (cathodeData1);
   SPI.transfer (cathodeData2);
   SPI.transfer (anodeData);
   PORTB &= B11111110; //Latch (pin 53) low - start transfering data    
   PORTB |= B00000001; //Latch (pin 53) high - done transfering data
   PORTL &= B11111110; //Output enable (pin 49) enabled


Unfortunately this doesn't change anything :( The ghosting remains. During multiplexing the ghosting is seen as the previous plane being lit up very lightly at the same time when the new layer is lit up at full brightness.
Andras
http://iqjar.com

Go Up