1,000 LED Control

I want to make a 10x10x10 single color LED cube, with a good, very smooth frame rate and the most detailed brightness control I can get. I've never used an arduino before (or played with electronics much) and was wondering if there was any chance of it being able to keep up with that. What is the highest overall throughput you can get with whatever arduino and set of pins (and circumvention of arduino code functions) is best? Can the mega manage much more or do those extra pins make them slower?

I'll be running animation and audio visualization/audio processing software from my laptop as I'm pretty sure it can't do all that by itself. Eventually I'd like to find something that can, without any computer. In an ideal world, a minimum of something like 60 frames per second and 64 brightness levels. Maybe I should just send serial directly from a USB chip into the multiplexer? Reprogram it to remove any signal management? I can't imagine that not being fast enough....

lets do some math to get some things clear

1000 LEDS with 64 levels => 1000 bytes (OK a bit overkill but stuffing the bits costs time)
you want 60 frames per second * 1000 bytes = 60000 bytes per second to process
Serial works in bits => 60000 *10 = 600.000 bits per second => that will be very difficult for Arduino to handle (read not)

Proposal
make 16 levels of brightness, => 4 bits per LED => 2 LEDS fit into one byte.
1000 * 16 levels => 500 bytes
the framerate back to 15/seconds
15 * 500 = 7500 bytes = 75000 bits per second [baudrate of 230400 could work]

Another option is to define higher level commands e.g. PLANE CIRCLE CUBE SQUARE and let the arduino find the bits to switch
Then the communication would not be the overhead...

I wasn't saying I expected 60 fps and 64 shades, I was saying those were my ideals. I expect/plan to get worse performance (that is, lower frame rate and shade count) if I use an arduino.

I don't understand what you're saying in some places.. why you mentioned bytes and bit stuffing where you did, 'read not', and both of the last two lines. Also not sure how you got 600,000 bps instead of 360,000, or 75,000 instead of 60,000. Could you explain? Remember I don't know much about the arduino. Where would this bit stuffing come in? Why does the baud have to be so much higher than the bit rate for a simple multiplexer?

Edit:
And how many/what pins would you use to get the highest total bit rate possible?

Here are two other possibilities for resolving the bit rate problem:

  1. Use some form of data compression, e.g. just send the differences between the current frame and the previous frame.

  2. Use a Teensy instead of an Arduino. The Teensy has a direct USB interface which is in theory capable of higher bit rates than the serial port of the Arduino. [Disclaimer: I have never used a Teensy.]

However, you still need to design a way of driving the LEDs that can cope with the large amount of data concerned. The easiest solution technically would be to use PWM LED driver chips such as the TLC5940, although this would be rather expensive (less so if you can use the SMT version). By clocking 8 chains of 8 of them in parallel and using direct port access, you might be able to get sufficient throughput.

Also bear in mind that 1000 bytes of frame data will take almost half the RAM on a atmega328p. You won't have enough RAM to display the current frame while receiving the next. So you'll either need to use an Arduino Mega, or reduce the cube size e.g. to 8x8x8, or reduce the resolution to 4 bits per LED as rob suggests.

I wasn't saying I expected 60 fps and 64 shades, I was saying those were my ideals. I expect/plan to get worse performance (that is, lower frame rate and shade count) if I use an arduino.

Did the math to show you what can be done with Arduino

why you mentioned bytes and bit stuffing where you did

64 shades of grey use 6 bit so from every byte two bits are unused. That means I can "stuff" the info for 4 LEDS (4*6=24bits ) in 3 bytes.
This technique is used in base64 encoding/decoding.

that will be very difficult for Arduino to handle (read not)

In theory the Arduino could be able to handle it, in practice I expect it will be too much as there is little time left to process the incoming data in time. I expect that low level assembly is needed to handle the level of dataflow mentioned.

Also not sure how you got 600,000 bps instead of 360,000, or 75,000 instead of 60,000.

To send one byte over a serial line the Arduino uses on average 10 - 11 bits (measured in time), it uses a bit to signal start of the transmission, then 8 bits for the byte and then 1-2 bits (in terms of time) until the next byte comes in. As a rule of thumb one can say to send 1 byte over serial one uses 10 bits. Better use 11 (or even 12) if you want a defensive estimate as serial communication is asynchronouos so you never know when thenext byte will come ...

Where would this bit stuffing come in?

See above, but bear in mind that bitstuffing takes time and the unstuffing of the bits should cost you less time than sending one byte. If it takes more time to decompress datat than to send extra data compression makes no sense. Only a good experiment will give you indications how for your specific project compression vs speed will behave.

Why does the baud have to be so much higher than the bit rate for a simple multiplexer

The reason to use a higher baudrate gives you time to process the data. if you need to transport 75000 bytes per second and you use 75000baud you will have no time left for doing something with the data (assuming a 100% usage of the bandwidth !!). The Arduino needs some time to do the math to switch the right LED.
To get some feeling,

  • write a sketch to measure how much time it takes to send 115200 bytes at 115200 baud. In theory 10 seconds (with start stop etc bits)
  • write a sketch to measure how much time it takes to switch a LED on/OFF 10000 times.

Also bear in mind that 1000 bytes of frame data will take almost half the RAM on a atmega328p. You won't have enough RAM to display the current frame

I think you IF you can shiftOut the current frame into shift registers like the 74HC595 - http://www.arduino.cc/en/Tutorial/ShiftOut - fast enough you could reuse the 1000 bytes for receiving the new frame as the shiftregisters work as "memory" of the current frame. That would be a project in itself to test the feasability of this...

Could you explain?

See above, hopes it is more clear now.
Advice: please spend some time on the tutorial section and the reference section of the Arduino site as you will learn there a lot of the possibilities and constrains of the Arduino and its language.

Succes!

I'm curious what kind of software :

I'll be running animation and audio visualization/audio processing software from my laptop

is capable to create 3D animation ?
There is a link: http://www.elcojacobs.com/shiftpwm/ , it says limit 768, w/ 75 fps. So you should be o'k with 60 fps.

I saw that you linked to my library here.
In the ShiftPWM support topic I posted a matrix version of the library, which is not up on my website yet.
If you make a layer of 100 LED's as the columns in the library and 10 rows to alternate between layers, you can use that version to drive your cube.
Milamber used it to drive 1024 LED's, see his topic as well. On a 328p, thats about the limit, due to memory restraints.

Magician:
I'm curious what kind of software :

I'll be running animation and audio visualization/audio processing software from my laptop

is capable to create 3D animation ?
There is a link: http://www.elcojacobs.com/shiftpwm/ , it says limit 768, w/ 75 fps. So you should be o'k with 60 fps.

The shift register thing isn't really that helpful for me, I don't think... unless I'm missing the idea. I need complete simultaneous control over everything. I've pretty much decided to just multiplex out the signal from the USB controller, no arduino.

Also... I haven't written it yet :3
Most of that comes after it's built.

I haven't written it yet :3
Most of that comes after it's built.

Make sure you are not designing something you can't drive.

Can move up a couple dollars to an ATMega1284 based design and have a lot more RAM to play with; having a more IO is nice but not critical here if you are going to just use SPI to send data to the PWM controllers quickly. The extra IO will let you have more chip select lines tho so can address the shift registers directly.
I can picture 10 IO pins with 10 current sources for the rows, with a '5940 to sink the current for the column for a layer.
10 pins to select the OE for the '5940 for the active layer.
10 pins to select the CS for the 10 '5940s.
3 SPI pins
2 serial pins.
Hmm, that's 35.
Okay, so two shift registers for the first set of 10 pins. Just walking a 1 across to enable a row at a time.
so 27 IO. '1284 will give you lots of RAM, all the needed IO, minimal external hardware.
Shift register will control a 200mA current source per row.