# PWM water pump flow control - in percent

I want to control flow level on 12V water pump with PWM pin, I'm using IRF520N MOSFET for that (and dedicated 12V power supply).

I'm assuming, that setting PWM to full byte should give me about 100% or 12V. But how to set proper value on PWM pin so the flow equals to eg. 10%, 25% or 50%? Is it some logharitmic equation?

• Unless the datasheet of the pump says something about it, you will have to experiment. – Edgar Bonet May 12 '17 at 19:46
• But is the voltage output on MOSFET linear? Like setting PWM to half gives me about 6V? – madneon May 12 '17 at 19:57
• No. Setting the PWM to 50% is like having a switch ON half of the time (your motor gets nearly 12 V) and OFF (0 V) the other half. It is never at 6 V. – Edgar Bonet May 12 '17 at 20:18

Expanding on dannyf's answer, if the pump datasheet does not feature a graph, then you will have to experiment. If a flowmeter is not readily available, an excellent approximation can be calculated by pumping water into a large, known receptacle (e.g. 10 litre bucket) and timing how long it takes. Do this for 20%, 40%, 60%, 80% and 100% Pulse Width Modulation modes, and you will have a plot of flow rate vs PWM that will help you interpolate the PWM required for a desired flow rate (e.g. 50% flow rate).

Below is an example of Rotations Per Minute of a 12V computer CPU cooler water pump for a given PWM input. It is assumed that this would be under load (of pumping water), but not stated explicitly.

Note that it may not be physically possible for the motor to operate with 10% or less PWM duty cycle. At this point I imagine that the internal friction of the motor and forces required to push the water along are greater than the force provided by a "10%" duty cycle. Source: ekwb

But how to set proper value on PWM pin so the flow equals to eg. 10%, 25% or 50%?

1. look at the pump's datasheet; and

2. experiment.

You'll need to tun the pump at some number of intermediate PWM values and measure its output at each one. The more intermediate values you measure, the more precise your control can be. Then you build a table of flow-rates vs. PWM level in flow-rate order, something like:

``````struct {
float flow;  // measured flow rate
float pwm;   // pwm value that gave that rate
} FlowTable[FLOWTESTS] = {
// flow  PWM
{   0.,    0. },
{ 218.,  256. },
{ 480.,  512. },
{ 732.,  768. },
{ 885., 1023. }
}
``````

For a particular flow-rate, step through the table until you find a flow in the table that is >= to the flow you want (if it's ==, just use that PWM and you're done.)

We'll interpolate between the two table values that span the desired flow-rate. The idea is, if your desired flow is say, 17% (0.17) of the way between those two flows, you want a PWM value that's about 17% of the way between the two PWM values.

Let's say you want a flow of 600 (in whatever units your measurements are in - cc/minute, for example. Index 3 in the table (remember, our arrays are 0-based) has the first measured flow greater than 600, the desired flow, so we know the required PWM will be between 512 and 768. To find it, find the desired flow as a fraction of the interval [480, 732]:

`frac = (600-480)/(732-480) = 120 / 252 = 0.476`,

or letting 'i' be the index of the first table entry whose flow exceeds the desired flow:

`frac = (flow_des-FlowTable[i-1].flow) / (FlowTable[i].flow-FlowTable[i-1].flow);`

. We need the PWM that is 47.6% of the interval [512, 768]:

`pwm_req = 512 + ((768-512) * 0.476)) = 634`
or

' pwm_req = FlowTable[i-1].pwm + ((FlowTable[i].pwm-FlowTable[i-1].pwm) * frac);`