## Manipulate multiple (5) individual MB PWM and output multiple PWM (5)

18 posts / 0 new
Author
Message

After my dead end on DDS & Tach signal I need to go the PWM method.

This is not necessarily a problem, it is only a pitty since the other code was doing its work quite fine.

However now I need to go the PWM way and I have a couple of questions and the way to follow to come to a working product.

Questions:

1. Motherboard PWM should be working between 21kHz to 28kHz, to be able to successfully determine what PWM is generated by the MB I should probably measure the frequency output by the MB. The idea that I have to do so is measure the time between 2 rising sides of a PWM signal. Using average of a couple of measurements to be sure. IS this a good method to get the MB frequency?

2. There are 5 fans connected, so I would like to measure each PWM individually. to do so I was thinking of using the pin change interrupt. What I am wondering is, how does this behave if lets say 2 pins change at the same time?

```ISR (PCINT0_vect)
{
uint8_t changedbits;

changedbits = PINA ^ portbhistory;
portbhistory = PINA;

if(changedbits & (1 << PA0))
{
/* PCINT0 changed */

}
if(changedbits & (1 << PA1))
{
/* PCINT0 changed */

}
}```

Furthermore, the fans state in their PDF that the preferred output frequency is 25kHz.

The 16 bit timer is used for the input PWM handling. This leaves me with 4 PWM channels in the AVR OR doing it software PWM, like DDS as I made with TACH only then with a adjustable pulse width instead of adjustable frequency. What would be your opinion?

I will split my project in:

1. Get the frequency of the MB by the rising edges of the PWM;
2. Get the PulseWidth of the MB signal;
3. Generate a PWM signal (software?) on 25kHz to spin the Fan;
4. Combine 1 & 2
5. Combine 4 & 3

Any thoughts on the above?

This is a project that would suit something like the attiny and have one chip per fan.
I'd be using input capture for the measurements. Using pin change - determine the resolution you want then do the numbers. Not impossible, but you're flying close to the wind performance wise. You can measure each input individually as you dont expect the pulse width to change too rapidly and the frequency should be constant. As for generating pwm, then choose a device with enough hardware pwm channels. Dds has no application here.

I am already looking at a splitted solution, because of the fact that I am stuck with the single solution.

The chip I am looking at atm is ATtiny441/ATtiny841. These could do 2 in and 2 out (never used PWM in the chip so I do not know if it can generate 2 PWM like I want from 1 timer, same kHz but different Pulse Width).

Otherwise such one for each fan separate. This would mean 1 have 1 timer for the input and 1 timer fro the PWM.

The PWM required is not constant, so I will be calculating per second the average and use that per second. To stabilize the output. Furthermore I will use the system that when the change is too small PWM is not adjusted (too avoid throttling).

For the moment I build a single solution in my 644 since I do not have a 441 on my desk.

input capture is different than my proposed method if I am correct. This is going one level lower, at pin level and not at pin group if I am correct. When I do 2 channels per chip that would still not be a problem (if I recall there are more than 2 interrupt vectors on pin lvl).

Is it recommended to use an separate crystal for this task?

Unless you're doing uart comms, the application should be able to tolerate the internal oscillator.

If you want some degree of precision with measuring the pwm, then input capture is the choice. By all means try the pcint or external ints, but you'll want to be familiar with counting processor cycles. Again, do the numbers. You haven't told us what sort of resolution you want with the incoming pwm - this is going to determine the path you can take. For example, if you wanted 8 bit resolution for a 25kHz pwm signal, that equates to 156nS or around two instructions at 16MHz - basically not achievable easily, at least directly. Even 4 bits of resolution is 2.5us which is a bit touch and go. So the direct method really isn't going to work too well methinks. A roundabout method is to use a RC filter and feed the resulting analog voltage into the ADC. Then you can easily measure 4 fans and still have plenty of cycles to burn.

I think the frequency rescale is not a valid solution to the noise problem. The temperature is regulated by fan frequency. If the dynamics of the system is great enough, it will increase frequency to adjust for the rescale.

Noise is a mechanical issue. Building an enclosure to contain and absorb the noise, while permitting air flow will be a more direct solution.

It all starts with a mental vision.

What I read so far is that ISR will not be accurate enough and the determination of the PWM demodulation needs to be done within the main loop?

Concerning resolution (can't answer right now)

What I was thinking to do it (just theoretical):

- Read in main the rising side, falling side (pulse width in t), rising side (rising to rising = period in T) so f can now be calculated.

- f is only of interest in the first 10 measurements (to get an average), after that it is set.

PWM creation I could do with something like this:

http://nl.farnell.com/texas-inst...

(just an idea)

Which leaves me to the fact to do this reading on 5 fans which cannot be done in 1 avr with a 16 bit timer.

Still just a thought...

Dont need any interrupts. Just read the pulse widths one at a time: Wait for the input to go hi, clear the timer, wait for the input to go lo, read the timer. Set the pwm. Go to next input.

Imagecraft compiler user

Sebas06 wrote:

After my dead end on DDS & Tach signal I need to go the PWM method.

Why did that not work as you expected ?

Sebas06 wrote:

However now I need to go the PWM way and I have a couple of questions and the way to follow to come to a working product.

Questions:

1. Motherboard PWM should be working between 21kHz to 28kHz, to be able to successfully determine what PWM is generated by the MB I should probably measure the frequency output by the MB. The idea that I have to do so is measure the time between 2 rising sides of a PWM signal. Using average of a couple of measurements to be sure. IS this a good method to get the MB frequency?

Err, nope.

If the control is PWM, you need to measure DUTY CYCLE, not frequency. See :

http://en.wikipedia.org/wiki/Com...

This avoids needing fast code, and fan speed values to not change quickly.

Sebas06 wrote:

Furthermore, the fans state in their PDF that the preferred output frequency is 25kHz.

The 16 bit timer is used for the input PWM handling. This leaves me with 4 PWM channels in the AVR OR doing it software PWM, like DDS as I made with TACH only then with a adjustable pulse width instead of adjustable frequency. What would be your opinion?

If you want to Drive alternate Fan levels, based on the Readings you get from above, then the simplest and least jitter will be HW PWM with an 8 bit timer, clocked at 6.4MHz.

Find a AVR with 4 PWM channels, or use multiple devices.

Software PWM at 25KHz is going to be tricky, and coarse.

Even 16 steps, will need 400KHz INT service rates, 32 Steps needs 800KHz etc.

For the moment I build a single solution in my 644 since I do not have a 441 on my desk.

So why not work on getting one channel working on the uC, then port the code to the Tinies.

Use one Tiny for each fan and be done with it.

JC

Quick reply before going to office...

That is indeed the plan after reading about frequency needed if combined.

Only problem is that 644 only has 1 16 bit timer (in comparison to the tiny who have 2 -> 1 for input and 1 for the output in my case)

I can build it in the 644 but only as half solution (probabbly displaying by UART the "wanted" values to check if it is correct)

Both who-me and myself have tried to bring attention to the problem of measureing pwm at 25kHz. I don't think you realise the challenge.

Of course in the original Thread, (I'm still not sure what was said above that wasn't already said in the original Thread), I mentioned using an Xmega.

This gives one a faster clock, and the XmegaE5 series has a programmable logic module.

Hence one could route the signal through a Flip Flop, (or two ? ), right on the uC, to bring the clock down to an easier frequency to work with.

(This is done in hardware!)

JC

Last Edited: Thu. Apr 2, 2015 - 01:01 PM

As noted, the best solution is probably to get an AVR with at least 5 timers.

Are the fans likely to spin more than 100 rps?

If not, you will only need to deal with up to 1000 transitions per second.

An atmegs168 (3 timers) could probably do the job,

but I'd recommend against.

Iluvatar is the better part of Valar.

I have seen the comments posted today and did some research on a couple of things:

• - Flipflop to read frequency. would be doable. However it does on itself not read the PWM (flipflop gives an 50:50 high low). It is doable but then you need a complex (as far as I understood circuit). Internal AVR Xmega could be but found no examples (short search).
• - Reading PWM doable but complexity is in the precision, but you need to calculate back the frequency.
• - Creation of PWM ideally in 1 chip
• - RC Low pass filter -> this can give me a percentage as well, less complex and probably precise enough (based on kartman's first suggestion)

Rationale:

Going after the DAC and readout the value and use that to generate a new PWM.

(Concept will be made on a 644 after that a suitable device will be selected).

Just curious, what or how would you detect the frequency and decode pwm?

I found AVR135, is this the way to go?

Last Edited: Thu. Apr 2, 2015 - 06:09 PM

Sebas06 wrote:

Just curious, what or how would you detect the frequency and decode pwm?

Digital PWM detection needs two capture channels, per PWM wire, one on each edge, plus division.

You then use Trise-Trise'(previous)  difference for the period, and (Trise-Tfall) divided by (Trise-Trise') for duty cycle.

If you want 8 bit values, the timer prescale needs care to avoid overflow on the lowest Frequencies, or you can prescale to 3.2MHz and use 7 bit granularity, which is likely ok

ADC is simpler, as small MCUs usually have more ADCs than paired capture channels.

For the short run I will go the ADC way, might be interesting to read through for a next project.

Thanks for sharing a solution

Hope to have some time to make an RC circuit this weekend and test readout en PWM creation.

In parallel I have ordered an Xmega with 2 capture channels per timer (dev board) -> quite curious to work with. In manual indeed was mentioned that it could measure Pulse width and period.

Still researching the devider part of your feedback.

(This is a later solution -> unless it is going to work quite soon).

Obviously PC MB fan control is a low precision process, with a slow feedback loop, (given the thermal time constants of the system).

That's good, as it makes it much easier to control.

For converting the PWM to a dC value for the ADC to read, you will want to pass it through a LPF.

Jim had a web page with an extensive discussion of PWM LPF'ing, but I can't find it at the moment.

Perhaps he will come along and provide the  link.

If you have an O'scope this is a fun project.

If you don't have an O'scope, then power up an old PC and Google PC Sound Card O'scopes, to find some freeware program to turn your PC sound card into a low frequency O'Scope.

Note that this will let you see the PWM signal, and kind of see  the output signal.  Sound cards are AC coupled, and you are trying to generate and look at an DC signal.

That means the PC will just show a flat line at 0 volts, even if you have a perfect converter and a true DC value of2.5 V for a 50% PMW signal.

BUT, the PC scope will allow you to see the ripple in the LPF output, which is the point of using an O'scope.

Look at the PWM signal.

Start with a simple RC LPF and look at the output.  The output depends upon the RC values, but the point is there will be a lot of ripple.

Now use a rail-to-rail op-amp and feed the PWM into a 2nd order LPF, (one op-amp).  You will have a much better output signal.

Now feed it through a second op-amp, for a 4th order filter.  Now you will have a really good DC approximation for the PWM signal.

Now give some thought to realistic values.

For a simple MB fan you probably don't need a 4th order LPF, x 5 channels (or whatever the spec was).

Also, 16 bit ADC is clearly overkill, given the device being controlled, and the rippling in the control signal.

The uC PWM signal won't give you a 0.0 V and 5.0 V output for 0% and 100% PMW.

The point is the uC's pin driver doesn't really go rail-to-rail itself.

A "low" isn't really all the way to 0.0 V.

A "high" isn't really all the way to 5.0 V.

This doesn't really matter, you design the system to use the middle of the signal range, and not go all the way end-to-end.

Finally, unless you have some prior experience with ADC's, take this a step at a time.

Put a pot across the power supply.

One end to V+, the other end to Ground.

The wiper feeds the ADC input.

Add a 0.1 uF cap from the wiper to ground.

Hook up an LCD to the uC and just display the ADC readings as you adjust the pot from 0 to V+.

Make sure that works properly before going any further.

JC