PMSM motor control with FOC using STM32F407 - Page 1
Forum section: electronics / general

author: Mrt12
author_rank: Regular Contributor
timestamp: September 20, 2019, 07:52:44 am
content: Hi guys,I want to control a PMSM motor iwth the FOC using an STM32F407. Just to test whether I can implementi it by myself, I don't want to use a library for that but I want to code it myself :-)So far I have implemented the center aligned PWM signal generation and the encoder interface is also working. Using a three phase H bridge I still had on my bench is used as power stage, and with that, I can now rotate a motor using external commutation together with SVPWM. So far this was fairly easy. However for the next steps I have a few questions...1) for the measurement of the phase current, I have added 2 shunt resistors and OpAmps to my H-bridge. To measure phase current, the ADC needs to be triggered in the phase where all 3 PWM signals are HIGH. How would you do that on STM32F4? I know there is a possibility to trigger the ADC on a PWM signal, but there are multiple possibilities to do it. Currently, I use TIM1 to generate the PWM signals on CH1, CH2 and CH3. I could either use CH4 as an internal signal to trigger the ADC or perhaps it is also possible to trigger the ADC when the timer overflows.2) the motor which I want to use has both, an incremental encoder (1024 steps per turn) and hall sensors. On startup of the motor controller, I cannot know the rotor angle exactly, I can only read the hall sensors which gives a rough estimate of the rotor angle +/-30°. So at some point, I need to align the encoder to the hall sensors. How would I do that?

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: September 20, 2019, 05:25:41 pm
content: 1) You want to use the timer overflow (when the center-aligned PWM counter reaches its maximum and starts to count down) to trigger the ADC conversion. The reference manual should have the details of how to set this up.2) Here's what I would do: drive one of the motor phases momentarily to align the magnets and use that as your "zero" by clearing the encoder count you maintain in software. You don't need to know the absolute position of the rotor.

author: lucazader
author_rank: Regular Contributor
timestamp: September 21, 2019, 01:39:49 am
content: You can also do the alignment by haveing the tree 120 degree of set phase voltages and then slowly ramping up the current into those phases which will pull the magnets into line.The slow ramp up helps reduce oscillations around the "center" point as the magnets move into place.

author: bhave
author_rank: Contributor
timestamp: September 21, 2019, 02:00:00 pm
content: Quote from: Mrt12 on September 20, 2019, 07:52:44 amThere are many different ways to align the motor on start-up. The easiest way is to ramp up a current on the D-axis and force the Q-axis to zero. If you know where the index pulse is on your encoder, you can line that up at this time. Otherwise, you can integrate your calculated speed to create the rotor angle internally and not worry about lining the encoder up. Once all that is done, every time you start the motor you do the same thing with the D-axis and Q-axis. Then, set your rotor angle to zero, drop the D-axis command to zero, and give the Q-axis some command. The Q-axis command generally comes from some sort of speed PI regulator.

author: Harjit
author_rank: Regular Contributor
timestamp: September 21, 2019, 07:37:34 pm
content: Quote from: bhave on September 21, 2019, 02:00:00 pmSo, before the inverse Park transform, ramp up the D-axis current and then the inverse Park transform and inverse Clark transform will do their thing? Oh, this will cause the rotor to gently rotate and the encoder will pick that up and then start commutating from there?Can't the rotor start off going the opposite direction?The approach I was considering was use a magnetic encoder on the motor shaft. Read that. Compute 90 deg. ahead and directly generate the three phases. At startup, I was going to set the max. current to some empirically determined value and once some speed was achieved, turn on the current loop. Would this work?

author: bhave
author_rank: Contributor
timestamp: September 22, 2019, 01:56:16 am
content: The control works like this:1. Read your currents2. Do a clarke transform on them3. Do a park transform on the output of the clarke transform using your rotor angle4. Create the D and Q axis current commands5. The output of the park transform and your D and Q axis current commands create the error inputs to current PI regulators6. Do an inverse park transform on the output of the current PI regulators using your rotor angleYou can make the motor spin in a certain direction by forcing rotation in the rotor angle even if you do not know the correct angle to start. This requires the current loops to be active and some predetermined current command to be used in either the D or Q PI. Once the motor is spinning a certain speed, you use the measured rotor angle and close the loop around the current command. Generally, this is some sort of speed PI loop or torque command. The output of this loop becomes the Q current command. The D current command is then forced to zero, unless you are field weakening.There are lots of little details required, but that is the general idea.

author: Mrt12
author_rank: Regular Contributor
timestamp: September 22, 2019, 10:04:51 pm
content: :bullshit:Hey guys,thanks so far for your hints. I see that it should be possible to "guess" the rotor angle from the current hall sensor states.In one application note from Microchip I read that the alignment may be done as follows:Excite the d-axis with some current and wait until the rotor settles. Then, the rotor angle can be determined.However, how can I do this alignment if I don't want my rotor to spin? e.g. when you are building a segway it can be dangerous if the rotor first needs to move to align the encoder to the hall sensors. There must be a more sophisticated algorithm, because many commercial PMSM controllers don't need to rotate the motor for the initial alignment. How do they do it?

author: bhave
author_rank: Contributor
timestamp: September 23, 2019, 01:03:44 am
content: Quote from: Mrt12 on September 22, 2019, 10:04:51 pmYou can either use an absolute encoder or something like high frequency injection to determine the rotor position on startup. This is an area of extremely active research.

author: lucazader
author_rank: Regular Contributor
timestamp: September 23, 2019, 01:44:48 am
content: If you have an encoder like a TLE5102b, ma302 or as5047x then usually these will give you an absolute position even after power loss.You would then just have to calibrate this angle against the magnetic position once, and save this into some form of non volatile storage.You also gain super accurate mechanical feedback of the rotor angle which will help if you need to do slower speed movements or positions controlled movements.

author: Mrt12
author_rank: Regular Contributor
timestamp: September 23, 2019, 08:01:52 pm
content: haha, sorry for that "bullshit" in my last post, I didn't intend that :-) I was typiing on the smartphone and apparently hit some wrong button without realising it.@lucazader,unfortunately I have no such encoder. I have only a very simple one which gives me A and B signals, I don't even have an index pulse. :-(

author: bhave
author_rank: Contributor
timestamp: September 23, 2019, 08:45:39 pm
content: Quote from: Mrt12 on September 23, 2019, 08:01:52 pmYour simple encoder is fine to get your code and hardware tested. Once you are controlling the motor the way you like, then you can start to optimize certain aspects of it such as rotor alignment. You will need very accurate position feedback if your goal is to provide really tight zero or low speed performance.

author: lucazader
author_rank: Regular Contributor
timestamp: September 23, 2019, 09:27:14 pm
content: Quote from: bhave on September 23, 2019, 08:45:39 pmAgreed. These magnetic style encoders are quite affordable and also very reliable for production environments.A cheap one you could look into is the a1333 or a1338, they can be had for around $1.60-$1.80 in volume.

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: September 24, 2019, 10:25:38 pm
content: Quote from: Mrt12 on September 23, 2019, 08:01:52 pmUnless your application is a servo motor or a steering controller, your 1024 count encoder is more than good enough. Commercial FOC controllers typically work with AC motors with 32 or 64 count encoders, which have more than an order of magnitude less position resolution than your encoder.Ditto for an index pulse--absolute position is really needed only for a servo or steering controller, and those controllers typically "fake it" by slowly rotating the motor at start-up until an index pulse is encountered to establish the zero point.What exactly is your application? That may determine how you align the motor poles. For the tiny motors I work with, just turning on a single phase at startup won't be very dramatic, but if you have a big, massive motor, you probably want to gradually build up the current in a phase using PWM rather than just turning it on all at once.

author: bhave
author_rank: Contributor
timestamp: September 25, 2019, 01:42:18 pm
content: Quote from: Sal Ammoniac on September 24, 2019, 10:25:38 pmI am just curious, what kind of commercial FOC drive for an AC induction motor uses a 32 PPR encoder (I need to figure out what they are doing!)? I develop drives for very large induction motors and have never been able to get decent low speed torque regulation using 32 PPR without playing games with flux observers and sensorless control. It works fine for things like fans and pumps. Anything that starts under load while crossing zero or at zero speed, seems to require more resolution. We have standardized on 1024 PPR for most stuff.His encoder resolution is fine, but if he wants to align the rotor without any rotation, he needs to dip into some more complex controls or use an encoder that gives him an accurate rotor angle on power up.

author: tb5byo
author_rank: Newbie
timestamp: September 05, 2025, 05:25:51 am
content: Quote from: bhave on September 22, 2019, 01:56:16 amI’m aware that quite some time has passed since this topic was discussed, but I still have some question marks in my mindBy manually setting the values of Vd and Vq in the inverse Park transformation, I can manipulate the generated output signal. At the same time, I measure the motor currents and bring them through the Park transformation, which contains the DC component.Let’s consider removing the PID in the PMSM and directly using the inverse Park transformation parameters Vd and Vq. When Vd is kept constant at zero and only Vq is varied, how are the Id and Iq currents obtained after the Clarke–Park transformation affected? Does changing only Vq cause both Iq and Id to increase at the same time, or are they independent?As I mentioned, I set Vd = 0 and increase Vq. As I raise Vq, the motor speed increases. However, when I look at the measured currents, I see that both Id and Iq values also change.Another point is that Vd and Vq are generated to take values between 0 and 1. However, we measure currents from the motor in the mA range, and the rated value is 650 mA. In this case, between what values should we normalize the measured Id and Iq currents? (Note: Id and Iq can also take negative values.)