# PID and motor control by PWM

I am having a potentiometer which gives an analog voltage in range of 0-5V. I am considering this POT as throttel input for motor. If i change the pot speed increase and decrese on the basis of voltage comming from pot. I am sensing the analog voltage from ADC of my ATMEL mcu. My MCU is working on 5V.

Let say analog input from the POT is 2V. And i am assuming that command signal is 200 RPM fpr motor. My motor have hall sensor o/p from which i am able to read current speed of the motor which is say 120 RPM.

error = set_speed - current_speed  = 200 -120 = 80 RPM


Now i apply the PID to this error signal(80 RPM) i will get some controller o/p.

Motor speed is controlled by changing the PWM duty cycle (16 bit register). But big question is that PWM use to control the speed of the motor. Now how to use this controller output to change the PWM duty of my MCU

How PWM relates to controller o/p signal to adjust the speed ?

When setting up a PID regulator you will need scaling parameters, that translates the abstract PID numbers to the real world characteristics. Similarly, you must also have max and min limits on P, I and D respectively, which must also be scaled to the output characteristics.

You will have a specified voltage that is max speed of the motor. This specified voltage has to be translated to a max duty cycle of the PWM. Perhaps it is 5V and then max is 100% duty cycle.

The scale value you have to use for the PID regulator will then be this max duty cycle. The unit will be timer ticks of the timer which you use to generate the PWM.

Also ensure you have some means to synchronize the read of the hall sensor with your PID regulator updates. You cannot regulate the system faster than you can read the sensor. The reads have to get scaled too, likely it will be easiest to scale them to the duty cycle too, so you have the same unit everywhere.

Programming-wise, it is much easier to work with this 16 bit raw timer tick value, than with for example volts, percent of duty, RPM etc.

• I assume that his sensor's output is voltage and his input is voltage from potentiometer, so it would be natural to scale everything to voltage and make PID with voltage as a control, and than translate it to duty cycle. But I agree with you mostly. Commented Apr 1, 2016 at 11:20
• my Hall sensor o/p is in the form of pulses. Commented Apr 1, 2016 at 11:24
• you says .. The reads have to get scaled too, likely it will be easiest to scale them to the duty cycle too, so you have the same unit everywhere. ... what i got from this is as input variable is set speed & o/p is the actual speed ... so you mean to say to have same unit every where .. input speed & actual speed applied to error detector should be scaled down to the PWM duty .. in this case i have same unit PWM duty throughout my plant model .. right ? Commented Apr 1, 2016 at 11:27
• @Haris778 There exists no voltage inside the program, voltage is an artificial unit made up to make humans comprehend what is going on. Inside the program you have output as a raw duty cycle expressed in timer ticks, and input as another raw value expressed in bits of your ADC resolution, or as your sensor reads/timer unit etc. It doesn't make sense to scale both the output and the input to some artificial voltage unit, which nobody but humans care about. Unless you have a display showing measured voltage, there is no need to have it in your program. Commented Apr 1, 2016 at 11:40
• @user6363 Yeah, I guess you'll be having pulses per time unit as input. Lots of bugs and confusion in these kind of programs originates from programmers using different units all over the place, and make irrational decisions like "oh but this will be 3.3V and there's a decimal so I must use float numbers". That's how PC programmers think. Embedded programmers must be closer to the metal. Commented Apr 1, 2016 at 11:44

Full duty cycle period will give you maximum speed and zero duty cycle will give you no rotation at all. Your error can be also 0 and maximum value when you want full speed and motor is not rotating. Full duty cycle is equal to full DC range to 5V, half period duty cycle is equal to 2.5V and so on. You need to make conversion from voltage you get as output in your calculation of PID to duty cycle. For example, if output of PID is 1V (in range 0-5V) your duty cycle should be 0.2. Hope this helps.

• you are saying .... You need to make conversion from voltage you get as output in your calculation of my PID to duty cycle. ... but my output of PID calculation is difference of speed .. any you are telling about voltage ? Commented Apr 1, 2016 at 10:33
• I am applying PID on the speed input command - actual motor speed ... then how come the o/p of pid controller will be an voltage ?? Commented Apr 1, 2016 at 10:36
• Input of your PID is error of speed (expressed in what units, rpm?) If that is case, than you need to assign values to max speed as full duty cycle and zero speed to no rotation. And because voltage is linearly dependent of duty cycle and motor speed is linearly dependent on voltage, than you have everything. If we consider system as LTI. Commented Apr 1, 2016 at 11:09
• It is quite important that you use the same unit everywhere. If you speak of RPM in one breath, duty cycle the next breath and voltage in the third breath, you will achieve nothing but confusion. Pick one unison unit and use that throughout the program. Voltage doesn't seem intuitive, because it is just a middle step in between the PWM duty cycle expressed in timer ticks, and the motor rotation, expressed in RPM. Commented Apr 1, 2016 at 11:19
• so you mean to say find the average value (as i know at max duty what is RPM & at minimum duty of 0 RPM is also zero) lets say for 1 RPM how much is the value of the duty cycle register should be ... then as i know that error is coming out to be 80 RPM, so in this case increase the value of duty register by 80*(digital value of duty for 1 RPM) .. right ? Commented Apr 1, 2016 at 11:21