Simultaneous positional and speed DC Motor control, using integrated encoders

Hello all,

I have a question regarding DC motors with integrated rotary encoders, and the practicality of being able to control both speed and position simultaneously. Through looking at other projects and articles, it would seem the conventional way of achieving position or speed control is through PID, but it appears to me at least, that you can only achieve one of the two at any given time, as the other variable is used as the error to drive the PID algorithm. As I myself am pretty new to PID, I am wondering if there is a way, to control both speed and position of the motor through PID at the same time, i.e. give the motor a target position to reach, and a speed with which to achieve this. Any opinions or advice would be most most usefull, and I thank you in advance for any response.

I think about PID as a precision way to control things.
As professional designer things had to be done other ways. Overshoot and then a slow move in the reversed direction made it.
PID is not always an easy and quick miracle fix.

Doesn't one imply the other? Moving a motor with a given speed makes it reach depending positions all the time. Controlling the position requires a certain speed to move to that position.

If you have to coordinate both speed and position of multiple motors, like x/y/z in a CNC machine, there exist special algorithms (Bresenham...) implemented e.g. in grbl.

Extrapolating position from speed, would be too inaccurate for the application in mind. Id rather have the positional accurasy offered by the encoder system. At the same time, setting the desired position and having the motor get there as quickly as possible at full speed is not desireable. Idealy, I would like to set a target position (in encoder steps) for the motor to hit, and this at a set speed.

From the encoder pulses you obtain both speed and position at the same time.

As a general note: the speed of a DC motor depends on various parameters. Moving at a certain speed requires permanent monitoring of the encoder pulses and adjusting the duty cycle by e.g. a PID controller. The motor also does not speed up or stop immediately, all that will take some time.

Reaching a target position at a certain speed is implemented e.g. in the AccelStepper library. First the motor is accelerated until the given speed, kept running and finally retarded to reach the target. With DC motors it may be sufficient to start with 100% and watch the speed until it reaches the wanted value, automatically at maximum possible acceleration. Then reduce the duty cycle for maintaining that speed, controlled e.g. by a PID. Finally reduce the duty cycle further for stopping at the desired position. The last phase is quite inexact, you may have to increase the duty cycle again to crawl to the target position, or to move back after an overshoot. And, as shown in the AccelStepper library, you may have to start braking before the given speed is reached, for small movements.

If precision is of special importance to you then use stepper motors and the AccelStepper library.

Thanks for the reply. After doing some further reading, it would appear it might be possible to "cap" the speed that the PID algorithm can dictate for the motor to run on in order to reach the target (this speed cap is usually set at 255 pwm, i.e. max possible output, as the PID can apparently even dictate higher speeds than possible). This should have the desired effect of accelerating the motor to the capped speed, and having it decelarate when reasonably close the target, or at least I think.

It may work, fully or to some degree, depending on your implementation.

Find out yourself and learn. You'll get help in case of problems :slight_smile:

Use position for the setpoint and change the setpoint over time to get the desired speed.