Large TLC5940 project help needed!

Hi all, some of you may have seen this in the IRC chat, my issue is I want to illuminate balloons using RGB leds to create pattern, here are a few videos to show my concept...

This is what I want the balloons to do...

As you can see there are a lot of balloons to control, about 350 minimum but we want as many as we can...

The issue I am having is we want it to fade through colours and I can't really get any further than fading 3-5 RGB LEDs (which obviously translates to 9-15 PWM channels.

TLC5940 Library - Google Code Archive - Long-term storage for Google Code Project Hosting.

This is my code which makes random choices but it could be modified to do other things.

Can anyone help me solve the scalability issue?

#include "Tlc5940.h"
#include "tlc_fades.h"

int red = 2048;
int green = 4095;
int blue = 3893;

byte current_r[5], current_g[5], current_b[5];
TLC_CHANNEL_TYPE channel = 1;

void setup() {
  Tlc.init();
  Serial.begin(9600);
}

void loop() {
    
  if (!tlc_updateFades()) {
    
    fadeRGB(channel, byte(random(0, 255)), byte(random(0, 255)), byte(random(0, 255)), 0, 500);
    channel++;
    if (channel >= 3) channel = 1;
    
  }
  
}

boolean fadeRGB(TLC_CHANNEL_TYPE channel, byte r, byte g, byte b, uint32_t wait, uint32_t duration) {
  
  if (!rgbIsFading(channel)) {
  
    TLC_CHANNEL_TYPE redChannel = (channel * 3) - 3;
    TLC_CHANNEL_TYPE greenChannel = (channel * 3) - 2;
    TLC_CHANNEL_TYPE blueChannel = (channel * 3 ) - 1;
    
    tlc_removeFades(redChannel);
    tlc_removeFades(greenChannel);
    tlc_removeFades(blueChannel);
        
  }
    
    uint32_t startFade = millis() + wait;
    uint32_t endFade = millis() + wait + duration;
    
    int fromRed = map(int(current_r[channel-1]), 0, 255, 0, red);
    int fromGreen = map(int(current_g[channel-1]), 0, 255, 0, green);
    int fromBlue = map(int(current_b[channel-1]), 0, 255, 0, blue);
  
    int toRed = map(int(r), 0, int(0xFF), 0, red);
    int toGreen = map(int(g), 0, int(0xFF), 0, green);
    int toBlue = map(int(b), 0, int(0xFF), 0, blue);
  
    TLC_CHANNEL_TYPE redChannel = (channel * 3) - 3;
    TLC_CHANNEL_TYPE greenChannel = (channel * 3) - 2;
    TLC_CHANNEL_TYPE blueChannel = (channel * 3 ) - 1;
  
    tlc_addFade(redChannel, fromRed, toRed, startFade, endFade);
    tlc_addFade(greenChannel, fromGreen, toGreen, startFade, endFade);
    tlc_addFade(blueChannel, fromBlue, toBlue, startFade, endFade);
    
    current_r[channel-1] = r;
    current_g[channel-1] = g;
    current_b[channel-1] = b;

}

boolean rgbIsFading(TLC_CHANNEL_TYPE channel) {
  if (tlc_isFading((channel * 3) - 3) && tlc_isFading((channel * 3) - 2) && tlc_isFading((channel * 3 ) - 1)) {
    return true;
  } else {
    return false; 
  }
}

To control 350 RGB LED's you would need 66 TLC5940's, a lot of power and a lot of money .-)

I think that it would be better to use more than one Arduino board, and do a modular design for a project of this magnitude.

Also note that the SPI bus used to control the TLC5940 is only intended to work over rather short distances.

Yeah I know it's going to be expensive. I have about £2000 to spend and I will need more than one arduino bit the problem is at the moment it doesn't seem possible to control more than about 3 chips from an arduino before it goes mega slow.

I was hoping some or might be able to suggest some alternatives to my current system. I should be able to use 40 tlc5940 chips in a chain if the arduino can keep up bit what's going on but that is the problem. It can't keep up so it ends up very very slow. Even if I put 9 chips per arduino it will struggle

Well, 688*3 = 1152 LEDs, or 384 RGB LEDs. That's six of those RGB LED Matrix parts. The only difference here is that your LEDs are far away from the matrix controller.

If this were my project, I'd make a protoboard that implements an 8x8 matrix part, except with a four-wire header instead of an RGB lamp, at each junction. Then put the RGB lamp at the end of a long four-wire cord. Then I'd put some header pins on the protoboard and run the whole affair from one of the several 8x8 RGB LED Matrix solutions that exist. (Six copies of the whole matrix setup if you really need that many balloons.)

If you need more power for long runs to the LEDs, the protoboard could incorporate the required transistors, but that might not even be necessary if your maximum run is only five meters of 16-gauge wire, and your site is a party-atmosphere darkened room as shown.

The downside is that with 595-driven matrices, you only get about twenty shades, not 4095 shades, for each LED. Fading from color to color is a little less smooth, but probably still quite effective.

Do you really need to control each balloon individually ?

lets say you have combination of RGB values, and call it a channel, and the channels values are choosen randomly as in your example, a single channel would require 3 pwm pins.

A channel could be wired to 9 different balloons in series, giving you 9 different colors just by rearranging how the rgb lines are connected. Maybe balloon1 R=R, G=G, B=B, balloon2 is R=R, G=B, B=G. If these balloons were distributed randomly within the structure, it would be very difficult to see that they were changing at the same time/rate, add in the noise of the other 341 balloons changing color, and it would be impossible.

if 3 pins can run 9 balloons in a single channel, then you would need 39 separate channels at 3 pins each, or 117 pwm pins. You could get this with 9 Arduino Mega's and no additional hardware. Just have each Mega outputting fade values on each of its pwm pins.

Using TLC5940's you would need 8 of them.

You could cut this down further by doubling to 18 balloons on a channel.

384 ShiftBrites is about 916 GBP...you could spread out the fade processing by using multiple Arduinos or maybe one FPGA. I think that calculating 30 or 36 bit fades of RGB colors for a lot of LEDs is going to be slow on an 8 bit processor no matter what.

After thinking about it some more, I forgot that you need different levels to accommodate for the brighter red or blue elements in the led's and to balance the colors.

But it may even simpler.

If you have 3 Arduino Mega's, one putting out 8 different random red values, one with 8 blue, and the other with 8 green. Thats 512 possible combinations, more than the number of balloons you have. Running those 24 lines up each branch as a bus, and plugging each balloon into a different combination of pins would give you the variety you need (ie R1,G7,B4 R3,G2,B8 etc)

Just a warning, building the 595 + transistor approach on breadboard or perfboard is a punishment! Even if this is a one time show, the one who has to build it will go nuts. There's just way to many wires :frowning:

But that's what Seeedstudio Propaganda is for. :slight_smile:


The thing is we wanted to be able to control the exact colours not just randomly fade them, this is just test code that I am using here.

Do you think it may be quicker for the computer to calculate the fades and the arduino just sets the colour and acts as interface between processing and the TLC5940?

hey yo!

intuitively i would say, it is cheaper/easier if a PC sends simple instructions to the arduinos via USB, and the arduinos would just push proper data to the TLC5940-s and set the control lines appropriately...

can u say something about the available bandwidths?

  1. arduino to a chain of TLC5940-s (how many single pwm value changes r possible per second? is it faster to talk to the first TLC than talking to the last TLC in the chain (it seems like u have to step through the whole chain - or did i get it wrong? how do u address a certain TLC?)?)
  2. PC to arduino via USB (115200 bits/sec and 3 bytes per instruction (error detection bits included) would suffice for 4800 instructions per second - theoretically)
  3. PC light control program to all arduinos (how many USB transfers can be done at the same time?)

but maybe more complex instructions would be better (e. g. when the USB sub-system is jammed or if 115200bits/sec r not enough...)... depends on the frequency of pwm value changes...

bye
arne

Where did you get the 8x8 Matrix for Eagle Cad please? I have been searching for one of those.

I can't give you all the details of my experience because it relates to a commercial project, but I will make some observations.

With careful coding it is possible to get the Arduino (we naturally use LEDuino's because they are our product) to talk to 10 TLC5940's, and it is possible to make the variations quite smooth. To do this our programmer calculated the next required set of values and placed them in a single buffer in memory which was then clocked out to the TLC5940's.

The limitation is not speed but RAM capacity. Our practical limit is actually 9 TLC5940's because of the size of the SRAM in the ATmega168. A move to the ATmega328P with 2K SRAM would certainly get us back to the 10 TLC5940 mark. Of course the ATmega644P used in the Sanguino would give us even more room.

Speed isn't so much of an issue, neither is SPI performance. I cannot recall the exact figures as it is some time since I had a CRO On the SPI output but I think we were able to get the LEDuino to clock out at about 4MHz, fast enough, and whilst it has been suggested that SPI Only works over short distances our LEDuino/LED strip combination is around 3 metres long, about 10 feet.

Make sure you strip out any code that is not absolutely essential - in particular this means anything to do with serial I/O such as loading tables or data over the USB port. If you must do that then blank the entire display whilst you do.

My largest single installation so far has around 850 strips each about 30cm long with a TLC5940 per strip. The strips are arranged with a maximum of 10 per LEDuino. So the installation has some 85, maybe more, LEDuino's in it.

I am sorry I can't expose the code we are using, but it is actually written in the Arduino language, there are no special libraries, no interrupt handlers or whatever, it was written by a special effects designer, not a professional programmer.

Good luck!

John