Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

BLDC motor and PID loop

Status
Not open for further replies.

giovaniluigi

New Member
Hi everyone,

I'm trying to control a BLDC motor with 6-step commutation sequence.

The motor in question is a Maxon EC22 100W with 24:1 gearhead.
I'm using a PIC 18f2431 8bits MCU to control the bridge with PWM.

The goal is to keep continuous speed with heavy changes on load.

The performance is too bad even using a PID controller.
I actually have turned off the "D" controller, because it generates oscillations around setpoint.

The biggest problem is about deceleration when load is removed.
PWM duty stays high generating high speed.
PID is slow to react into this condition for example.

Here are my tests steps:

Start the motor and wait stable RPM.
When the system is stable, I insert a load.
The PWM is increased.
It takes about 2 seconds to stop increasing, then it is stable.
I keep the load and the system remains stable.
When I remove the load the motor starts to rotate in a very high speed due to the PWM duty.
The PI needs about 3 seconds to stabilize the speed again.
During this time, the PWM duty is slowly decreased till reach almost zero, then it increases back to the setpoint.

Well, probably you could say that I need to increase I constant or change the P constant.
The problem is that they seems to be in limit.
But system remains slow.

This is my PID:

error[0] = setSpeed - motorSpeed

integral = integral + error[0]
PID = Kp*error[0] + Ki*integral

I did some tricks to avoid floating point because I'm dealing with 8-bit MCU.

My constants are:

Kp = 5
Ki = 7

Now, for example, I can change Kp to 7.
Almost nothing changes.
Then I change Kp to 10.
The system becames unstable in all conditions.
Oscillations happens around setpoint even without load.

Ki = 7 makes the system take 3 seconds to stabilize.
Increasing Ki from 7 to 10 creates big overshoots.
The system also becomes unstable even without loads, having random overshoots around SP.
Also, it takes more time to reach SP.

Enabling "D"...
The system becomes slower and very unstable around SP.
Small overshoots happens in around SP.
But at least the BIG overshoots are reduced considerably.

The PID reference is the speed from hall sensors.
To reach a good performance system I think that current measurement should be used also.
I have used a shunt resistor to read current with A/D port.

The problem is that I don't know the best way to insert current measurement in PID speed controller. I have read documents in internet showing cascade loops. Where speed generates a current setpoint, then another loop corrects the system MV using current error. I didn't understood how to generate a current reference from speed controller. So if someone could help me to make this controller work better, I will apreciate.

Please!

Thank you in advance.
 
Electric motors are inherently integrators. Usually electric motors are controlled with PD-controller.. maybe small integrator is added to remove steady state error. Selecting a proper refresh frequency is important, and if you change the frequency you need to re-tune your PID. Delay and mechanical hysteresis etc. can be a big problem also.

I think your biggest problem is that you do not have a good model of the system and you try to tune your PID controller by guessing. Post more details about the system if you can (code and mechanical).

https://www.electro-tech-online.com/custompdfs/2012/03/tuning_pid_controller.pdf
https://www.electro-tech-online.com/custompdfs/2012/03/PID.pdf

Ugly, but good text about PID algorithms:
http://www.straightlinecontrol.com/pid_algorithms.html
http://bestune.50megs.com/typeABC.htm
 
Last edited:
Since it's a BLDC motor with a 6 step manual commutation, just drive the 6 steps with your microcontroller at the speed you want. The motor will run synchronously at the exact speed you want.

You need to ensure there is enough motor current that the load does not cause it to "skip steps", but basically you can just treat it like a 3 phase stepper motor.
 
misterT

I have read that the most efficient controller for servo motor is PI and derivative causes oscillations.

But you are right about the real problem to tune the PID.
I have not a model from the system.
I want to implement some interface to monitorate PID output and setpoint, then plot in the screen.
But the small PIC CPU is almost on the limit.
So I really have to guess a lot of the things...
The only visual feedback that I have is from PWM duty on oscilloscope.

The mechanical system is very simple actually.
The motor will be used in a drilling tool.
So, basically it needs to deal with huge changes on load.
To test motor power I coupled the motor shaft with a 50mm circular disk.
To "break" motor simulating load, and test the response, I just hold this disk.
More or less pressure changes the amount of load.
That is it...



Mr RB

I had this idea too.
But I tought that without a very good current control the motor will not have power enough to turn in preset speed.
If too much current is used, then motor will overheat.
I don't know if this is a very good technic.
I really tought in using it, but I have never found a reference to this type of control for 3-Phase BLDC

I think that it should be easier to tune than the other one, but I'm not sure about the torque performance.
The load can cause the motor to "skip steps" like you said...
Let me know if you have experienced any motor controller using this strategy.
 
Last edited:
I have read that the most efficient controller for servo motor is PI and derivative causes oscillations.

Internet is full of all kind of information.. I study Control theory at University, so trust me on this. Electric motor has pure integrator in its transfer function, so you don't need the integrator in PID. You need the derivative if you wan't a fast dynamic response.

- You should tune the D parameter first. Turn it up until step response oscillates and then turn it down by 2/3.
- After this tune the P parameter. Turn it up until you get the overshoot you tolerate.
- You can turn up I parameter until the overshoot is within specs, but if you do this make sure to set inegrator limits.. otherwise the system becomes sluggish, slow.. not responsive.

I found a good page which explains the above in more detail:
http://support.motioneng.com/downloads-notes/tuning/pid_overshoot.htm

It is not a perfect method, but good practical one.
 
Last edited:
Hi misterT

Thank you for your help.

I really trust on you and I don't want to doubt of your theory, but I have seem a BLDC kit from texas instrument called BLDC RDK
It uses PI controller.
Again, I'm not saying that this is applicable to my situation but the interesting thing is that they usually use PI controller only.

Well, I will try tuning it according to your pratical rules.
Actually makes sense not using Integrator because it will really slow down the system instead of making it more responsive.

I did one trick to help my integrator.
I set integrator sum to zero when it reachs SP or pass throught it.
That way, system doesn't need too much time to compensate Integration sum, not causing big overshoot.

The only question about Derivative is about the oscillations.
It is very responsive so oscillations are very difficult to damp.
Have you any tip to damp D term oscillations around SP ?
 
You need to ensure there is enough motor current that the load does not cause it to "skip steps"

This is exactly what the PID controller is supposed to do :)
 
misterT

Do you think that generating commutation time by MCU is a better option ?
Like the one proposed by Mr RB ?

I think I will change the commutation to be done by MCU in fixed period.
 
The only question about Derivative is about the oscillations.
It is very responsive so oscillations are very difficult to damp.
Have you any tip to damp D term oscillations around SP ?

Set P to one and I to zero. Then tell me at what value of D the system starts to oscillate.

.. or does it oscillate even at very small D values?
Only answer I can give to that is that you should lower the D parameter.
Can you post some code? Maybe the problem is in the math. Are you using integers or floating point?
 
misterT

Do you think that generating commutation time by MCU is a better option ?
Like the one proposed by Mr RB ?

I think I will change the commutation to be done by MCU in fixed period.

What exactly are you controlling with the PID?

You can try a simple P controller and fixed (sync to hall sensors) commutation period.
 
Last edited:
I'm using integers.
32-bit signed integers.

I will follow your tips.
I will record a video and take few pictures.
Then I will post the code and some pictures of the system.

I should reply soon.

Please keep following this thread. ;)

Thank you.
 
This is a brief of my code

Interrupt:



Code:
Commutation sensed ?
commutate()
calculateSpeed()
end

Main:


Code:
error = setSpeed - sensedSpeed
P = error[0]
I = I + error[0]
D = (error[0] - error[1])

PID = Kp * P + Ki * I + Kd * D

PWM = PWM + PID

The motor commutation is done when hall sensor reports change.
Speed of motor is proportional to voltage over it.
Voltage over motor is controlled by PWM that have duty cicle defined by PID.
 
Your PID algorithm is very sensitive to noise because of this:
D = (error[0] - error[1])

You are right.
The link you sent is very interesting.

I'm going to my lab to perform test and implement another PID code.

I should post an answer soon.
 
This is exactly what the PID controller is supposed to do :)

I understand that, but it's not the only system of keeping the motor speed accurate and it's inferior in a few ways compared to running the motor synchronous, which ensures an exact locked speed.

If the load is light (which is likely as it is a gear motor) running synchronous open loop will be fine and is very simple. This is done with stepper motors with great success.

If the OP wants to use a closed loop system he can still run it synchronous for simple exact RPM and use the sensors to indicate phase angle displacement (ie sense load) and use that to control PWM. That's a really simple one-term closed loop system.
 
I have implemented the PID using only PD like misterT said and the performance to load changes is excellent but...
The stability when it have low loads or no load is very bad.
The oscillations almost stop the motor, then speed increases, overshoot the SP a little bit...

I will try to change a little bit my code to see if oscillations from Derivative are eliminated.

But at same time I'm thinking in locking the synchronism with MCU timer so I will always have the right speed, then I can focus to tune the PID
to deal with torque. I was thinking in using the phase angle displancement and also some information about current from A/D.

I'm just afraid about the PID performance with speed sync. method.

I will use a timer to generate interrupts to commutate motor in the set speed.
I will use interrupt to detect hall sensors and then calculate speed.
With this difference I pretend to use the PID to change PWM duty.

I'm just afraid with the speed of response.
With this method motor must to "skip" some commutations to have a good correction.
I'm almost sure that it will "skip" because the load change is very heavy for this motor, even with gearhead.
That may delay response and make it slow.
Also I'm afraid of too much heat being dissipated.
But I will try...
 
Last edited:
Here is the video with PD controller:


Problems:

Needs some brake to decelerate
The oscillation around SP in no load condition is very high and not acceptable
 
Last edited by a moderator:
If you want a very exact speed and loads are light, then definitely run synchronous. PID is mainly of benefit to compensate for large changes in loads and changes in the selected speed, and it tries to do the best it can.

For running a relatively constant light load at a very precise speed then synchronous is the way to go.

What is the RPM range and what is the load (what is it driving?).
 
The RPM range is 100 RPM to 1000 RPM - in motor that means 2400 RPM ~ 24000RPM.

The load will be heavy.
It is for a drilling machine.

I changed the code to run it synchronous but for some reason I burned my power stage.
I will modify power stage and then I will back to do the tests.

I could see the motor running in synchronous mode and it seems that it makes noise and vibrations.
Well, that happened 3 seconds before burning my power stage.
But I think that was a power mosfet burned, causing 1 phase to fail and generating these vibrations.
I remember that driving a stepper motor was a very complicated task when I needed to deal with noise and to smooth stepper motor switching. I hope that for 3-phase motor will be different.

I will back to post news once I have repaired my power stage.

Thanks.
 
Whay are you using a BLDC motor for a high torque application like a low-RPM drilling machine? A series wound DC motor would be a much better choice and much easier to drive.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top