Getting the TLC5940 to output 25kHz PWM (Silent efficient PWM 4wire fan control)

Hi all,

Question: What is the code to make the Uno & TLC5940 output a 25kHz signal?

What I've researched:
Using formulas from USING TLC5940 TO GENERATE VARIABLE FREQUENCY PWM SIGNALS USING ARDUINO - OxGadgets, it appears setting TLC_PWM_PERIOD = 320 and TLC_GSCLK_PERIOD = 0 will make 25kHz.
However, I don't see how to easily modify the code to make TLC_PWM_PERIOD = 320.
According to macegr of Running a TLC5940 at lower resolution - LEDs and Multiplexing - Arduino Forum, I can do it by altering how I pulse the BLANK line, but that I have to "do it on my own."
Also smithr of Shift PWM Problem - Programming Questions - Arduino Forum seems to know how to do it, but I've not been able to reach him.

My Goal: Silent power efficient independant speed control of 14 PWM 4-wire DC 120mm fans.

Thank you for helping me on this issue!

What's the current draw on those? TLC5940 does not have lot of current drive:

· Drive Capability (Constant-Current Sink)
– 0 mA to 60 mA (V The TLC5940 is a 16-channel, constant-current sink CC < 3.6 V) LED driver.
– 0 mA to 120 mA (VCC > 3.6 V)
· LED Power Supply Voltage up to 17 V

Mega has 16 PWM capable outputs. Might be better off using those to drive transistors for sinking current thru the motors.
Google "Arduino PWM secrets" for changing the PWM frequency.

Check out this thread, but primarily this post:
http://forum.arduino.cc/index.php?topic=155089.msg1176136#msg1176136

CrossRoads,

What's the current draw on those? TLC5940 does not have lot of current drive:

The Arduino/TLC5940 idea has nothing to do with the supply voltage/current for the fan motor; instead, it sends a signal to the internal circuitry of a PWM fan via the magical 4th wire, instructing it to switch on and off many times per second (25kHz, to be precise). Fan power comes from a separate 12V power supply.
However to answer your question, the current draw of a PWM fan's control wire (by specification) is --> Absolute maximum current sourced: Imax = 5 mA (short circuit current)
So the TLC5940 appears perfect for driving anything in this range (LEDs, PWM motors & servos, logic switches, etc).

...Might be better off using those to drive transistors for sinking current thru the motors.

Keep in mind I want this system to be very efficient ... that is, cut out waste heat overhead of analog electronics. Technically there are some analog electronics within the PWM fan, but they are waaaaaaaaaaaaaaay more tweaked for efficiency than I could EVER hope to make by slapping some FETs & caps together. To me it's simple... leave all the switching/sinking R&D stuff to the PWM fan makers, and I'll just assemble the black box for controlling it with some simple duty cycle code & 25kHZ pulses. ...Ok, maybe not "simple", but hopefully someone here can get me some code (I am a NOOB and this is my first Arduino project!).

afremont,

Unless I've missed where that post talks about changing the Arduino fosc from 16MHz, that thread is apparently only for adjusting the arduino's timing (like from Arduino Playground - TimerPWMCheatsheet).
In other-words, I think I can easily make the Uno spit out 25kHz, but it's the expanded outputs via the TLC5940 that I must make 25kHz. My idea is by no means novel, so I just must find the Arduino/TLC5940 library mod that already addresses PWM fans. No?

How about a link to these
PWM 4-wire DC 120mm fans
I am not sure what it is you are controlling.

chillteas:
Question: What is the code to make the Uno & TLC5940 output a 25kHz signal?

With 4096 steps? That would require a 102.4 MHz clock which is well beyond the maximum frequency of the 5940 and AVR processor.

How PWM steps are you hoping to have?

CrossRoads,

My Goal: Silent power efficient independant speed control of 14 PWM 4-wire DC 120mm fans.

The fans are any high frequency PWM DC computer case fans based on the spec Motherboard Form Factors

Here's one of many such fans --> http://www.cougar-world.com/us/products/fans/vortex_pwm.html
My favorite is the http://www.coolermaster.com/xresserver01-DLFILE-P13021803113d6e-F1303150006ac49.html

Coding Badly,

To get well within the frequency of the Uno, I know the trade-off for higher frequencies will be a lower step resolution.
This application is only speed control, so it only needs a few... 640 steps would be way more than enough.

I don't think it's the Uno's limits I must be concerned with (Uno can output up to 62.5kHz according to Arduino Playground - TimerPWMCheatsheet). Instead, it's how to make the Uno talk the right talk to the TLC5940 so the TLC5940 can output the 25kHz. From other posts, it appears I just need to set TLC_PWM_PERIOD = 320 to get 25kHz. Only confusion I have is it appears the library's formulas are mostly fixed constants... so I'm just searching for how to change one of the constants.

I'm sure my answer is simple, but it probably only lies with someone who's very familiar with the TLC5960/Arduino library... So, any of you Guru's, please tap in here!

chillteas:
This application is only speed control, so it only needs a few... 640 steps would be way more than enough.

Which requires exactly 16 MHz. Given the fact that the processor can execute exactly one operation (or fewer) per clock tick, how do plan to toggle the GSCLK signal at 16 MHz?

I don't think it's the Uno's limits I must be concerned with (Uno can output up to 62.5kHz according to Arduino Playground - TimerPWMCheatsheet).

Which is 256 times slower than you need. Do you understand the difference between "MHz" and "kHz"? Do you understand how the TLC5940 works?

I'm sure my answer is simple...

Maybe. But first you need to get your expectations in line with what the hardware is capable of doing.

Coding Badly,

Which requires exactly 16 MHz. Given the fact that the processor can execute exactly one operation (or fewer) per clock tick, how do plan to toggle the GSCLK signal at 16 MHz?

I was just trying to communicate to you I think my project is not beyond the AVR's ability... that 25kHz works with the UNO up to a mathematical maximum of 640 steps. I don't yet know how many steps I need, but it's a heck lot less than 640... just a few steps to take some temperature inputs and then talk the TLC5940 into changing the duty cycle for the respective channel at 10% increments. That is, fan speed 10%, 20%, ... 90%, 100%.

Which is 256 times slower than you need. Do you understand the difference between "MHz" and "kHz"? Do you understand how the TLC5940 works?

I need to shoot square 25kHz at the fan... That I know. No, I don't fully understand the TLC5940... it's a black box to me, but I understand it can expand UNO's capability to 16 channels (needed for 14 independant fans). Without using a TLC5940, I only have 2 maybe 3 channels from the UNO. Problem is (yes, because I don't understand theTLC5940... which is why I'm posting here) I don't know if the UNO must put out 25kHz to make the TLC5940 put out 25kHz. I had assumed the TLC5940 had it's own timer. I guess my assumption is wrong, but even so I didn't think it was a deal-breaker to make the UNO put out 25kHz...

But first you need to get your expectations in line with what the hardware is capable of doing.

Aside from the TLC5940, you now have me worried the UNO can't put out 25kHz itself like it appears in Arduino Playground - TimerPWMCheatsheet. I hadn't questioned the UNO's capability because it seems many people have successfully altered it's output frequency to drive one or two PWM fans anywhere from 16kHz to 32KHz. Have I fundamentally missed what those Arduinian's are doing?

Now I have NOT yet bought the UNO or TLC5940. If these components aren't correct to acheive my Goal, would you please suggest what is? I only require it be a digital 25kHz output (not analog).
-Thanks for your help in advance!

chillteas:
No, I don't fully understand the TLC5940... it's a black box to me, but I understand it can expand UNO's capability to 16 channels...

16 PWM channels with per channel current limiting. Correct.

Without using a TLC5940, I only have 2 maybe 3 channels from the UNO.

Or maybe six channels.

I had assumed the TLC5940 had it's own timer.

It does not. You are responsible for providing a clock signal on the GSCLK pin. You are also responsible for asserting BLANK at the correct time. The two commonly available TLC5940 libraries handle both of those tasks.

I don't know if the UNO must put out 25kHz to make the TLC5940 put out 25kHz.

Each clock tick advances a counter in the TLC5940. The counter stops (essentially freezes) at 4095.

So, if you use the TLC5940 library reconfigured for 25 kHz, the counter is incremented every 40 microseconds. The count goes from zero to 4095 (4096 steps) which comes out to about 164 milliseconds. That gives a cycle time of 164 milliseconds or a 6 Hz PWM cycle rate.

Which means you have to do two things: 1. Increase the clock rate. 25 kHz output from the Arduino equates to an essentially useless PWM cycle rate. 2. Decrease the number of steps. It is simply not possible to get 4096 steps with a PWM cycle rate of 25 kHz.

...then talk the TLC5940 into changing the duty cycle for the respective channel at 10% increments...

10 steps. For that you need to reconfigure the TLC5940 library for a 250 kHz clock output and reconfigure (or recode) the TLC5940 library to assert BLANK when the count reaches 9. Bear in mind that asserting BLANK has to be performed every 640 cycles of the AVR processor clock. That is a significant overhead which will not leave much processor time for the rest of your application.

I only require it be a digital 25kHz output (not analog).

That is a lie. You also stated...

...take some temperature inputs...

...which presumably also includes calculations.

If these components aren't correct to acheive my Goal, would you please suggest what is?

For outputting 16 PWM signals at 25 kHz with 10 steps an Uno + TLC5940 will most certainly work.

As for the rest of your goal, who knows. You haven't told us enough to offer an opinion.

Coding Badly,

Thank you for your informative and revealing answers.

For outputting 16 PWM signals at 25 kHz with 10 steps an Uno + TLC5940 will most certainly work.
As for the rest of your goal, who knows. You haven't told us enough to offer an opinion.

Stop. Back up. The cart is getting before the horse... My original question stands valid as-is, "What is the code to make the Uno & TLC5940 output a 25kHz signal?" (My Goal is just extra information at this point). Simply put, besides fosc = 16Mhz, the Uno is moot if the TLC5940 can't put out 25 kHz in the first place. Although the posts I've mentioned suggest it's possible, the research I've listed seems to conflict. That is, the main equations of the TLC5940 seem to prevent 25kHz from ever happening. If TLC_PWM_PERIOD could actually be 320 then 25kHz could be output, but the TLC_GSCLK_PERIOD equation appears to make it an impossibility since TLC_GSCLK_PERIOD is defined as an integer:

So if anyone here were to actually know a working answer to my question, then it would mean they know how to get beyond my interpretation of the TLC5940's equation limitations... And THAT is exactly what I seek FIRST.

"I only require it be a digital 25kHz output (not analog)" is true. It by know means suggests I don't need other basics, like inputs. From that commanding sentence, the words "Digital" "25kHz" and "(not analog)" are key, which mean I don't want any other transistors, caps or other analog stuff between the TLS5940 output and the fan's PWM input. I make emphasis here because most all other threads in this forum about HF PWM fans get replies trying to suggest an analog solution which defeats the purpose of a HF PWM fan. Forgive my directness.

chillteas:
So if anyone here were to actually know a working answer to my question...

Did you read reply #11? 250 kHz GS clock. Pulse BLANK every 10 clock ticks.

Coding Badly,

... 25 kHz output from the Arduino equates to an essentially useless PWM cycle rate...
...the TLC5940 library for a 250 kHz clock output and...

Forgive me, the 250 kHz threw me and I thought you were just being facetious...

If it can be done, great! But so far I'm told one of two things:

  1. Yes, it's been done (but no one cites success or code examples).
  2. No, the max you can get out of the TLC5940 is 3.9kHz because the smallest value of TLC_GSCLK_PERIOD is zero.

Unfortunately, I'm not yet versed on Arduino code to know how to do what you suggest. That's why I'm looking for the code... as in it's already been done... a proven "success" if you will. With what I've seen it seems like I could code the Uno to jump through hoops, but only to get snuffed when it comes to the TLC_GSCLK_PERIOD (ref: Adjusting TLC5940 libraries to run different frequencies/values - OxGadgets).

Since I'm only at the feasibility stage of this project, I must only determine if it can be done. My pseudo-pseudo control code is: Temperature control by 6 thermister inputs --> microcontroller --> 14 PWM fans. Besides 6 zone temperature control (four 2-fan, two 3-fan zones), each fan independently speeds up/down to keep any resonance noises down and silent operation to a maximum. The needed thermodynamic sweet-spot is at a low power fan rpm range which is solar powered (note: extreme heat conditions (high rpm) will switch to line power, but power switching is outside of the Uno's responsibility).

So if you are truly saying YES it can be done, then I'll get the Uno and TLC5940.