Running a TLC5940 at lower resolution


I'm not sure if I started of with the correct IC, but I'll see if I can get there or not.

Basically, what I need is a PWM controller that can run at a frequency upward of 25kHz. Ideally something that I can 'control' between 25k and 75k.

Now, a TLC5940 can run with a maximum clock signal of 30MHz. With 12 bit resolution, or 4096 steps, the PWM frequency is 7.3kHz. Way too low for what I'm looking for.
I don't need all that resolution, I'm more than happy with 10 bit, or even 9 bit if necessary. At 10 bit, I am around 30kHz, which is what I would be happy with for the worst case solution.

So my question is, is there a way to make the controller run at a lower resolution? If not, do any of you know of a solution that can work?
The Arduino is only used to receive PWM duty requests through serial interface, and then sends those requests to whatever external PWM generator is attached.


is there a way to make the controller run at a lower resolution?

Sorry but no.
I think you have the wrong chip.

I thought so...

Any ideas on chips that can handle it?

Actually, since you control the grayscale clock and the PWM counter reset line, you can. Basically instead of counting up to 4095 before pulsing the BLANK line, you count up to 1023. Then just send 12-bit brightness values, of which you only use 10 bits (0-1023).

You'll need to make this happen on your own, though, instead of just using the TLC5940 library.

However, the Arduino definitely can't generate 30MHz, so if you want that to happen you'd need to make some kind of separate circuit that runs at 30MHz and sends a BLANK pulse once every 1023 counts.

That's actually a good idea. So after a 'blank' the TLC starts all over again?

I guess it would be possible to use one of it's own inputs to trigger the 'blanc' pin as well. Because the Arduino will not be able to keep up with counting a 30MHz clock.

Not sure what you mean by that. There is no 30MHz clock unless you provide one. You don't have to run it that fast it is just the fastest you can. You still have to clock data synchronously with the clock so there is no point providing a clock so fast you can't output the data fast enough
What maceger is suggesting is just stopping the
PWM signal short, you will still need to clock all the data in including the bits that you don't use.

Mike: the TLC5940 has separate data and grayscale clocks. It's actually possible to have a completely independent grayscale + blank generator circuit. I know you've used the TLC5940 as part of a matrixed solution, and so have I, and that's where you do need to carefully sync the data and grayscale generators. However it's not required....

Thanks macegr, you set me of in the right direction. I wanted to keep this thing as simple as possible, and knew the library works, so didn’t want to change any of that. No need to fix things that work :wink:

So I went of and got a 30MHz oscillator crystal and hooked that up to GSCLK on the TLC. So not using the wire coming from Arduino Digital 3. Together with the library, everything is working properly. Of course you do loose port 3 if you don’t extract those parts form the library.
The PWM frequency is now ~7.3kHz.

Now to make the TLC reset faster, I have to pulse the BLANK pin faster. To get to a frequency of 30kHz, it needs to reset every 1000 oscillator pulses. Ideally, I want to be able to control the frequency. Worst case, a potentiometer; best case, digital via RS232.
Adding another clock (or a 555 for variable frequency) with the requested frequency was the easy solution. But both clocks start to run out of sync. This is not a really big problem, but in my case, as I’m both logging requested duty and performing PID on them, this wouldn’t give me smooth log files.

So what I needed was something that is fast enough to count oscillator pulses, and then output a very short pulse on BLANK. The TLC his main job is to count those pulses, so why not exploit that?

As I only needed 10 PWM outputs, there are 6 left on the TLC. I can then use one of those to create an on-time that is the same as the period of the requested PWM frequency. When that period is over, the output goes high. So a positive edge detection circuit is all I need to give a pulse on BLANK.

I tried various solutions, going from neat and tidy to a clutter of components. All solutions either gave a pulse too short (not resetting), or too long (decreasing the maximum possible duty request). In the end, I ended up with a simple circuit. Maybe a bit large PCB wise, but it is the most stable solutions of everything I had laying around.

A transistor is used to inverse OUT15. Both the OUT15 and the inverse are than added together. Because of the slow response of the transistor, the inverse stays high slightly longer. It is during that time, that it makes a pulse.
The ‘Custom_Arduino_BLANK’ is needed to get the TLC going. The Arduino has to output a pulse on it to start the TLC. Of course this pin can also be used to actually blank the outputs as well.

I was a bit concerned about the length of the pulse influencing the maximal achievable pulse duty. But in fact, it runs perfect up 100%. The edges aren’t perfectly straight after 95%, but I guess that’s the same when using it ‘normal’.

Blue is OUT15, red is BLANK.

The code I use is very easy.

#define osc_freq 30000
int pwm_freq_req = 30;
int pwm_freq_req_pulse = 972;

pwm_freq_req_pulse = osc_freq / pwm_freq_req;
Tlc.set(15, ( pwm_freq_req_pulse - 28 ));
pwm_pulse_per_duty = (float)pwm_freq_req_pulse / pwm_duty_max;

pwm_duty_req_pulse_c1 = pwm_duty_req_c1 * pwm_pulse_per_duty;

The factor 28 is there to take into account of the time delay of the whole circuit. So in fact, I make OUT15 stop slightly sooner, so that the BLANK pulse happens exactly goes high at the right time. This will probably depend on all the components used, and I will check this again once everything is running on a PCB instead of a bread board.

Don’t know if anybody else will ever need this, but at least it’s possible to do this.

Very cool to see it working correctly...honestly I wouldn't have guessed that you would successfully get 30MHz working reliably, since that's close to the quoted maximum. I guess TI might be underspeccing a little bit, you might be able to overclock :slight_smile:

Perfect forum post...ask question, get answers, then actually do remaining work instead of demanding entire solution, and then post final solution. :slight_smile:

Well, if the datasheet says max 30MHz, it SHOULD do it! ]:smiley:

I know that forums like these often get cluttered with questions, but people actually demand solutions. For me it’s always fun to find out how it works, or to find how to make it work.

The only problem I have with this set-up, is that it’s a little buggy to run from the USB port. The TLC (and the rest) only get’s 4.5V. Due to the components never giving perfect pulses, but always with an up/down slope, the BLANK pulse sometimes doesn’t go high enough to reset the TLC. And once it misses a beat, it goes dead…

Running of a proper supply luckily does solve this.