PWM tuning of DC motor

I've connected a DC motor to the PWM signal of an arduino using a MOSFET. The circuit works fine but the scaling of the signal to motor output is driving us nuts.

The PWM duty cycle does not directly correspond to the motor output percentage. The motor doesn't start moving till PWM duty cycle reaches 15% then the motor power jumps from 0 to 30%. And when the PWM signal reaches 100% the motor only gets to 90%. I've tried to scale this using regression methods but still can't eliminate all of the offsets. Regression methods involved recording motor output at certain given duty cycles then finding a mathematical function to relate the input needed to reach a certain output. I want to calibrate the system so that the output follows the input, ie 50% PWM signal corresponds with 50% output.

Am I missing something with how PWM works when controlling motors? I just can't seem to remove the non-linearity from the system.

The motor doesn't start moving till PWM duty cycle reaches 15% then the motor power jumps from 0 to 30%.

I'm not 100% sure, but I imagine this is because of the static friction. The basic idea of this is that when an object is stationary it has a coefficient of friction, .1 for example, and when it is moving it also has a kinetic coefficient of friction, .05 for example. This means that it requires more force to get an object moving, but once it is moving it doesn't take as much force to keep it moving. That is probably why your motor needs a 15% duty cycle to get moving and then once it is moving its power shoots up. You might be able to fix this slightly by getting it moving, and then lowering the PWM duty cycle some to slow it down.

As to why it only gets to 90% power with a 100% duty cycle, I couldn't tell you. It is probably something with your motor or motor controller. I have personally never experienced this issue before.

PWM ime is very non linear for ordinary brushed motors.

If the load is a pump expect very poor results.

There are two distinct issues here.

Firstly there is the friction in a brushed DC motor - which is significant in small motors, which causes
hysteresis in the response to drive voltage as observed. With extra loading a greater percentage of
drive is needed to move the load and overcome friction.

The second issue is decay mode. There are several ways for PWM to be applied to a motor, especially
if via an H-bridge, and several decay modes are not linear at all because the current falls to zero in
part of the waveform, and the percentage of time its at zero depends on various factors, leading to an
effective voltage that is not proportional to the PWM duty cycle.

The linear way to do things is to use high frequency PWM in synchronous rectification mode - the current
never decays to zero, and has a small amount of ripple under load. The effective driving voltage is
linear with PWM duty cycle because the winding is always being driven.

This mode isn't often used because the higher frequencies tend to mean more losses in the motor
magnetic circuit and more switching losses, but its perfect for linear control in a servomotor for instance
since control loops work best in linear systems.

How are you measuring motor speed and how does the PWM controller "know" what the motor speed is.

If you have no feedback of the motor's speed to the controller then you have in effect an open-loop control system and you're doing pretty well if the problems you experience are the only ones.

An open loop control is one where you issue a command for something to happen but then get no acknowledgement it either has happend or has "nearly happened". If you "close the loop" by providing feedback of motor response then the controller can adjust its output until the motor's actual speed matches that which you have requested.

Because a motor is a dynamic device with a somewhat non-linear response to input mean voltage then you cannot get the response you expect without making appropriate allowances. In general it is stated that DC motor speed is a direct function of voltage - that's reasonably true until you consider the variables of friction, windage, commutation, mechanical load etc etc. These variables can however be compensated for my monitoring motor speed and feeding this back into the controller.

You refer to tuning the PWM. Without feedback you cannot "tune"

Tuning was a poor choice of wording. Mapping would have been a better one.

I've read your comments and have come to understand that adjusting the speed of a motor is more difficult than I thought and there is no easy fix. Thanks for the knowledge guys.

The way I solved this problem is to set the PWM signal at certain duty cycles then measured the fluid output from the pump. After doing this a few times I had a graph showing fluid output vs duty cycle. I was then able to find a mathematical function that related output to duty cycle. This function was used to determine the input needed to produce the output in percent of total output. It's basically mapping input to output values in a way that allows the user to easily adjust the pump output.

I might add a feedback loop if they ask me but I doubt they will because they want to get something done asap.

Unfortunately mapping is still an open loop since pump output will vary depending on changes in speed, discharge back pressure (head), fluid temperature and fluid viscocity. If you could fit a flow measurement device into the pump outlet then you will have a good feedback signal for controlling pump speed. Without information on flow rates it is not possible to suggest a suitable transducer.

You might take a look at how Grundfos type circulating CH pumps work.

The modern ones have integrated controllers with pressure/flow/temperature feedback.
The solar ones have an external speed control input which appears quite linear, range being about 30 % to 100 %.

EDIT
By linear i mean related to mass flow , as the head is variable.

Another thought is if you can use a 3 phase motor, ESC (electronic speed controllers) can be had from modelling suppliers which use back EMF to sense speed.

Flow/pressure would have to be calculated though.