- position error = your input - measured position (after voltage to angle conversion)
- P controller output = K * position error (NB : this command signal can be positive or negative , hence my first recommendation about knowing how to control your motor speed in amplitude and direction)
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
DC Motor Position Control using Potentiometer as a Feedback
102 views (last 30 days)
Show older comments
Hello,
I am trying to control the position of a dc motor using a potentiometer as a feedback (on simulink). The idea is to input an angle from 0 to 180 degrees and then motor will spin clockwise or anti-clockwise (depending on it's physical position) until it gets to the desired angle. My goal is to implement a P controller on this process (getting to the desired angle). The problem is that I am confused on how to express the problem on it. At first I have a similar setup as the one in Picture 1. After that, in Picture 2, I have expressed the dc motor's speed with a constant and I have used Digital Pin 9 for PWM. So 0 means that dc motor will not spin and 255 means that dc motor will spin at its highest speed. Potentiometer is connected at pin 5 and its value is shown on the simulink's display. Both dc motor's speed and potentiometer's value are working and I would like some suggestions at Picture 2. My idea is to set a desired angle as a constant, do you think that it will work with a constant block? Also, I am confused on how am I going to connect dc motor's speed and potentiometers value with my P controller, can you suggest me a way? One last thing is, how can I get the current angle and then fix the error in order to get to the desired angle, any ideas?
Thank you so much for your time, appreciate your help !
Excuse me for any mistakes !
Picture 2: Thoughts of the model in Simulink
33 Comments
Mathieu NOE
on 5 Jan 2022
hello Christos
I have the following recommendations :
before attempting to put the controller in place , you have to be sure that you are able to spin your motor in both directions (which is not yet the case as far as can see here) and in a proportionnal manner (through the PWM signal)
so the control of you motor requires you to be able to transform a given positive or negative control signal to the right PWM and CW /CCW rotation signal (I will not dig into how to do it at the L293D driver level, there are enough ressources about that topic)
that was for the motor
for the potentiometer sensor , your signal is a voltage signal that must be first converted to a angular representation; assuming the pot has a linear output (vs actual position) this equation must be simple (affine)
from there you have to make a conversion block that will convert back the voltage reading to position
then you can easily buid a classical feedback loop (can be P controller or more advanced controllers)
Christos Tsallis
on 5 Jan 2022
Hello Sir,
I tried to follow your instructions about the potentiometer and I have the results in Picture 1. At first I got a voltage measure of 288 and using a subsystem which I created (basically it makes a simple multiplication in order to convert the voltage to angles) I got 90 degrees which in the physical setup seems a quite good approach. In Picture 2 I express how I understand that the dc motor will turn CW or CCW using a simple switch but I can't understand how to make it work itself and not changing the values by myself in order to move CW or CCW. So my questions are the following,
Is the approach in Picture 1 the same that you are expressing ?
Could you please suggest me a way to make the dc motor spin it self when the desired angle is not yet achieved ?
Thank you again for your time, appreciate so much your help !
Picture 1: Potentiometer (Voltage to Angles) and an approach of the system.
Picture 2: DC Motor's Speed and Direction.
Motor will not spin when IN1R1 and IN2R1 is "1 1" or "0 0", otherwise if IN1R1 and IN2R1 is "1 0" or "1 0" it will.
Mathieu NOE
on 5 Jan 2022
hello again
for the sensor it's fine now;
for the motor control : from what you say I guess IN1R1 and IN2R1 will define the motor rotation direction depending if they are "1 0" or "0 1" (I have not really looked at the driver specs)
see below : you can now control the speed and direction without any manual intervention :
I used a sinus wave input as an example (with max amplitude =1 here) , this will be in the future the output of your controller
- the speed control is defined by the abs block output (multiplied here by 255 to represent the PWM)
- the direction is given by the sign block that drives two switch blocks (these are the two IN1R1 and IN2R1 signals)
the simulink file is attached if it works for you
Christos Tsallis
on 5 Jan 2022
Edited: Christos Tsallis
on 5 Jan 2022
Hello again Sir,
I made some progress from the previous comment. In my real setup, when I use the following simulink model this happens:
when I set the set point at 90 degrees (example) then the motor spins until the position error is 0 but it always gets close to 0 and never exactly 0. As a result the dc motor position can't be controlled. I tried to make a P controller to limit the value to zero but it doesn't work. When I tried to add a PI controller to my system then for some reason if Ki is anything but 0 the position error keeps increasing (same with Kd). I can't understand what should I fix in order to make my P, PI or PID controller work so that the position error becomes 0, could you suggest me any tip?
I will try to recreate the model with the way that you posted !
The dc motor works as,
u2 is the desired angle and u1 is the position error, so if u1<0 it means that the motor needs to spin so that the position error gets to 0. Also, if u1>0 it means that again the motor needs to spin so that the position error gets to 0. If neither of the above happens it means that the position error is 0 and motor needs to stop. The problem again, is that I can't understand how to express the P, PI or PID controller to keep my motor steady at the desired angle. Any suggestions?
Thanks you so much for your time Sir !
Excuse me if I am not clear with my thoughts.
Mathieu NOE
on 5 Jan 2022
there is one thing that still needs to be done before we decide what controller is appropriate to do this task
we need to know what is the model or transfer function between you command signal (PWM) and your position reading
I would suggest first to make a step response (PWM switch from zero to a non zero value at given time value) and record both command and angular signals together
now I am curious how the angular sensor step response looks like
can you do this experiment and share the result ?
Christos Tsallis
on 5 Jan 2022
Edited: Christos Tsallis
on 5 Jan 2022
Hello,
I think that I didn't understand correctly what you said. I will tell you what I did and then correct me if I am wrong. At first I added a step response block from zero to 50 (random) and I manually rotated the potentiometer when the step time became one in order to follow the step response. Potentiometer's behaviour is shown bellow.
Picture 1: Step Response Connection
Picture 2: Step Response and Potentiometer's behaviour (manually)
Also, the DC Motor's behaviour while trying to make the position error zero is shown bellow. It seems that it becomes zero for a very tiny period of time that even on graph can't be shown. Blue and Yellow lines are the motor's direction which oscillates because of position error was close to zero. I glued the DC Motor with the potentiometer in order to get the following results.
Picture 3: Connection of scope in order to get the dc motor's behaviour
Picture 4: DC Motor's Behaviour
Last, I connected the motor's direction, pwm and the angular value at one scope as shown bellow.
The result is the following, in which I have glued the dc motor with the potentiometer. There is a huge oscillation and it never gets to the desired angle. Also, the blue line which is steady at 65 is the PWM signal which always stays 65 and never gets to 0 cause of oscillation. Yellow and red pulses are the change of direction which motor does in order to move closer to the desired angle.
Mathieu NOE
on 6 Jan 2022
hello again
it's a bit confusing ... you say you are rotating the pot by hand ?? i thought the pot was only linked to the motor shaft ?
the step response measurement means the step signal must be applied to the motor and we measure this signal and the pot reading simulteanousy
why turning the pot manually ? it was supposed to be done by the motor under a step signal command ...
Christos Tsallis
on 6 Jan 2022
Edited: Christos Tsallis
on 6 Jan 2022
Sorry for the misunderstanding, at the last picture that I have posted there is nothing turned manually. Pot is linked to the motor shaft as you say. As you can see potentiometer does a lot of oscillation, cause of dc motor’s behavior. I have tried to make it speed as low as possible in order to reduce the rotation speed of the shaft but it still oscillates. I think that’s where I need a P, PI or PID controller. Should I upload anything else to be more understandable? Also how can I find the transfer function that you previously said in order to find out what controller I need ? Thank you again Sir, I really appreciate your help!
Mathieu NOE
on 6 Jan 2022
as you post only a fraction of the model (picture), I cannot see if the test is done open loop or closed loop (with P controller)
can you clarify ?
Christos Tsallis
on 6 Jan 2022
Edited: Christos Tsallis
on 6 Jan 2022
Of course,
the model which I used in order to get the previous picture is the following. It's a closed loop system that checks the position error and if it gets to 0 dc motor should stop. It never stops cause it oscillates for ever and it seems that I have connected wrong the P controller because it doesn't do anything at all. (The Ki and Kd are disconnected)
I have attached the Simulink ".slx" file as well.
Thank you again!
Mathieu NOE
on 6 Jan 2022
sorry - again a few basic questions
1/ are you able to control your motor in speed and direction now ? I mean positive and negative u1 are giving expected rotationnal speed amplitude and direction ?
2/ the u2 input in the IF block is not used I assume ? or what was the intention (I don't understand why it's connected directly to your angular input
3 / have you tried to reduce / increase Kp and see the effect on transient response (how fast the otor reacts) and the steady error ?
4/ your steady error will be reduced if you can use a larger K gain but within the limits of stability (some chatter may arise if you are too strong)
also the PWM resolution may limit your position accuracy ; can you increase the PWM resolution ? or a geared motor would be more precise so you would see less wandering around the position target value
same for the accuracy of the position sensor voltage reading : accuracy of your ADC converter can also limit here how accurate your loop will be
Christos Tsallis
on 6 Jan 2022
Edited: Christos Tsallis
on 7 Jan 2022
Hello Sir,
I tried to convert the double value which I get after the Kp gain block with an integer value. Now it oscillates not that much arround zero. I think that the problem is the following:
When the dc motor needs to stop because the position error is zero it stops for a very little period of time. This little period of time is not enough because the motor has a speed which is able to move the dc motor away from the zero position error and then oscillation occurs. (I have set the dc motor's speed at the lowest possible)
1/ Indeed, they give the expected rotational speed and direction.
2/ My mistake, thank you. It does nothing, I will remove it.
3/ I tried reducing the Kp value but it still oscillates. Increasing Kp value make things worst than decreasing it.
4/ Larger Kp gain isn't working well.
I am using a TT DC Gear Motor.
TT DC Gear Motor : https://www.verical.com/datasheet/adafruit-brushless-dc-motors-3777-5912007.pdf
- Can you suggest me a way to increase my PWM resolution?
- Also, is the P controller placed at the right position?
Thank you again for your help Sir!
Mathieu NOE
on 7 Jan 2022
hello
I am not sure the driver is able to provide lot of improvement on the PWM resolution
there is some info here : if you could reduce the PWM carrier frequency this translate into better resolution
another point to watch is the freeplay in your geared motor (freeplay is your ennemy, will create inaccurate control & oscillations), try to reduce that or introduce a way to make sure the teeth are always in positive contact (preload spring or use a weight (gravity) to introduce some loading torque on the output shaft.
if you cannot improve your current motor system , maybe pick a geared motor with high ratio gear (worm gear) and minimal freeplay (or add some loading on the output)
in the control logic you can add a "dead band" block on the position error signal, so when you have reached steady state, the small oscillations are zeroed by the dead band block; this solves the oscillation problem but you are still with some inaccuracy of the control
Christos Tsallis
on 7 Jan 2022
Edited: Christos Tsallis
on 7 Jan 2022
Hello,
About the dead band block, it keeps oscillating..
Do I need to use any other block for my I or D part of the controller in order to stop oscillation?
Also, is the controller's placement right?
I have attached a simulink "slx" file with the model.
Thanks for your time, appreciate your help!
Mathieu NOE
on 8 Jan 2022
hello
normally , the dead band "amplitude" should be selected to be slightly larger to the oscillation amplitude you have before you implement it
what was you "best resukt" obtained so far ?
have you tried to load the shaft to reduce the free play ?
what is your gear ratio ?
Christos Tsallis
on 8 Jan 2022
There was no best result unfortunatelly.
I haven't tried to load the shaft because I would like to make it work without loading it !
Also the gear ratio it 48:1.
Christos Tsallis
on 9 Jan 2022
Edited: Christos Tsallis
on 9 Jan 2022
Hello Sir,
First of all thank you for all of your help and time.
My system is working, the only problem was that I haven't tried a lot of PID values. So, I tried approaches with different PID values and at the end, I got a good result of arround +/- 4 degrees deviation from the set point.
Now, I have another question. My PID outputs ,as you can see from the previous "slx" file, only the deviation of a set point and a measurement. As a result, PID checks only this value and it is not controlling the PWM pulses which they go to the dc motor (PWM pulses are controlled from the "Block - if" of previous "slx" file).
So, in order to get PWM as an output of the PID I used the model that you previously suggest me (see screenshot bellow). I think, this is the right approach compared with my previously "slx" model. I have some questions about the following model. At first do I need to change the PID's Output Saturation ? Also with the following model, do you think that finding the correct PID values will make it work?
I have attached the "slx" file and a screenshot of the model bellow.
Appreciate your help Sir !
Mathieu NOE
on 9 Jan 2022
hello
I just figure out now that your previous implementation with the IF block was not making any proportionnal control of your motor as your are always driving the motor with a fixed PWM value ( = 65), just changing the direction;
now this new version is a bit different as now you are using the range (-65 to 65) together with the sign of the PID signal driving the direction pins
nota that all you did isnside the red rectangle is correct but is basically what a simple abs block can do in a much simpler way
also, now that the PWM is proportionnal to error why do you limit the PWM to 65 ? you are limiting yourself to lower speeds ?
if you want to reduce steady state error you can try using the integral gain of the PID
the derivative term is for me not needed in this case because your "load" is not a resonant system (like a mass - spring system)
again it would have been interesting the measure the open loop step response to do a bit of PID tweaking (matlab script) - but sure you can also make trials and error method on the bench directly
Christos Tsallis
on 9 Jan 2022
Edited: Christos Tsallis
on 9 Jan 2022
Hello Sir,
Excume me, I have edited the last comment again. Can you re-read it? There were some mistakes which I fixed.
Also what's the purpose of the gain in the circle? I am thinking of making it 1 and only have the output of PID. Is my thought wrong?
Thank you for your help !
Mathieu NOE
on 10 Jan 2022
hello
this model is correct for me
the gain block (x 255) can be used but this is equivalent to put this gain inside the PID gains - so there is not "benefit" or "drawback" using this block ; at the end, your performance is given by the open loop gain (i.e the product of gain of all blocks, so the controller's gain is either fully inside the PID block or you can split it in two but again no benefit of doing so)
the PID output saturation depends only if you really need to saturate the command to the motor to keep RPM or power consumption below a given level; on the drawbacks I would say it limits your time to reach the target angle (it acts as a slew rate limiter); can be needed but I leave it to you to decide if it's necessary or not; it will not have any influence on the accuracy or noise as this is more a question of PWM resolution / free play and gear ratio
Christos Tsallis
on 10 Jan 2022
Edited: Christos Tsallis
on 10 Jan 2022
Hello again Sir,
I see, so I will use only the PID Block. I did some tests with P and I values (it can work without D) but the results where not stable at all. For example I observed that, with P values between 1 to 2 and I = 0 then my system was trying to achieve the desired angle and it had a deviation of +/- 10 degrees from the desired angle (sometimes it was accurate and had 0 deviation from the desired angle). In order to face this problem I started to increase the I value between 15 to 35. I understood that the PI works like this, my system was trying to achieve the desired angle with P controller at first and if the result was not the desired angle then the I controller shows up to try some more times to fix the deviation.
I think that the problem isn't the PI values, because I tried so many combinations (of P and I) and I got nothing stable at all. Do you think that I can add a block after the PID in order to fix those oscillations ?
Thanks for your time, appreciate your help!
Mathieu NOE
on 11 Jan 2022
Edited: Mathieu NOE
on 11 Jan 2022
hello again
I would like to make a test to measure the actual transfer function between command and measured position
this is an open loop test , so the PID should be removed
can you try record 10 to 30 seconds of data if you put a low amplitude random noise at the motor command signal
in the data should be the command signal and the position signal
from there we can build a model of your process and do a bit of controller optimisation
this is more "scientific" rather than doing by trial and error (maybe sometimes you are lucky, sometimes no)
Christos Tsallis
on 11 Jan 2022
Edited: Christos Tsallis
on 11 Jan 2022
Hello again Sir,
my thoughts are the following,
first I must find the transfer function which represents my real dc motor, then place it into a function block and with the PID Auto Tune feature I will tune the transfer function and get the best results for Kp, Ki and Kd. After that, I will remove the transfer function block and connect again my model which represents the real (physical) system. The problem is that, I need to know some of the parameters which are shown in the following image. I must know R, L, Back-EMF and some more values in order to mathematically express my model as a transfer function. This can not happen with the dc motor that I currently have, because there are no specifications like those needed. Am I correct?
So, about the suggestion of yours. I can't understand how to implement the open loop test that you are saying. I removed the PID.
Is the motor command signal the setpoint ? If it is, should I use a step function block instead of this?
Is the position signal the one that potentiometer reads ?
Thank you again for everything, you helped me understand a lot of things !
Is the following model right about the open loop test? I have removed the PID and added a signal at the command signal.
Mathieu NOE
on 11 Jan 2022
hello again
you can build either your model from the equations , but you can also do it experimentally (this was my suggestion)
the open loop test means that before you even put in place any controller , you must first have a good model of your process - either by theoretical or experimental approach
this is how you should make your model for a open loop test
the random number block (red) is used to "shake" your system with a kind of broadband (white ) noise
we record simulteanously both this command signal along with the response of your system (the position signal)
from there we will build a model of your system and that will be the start point of the PID optimisation
Mathieu NOE
on 11 Jan 2022
forgot to mention : maybe add a gain block after the random generator so you can easily tune the amplitude of the broadband signal so that the system is shaken with a reasonnable amplitude , not too low, not too high.
make sure that what you record is the broadband signal after the gain block
Christos Tsallis
on 11 Jan 2022
Edited: Christos Tsallis
on 11 Jan 2022
Hello,
I added a random signal as you said, and a scope on both outputs. The problem is that, with this connection the motor will may spin in the direction that the potentiometer ends. What I did here (to limit this problem), is that I rotated the potentiometer by hand to a degree with enough range to rotate left or right and then glued again the dc motor. I run the model and got the following results (2nd picture). Also, in the random signal I set mean = 0 and variance 200 in order to get from -200 to +200 (+right rotation, -left rotation, values between -200 to +200 are speed).
If I understand correctly, the diagram will show random moves of the dc motor and the result of these random moves at the potentiometer. Am I right?
On the diagram blue line represents the potentiometer and red line represents the dc motor. Both of them where tested with random values and this was their response.
I have attached the "slx" file.
Thank you again Sir !
Mathieu NOE
on 11 Jan 2022
hello
yes it can ba bit tricky to center the motor at the potentiometer mid position before you do the test
you can probably do that by giving some positive / negative hort duration maunal commands
to your record
I am quite a bit surprised by the look of the position sensor signal. I was expecting something like low pass filtered version of the input signal , so it should be more centered around a mean value. I wonder alsowhy we have these "flat" responses from time to time (as if the shaft would not move at all ? ) and also abrupt vertical changes
is the potentiometer a bit "sticky" so that the motor has difficulties to turn in a precise and stick slip free manner ?
or have we made any mistake in the control logic (amplitude and direction ?)
Christos Tsallis
on 11 Jan 2022
Edited: Christos Tsallis
on 11 Jan 2022
Hello,
these flat responses from time to time is when the dc motor moves the potentiometer to its end so its value is zero (because potentiometer can't move more than that). I can't control it because the values are random and it happens from time to time. Should I "center" again the potentiometer and try one more time? Also what result about the PID optimization can we get from the graph?
Thank you again.
Mathieu NOE
on 11 Jan 2022
Edited: Mathieu NOE
on 11 Jan 2022
Ok , so it means we have a situation where it's not easy to do "open loop" testing
I would try another option, so let's put the "best" PID controler back and now the random signal is applied again as a position command input (replaces the step block)
the data we need to measure for the model is
- the PID output (which is now a closed loop command signal to the motor)
- the position sensor (as before)
the benefit of having a "almost" working PID is that it will keep the shaft centered around a mean value and there should be no risks of hitting the potentiometer ends - if the input amplitude is not too large
Christos Tsallis
on 11 Jan 2022
Edited: Christos Tsallis
on 11 Jan 2022
So my PID's input is going to be random again? Did I understand correctly?
Mathieu NOE
on 12 Jan 2022
yes , basically replace the step block by the random generator and record the PID output along with the position sensor signal
Answers (2)
Christos Tsallis
on 12 Jan 2022
Hello, I am facing some issues. At first, my PID’s output is the PWM signal which controls the speed of the dc motor. If this speed is less than 65, motor can’t spin at all. I tried to tune again the P value by myself (I=0, D=0) with the Random Number Generator Block as an input. I set its main value equal to 90 and its variance 30 (for RNG block). The problem is that when it oscillates for one random number it goes close to this random value and after that cause of the PWM’s output is less than 65 it doesn’t move at all (when a new RNG value occurs). So at the scope there are less than 5 seconds which they show the system’s response… The DC motor which I use is called TT DC Gear Motor and it operates at 3 - 6 Volts. It’s “datasheet” can be seen here: https://media.digikey.com/pdf/Data%20Sheets/Adafruit%20PDFs/3777_Web.pdf Do you think that I need a better dc motor in order to fix my problem ? Thank you for your time, appreciate your help !
5 Comments
Mathieu NOE
on 12 Jan 2022
hello
I have the feeling your geared motor is not able to turn the pot at low speed / low torque (tends to stick in place)
that's why we get these "flats" in the response when the PWM is in the low range
I haven't check either that the arduino board can supply enough current to make your motor turn in all cases
that could explained why we have so much difficulties to get a clean response and why the PID cannot really give you the expected results in terms of accuracy and steady state response (without oscillations)
maybe the pot is too hard to turn for your geared motor , I am not sure how much torque is needed to make the pot turn. that could be the major issue here
as I am a bit involved in the hobby and I am using rc servos , I think it's worth looking at how rc cars / planes are made , basically the same ways as your system but with a higher gear ratio , less free play (maybe) and better motors (maybe )
why not buy a cheap rc servos (take analog rc servo with plastic gears ) , you can easily unsolder the tiny electronic circuit and solder the motor and pot to your arduino board
Christos Tsallis
on 12 Jan 2022
Edited: Christos Tsallis
on 12 Jan 2022
Hello !
I have connected the dc motor to the L298N motor driver and not to the arduino itself. You are right, I will buy an analog rc servo, then unsolder the needed parts and then try it to my arduino.
Sir, I have really learned a lot with your help ! I really appreciate it ! I will inform you soon about the results of the new motor and potentiometer.
Do you think that I can use the interior of a SG90 Servo for this purpose?
Thank you for everything !
Mathieu NOE
on 13 Jan 2022
hello
yes , I think this servo can do the job. I'm curious to see the results with this one.
all the best
Christos Tsallis
on 27 Jan 2022
Hello Sir,
a lot of days have past since my last message, excuse me about that.
I haven't yet connected my PID controller to the SG90 Servo, but I bought the following motor : https://gr.mouser.com/ProductDetail/Digilent/290-008?qs=s%2FdyVPQMB4zvWqNo5wm3QA%3D%3D
I bought it cause on its datasheet there are all the required variables that are needed in order to simulate a DC Motor in simulink and then get the best PID values using Auto-Tune. So, I will replace my current TT DC Gear motor with this and I will see the results...
I will inform you again, when it will be on my hands !
Thank you for everything !
Mathieu NOE
on 28 Jan 2022
hello
ok - sounds good
I see the gear ratio is only 1/52
all the best for the future
See Also
Categories
Find more on Adaptive Control Design in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)