Making a PMSM Motor Drive (FOC questions)  - Page 1
Forum section: electronics / projects

author: TSOL
author_rank: Contributor
timestamp: April 23, 2025, 05:04:14 pm
content: Hello!I have recently purchased a cheap(er) PMSM motor off of aliexpress, and the intent was to learn how to control it using as much "homemade" circuitry as possible (no black boxes). I have already started making a sinusoidal controller on LTSpice, and it works (at least in simulation). I will upload it later as I don't have access to it right now.Typically, when doing Sinusoidal control (which is different than SVPWM), You would measure the rotor's position to figure out where it points, then generate a current magnitude on the 3 phases that is 90 degrees perpendicular to this direction to generate maximum torque. When the motor is spinning, these magnitudes change sinusoidally, and therefore the resulting 3 phase currents are sinusoidal. One would just need to adjust a scaling factor to adjust how much current is being commanded, and this would adjust the rate of rotation of the motor quite nicely. This much makes sense to me, it is when SVPWM gets involved that throws a wrench in my plans. The driving voltage is not sinusoidal, but the current is. If you are controlling current, I can't see a way to possibly get non-sinusoidal voltage. (In the case of 3rd-harmonic injection, it is still sinusoidal but not of the same form as the current).As far as SVPWM is concerned,Let's say you are at a stoplight. Your motor is at the -10 degree angle, so you need to command a torque to it at the 80 degree angle. (Assume that positive degrees is forward travel). Would you start PWMing it the duty cycles for 80 degrees, like shown in the photo? Or would you have to PWM it for the 170 degree angle because the current lags behind the voltage another 90 degrees? Perhaps inductance is so slow compared to motor speed that the phase lag is assumed to be negligible? And certainly one cannot just PWM this duty cycle forever, as motor current would skyrocket and go to several kiloAmps (or fry your transistors), so current control has to be involved SOMEHOW, right? Would you then have to have the duty cycles of the PWM attached to a PI controller that measures the current and will reduce them (or increase them) as the target current approaches?It is really difficult to wrap my head around this, so any guidance would be appreciated.

author: Siwastaja
author_rank: Super Contributor
timestamp: April 23, 2025, 05:46:08 pm
content: FOC in essence:You want sinusoidal currents, because (assuming perfect mechanical construction) sinusoidal currents give sinusoidal forces, and sinusoidal forces from stationary electromagnets give smoothly rotating vector with no torque ripple.You also want the sinusoidal currents to be 90 degrees in advance of the current rotor position to create optimum forward rotation. 0 degrees, for example, would just pull the rotor with a lot of force towards your current position, consuming a lot of current (thus resistive heating) for no work done.Now the problem becomes how do you generate three sinusoidal currents that are in correct sync of rotor position? You need to output PWM signals for the bridge. Obvious first solution is to create three PI controllers: measure current, adjust PWM output in feedback loop to maintain any desired setpoint. Now you can have any current you want. Now make the setpoints change, sinusoidal, 120 degrees out of each other. Tadah, job done. And it works, I have tried it.The problem comes when the motor is rotating any faster than some dozen rpm (more than a few Hz). Your PI controller will have lag, and the lag is not constant, and so your desired 90 degree shift will get longer and longer.Solution: measure currents, but mathematically rotate them by the simultaneously measured rotor angle, so that the measurement appears "stationary". Now apply PI controller tothatsignal. Rotate the feedback loop's result (PWM setpoint) back to the rotor angle.Yes. That's all to it. It's really this simple.Minor mathematical details are the conversion from the 3-axis geometry into our much more familiar 2-axis geometry. In latter, you can apply the classic 2D vector rotation formula. The one you see all over the place, including stuff like computer graphics, it has sines and cosines in it. That's where the sine generation ultimately also comes from.2-axis data is comfortable to work with because that way, you get your desired 90deg advance by regulating one of the axes to your desired current (torque you desire), and the other to zero.measure 2 currents -> calculate the third by subtraction (Kirchoff laws!) -> 3 currents in -> 3-axis-to-2-axis conversion -> 2 currents -> rotation -> two PI controllers -> 2 PWM setpoints out -> rotation back -> 2-axis-to-3-axis conversion -> 3 PWM setpoints out.I never understood SVPWM and never found a resource which explains it to an idiot like me. Turns out it was unnecessary. The classical explanation is that it saves you a few multiplications and subtractions. Maybe that was relevant in 1970's.And practically, high resolution position encoder is your best friend. You can of course run FOC with hall sensors giving 6 steps per electrical revolution, but your position input signal will be quantized and jumpy and the end-result is something between the classic super-simple BLDC commutation and "real" FOC.

author: Martinn
author_rank: Frequent Contributor
timestamp: April 23, 2025, 05:53:07 pm
content: In addition: If you want to drive your specific motor, what rotor angle sensor does it have?None?Hall sensors?High resolution encoder?For learning FOC, it makes sense to have a high resolution (preferably absolute) encoder.If you have no sensors, you go sensorless which involves estimating rotor position, you don't want that on top for the beginning.If you have hall sensors, it means 6-step which is kind of boring and also handled differently from FOC (simpler actually, but less fun).Don't be intimidated by "SVPWM". In low power terms, this comes down to center-symmetric PWM, typically with some midpoint shift to maximize working voltage. No magic here.- Martin

author: Martinn
author_rank: Frequent Contributor
timestamp: April 23, 2025, 06:01:26 pm
content: Quote from: Siwastaja on April 23, 2025, 05:46:08 pmI also struggled with that. SV theory was probably some academic concept relevant when there were still tubes in calculators. I also have found references to early fixed point DSPs where saving sine/cosine was a thing. Not sure though. These days it's just scaling/shifting the voltage output, but I guess the SVPWM terminology stuck.

author: Siwastaja
author_rank: Super Contributor
timestamp: April 23, 2025, 06:17:29 pm
content: Quote from: Martinn on April 23, 2025, 06:01:26 pmOf courseIt just appeared to me that SVPWM is a very recent made-up term.The original term is space vector modulation (no pulse width anywhere). Since it became obsolete at latest in the 1990's with microcontrollers having motor-control capable PWM peripherals (center-aligned, synchronized 3 PWM channels), maybe some people were afraid to just call PWM PWM, and took the Space Vector part because it sure sounds cool, and glued it in the front of PWM. And of course, if you google this stuff, you will find information about the good old Space Vector Modulation, and get super confused since it doesn't seem to haveanythingto do with how microcontroller PWM peripherals operate. Then you start wondering, what, do I need to get a freaking FPGA to implement this SVM thing, or bitbang it on MCU? Is it so much better than the obvious way of just using the PWM peripherals? And the answer is of course no, everyone uses the PWM peripheral, just that some people add random words that they don't understand and that sound cool. Like when kids learn first swear words.So in the end everybody does it exactly like I outlined above - maybe except adding the trick of shifting the PWM values to increase the maximum peak currents that can be achieved given the DC link voltage, and reduce switching losses a bit by having some switch sitting at 100% or 0% duty for a while.Now, rotor angle estimation in absence of positional measurement is a somewhat more complicated additional topic that is best avoided if possible by hardware design (having the sensors).

author: TSOL
author_rank: Contributor
timestamp: April 23, 2025, 07:03:56 pm
content: Quote from: Martinn on April 23, 2025, 05:53:07 pmCurrently Hall sensors are on the one that I have in real life, but I'm designing this board for use with a high-accuracy encoder, as I will be adding a real encoder to this motor. RLS RM44/58 are my ideal encoders.

author: Martinn
author_rank: Frequent Contributor
timestamp: April 23, 2025, 07:38:14 pm
content: Quote from: TSOL on April 23, 2025, 07:03:56 pmSounds good.What motor do you have? Best try with something low voltage/low power, so you are not electrocuted or the switches vaporized if you make a mistake. Only drawback for smaller motors is that they have very low inertia and you'll want pretty high control loop update rates if you want to attempt position control. Like run PWM, PI current control, PI velocity and position control all at 20 kHz. Not a problem with a modern microcontroller with hardware float support though.Do you have a control platform already? Proper current measurement is a thing that one needs to get right as well.Maybe get a development kit where all the hardware is at least known to work.

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 23, 2025, 08:00:16 pm
content: Quote from: TSOL on April 23, 2025, 05:04:14 pmIn SVPWM, output voltage of each leg of the driver is different from SPWM. However, the phase-to-phase voltages are the same. This can be true because a three-phase bridge has more degrees of freedom than the required two (amplitude and phase) to generate the required phase-to-phase voltages. By using the extra degree of freedom to inject a common mode component to all three phases, the driver can benefit in various ways (for example, attaining a higher driver voltage, or having lower switching losses). The motor itself doesn't notice the common mode component, so long as it provides no return path for that mode (most motors don't).SVPWM is just a tool/trick for synthesizing PWM. FOC is something entirely different (in theory FOC doesn't even require PWM at all). Though the two can be used together.

author: TSOL
author_rank: Contributor
timestamp: April 23, 2025, 08:14:07 pm
content: I have personally watched Jantzen Lee's motor control series on YouTube more than a few times, so I'm sorta familiar with the topic of FOC and SVPWM (or SVM), the biggest issue I ran into was when I was trying to simulate this. Again, I will post schematic and LTSpice Sim when I get home later today, but my big issue was that the phase currents were not balanced in magnitude. Granted, there was no current control in this simulation, but there was also no "motor" either. Just 3 inductors arranged like a motor with small resistances signifying loss. After typing this all out, reading it back makes me think that the overall current magnitude kept increasing, and this caused one phase at a given time to be way larger than the others... anyways, I'll post more later.Quote from: Siwastaja on April 23, 2025, 05:46:08 pmPerhaps this is less obvious than you think (it is to me, at least). So, if I understand the order of operations right, you apply a PWM signal based on the current position to the 3 phases (this is a locked-rotor scenario I am describing, so no rotation). This causes current to build up in all 3 phases (if applicable). You would then have a PI controller measure the current and adjust the duty cycles to raise/lower as the current approaches closer to the setpoint. I have a question here then: once they all reach equilibrium, where does the PWM Duty cycle lie?Let's say I want to command 100Apk from the motor. If I did it at the point in the image, that means one phase is 100A, and the other two phases are -50A. I read online in quite a few places that say that the "Zero Point" is 50% duty cycle. That is, commanding 50% duty cycle gets you no change in current, commanding >50% increases the amount of current in the phase, and <50% decreases the amount of current in the phase. But doesn't the same thing happen if you just apply the zero vector? E.G. If you switch the 3 phases all at 50% duty cycle, nothing will happen. But, if you have a 0% duty cycle (where the low side FET is on constantly, doesn't that do the same thing? If so, wouldn't we want to do that, as it reduces switching losses?Quote from: Siwastaja on April 23, 2025, 05:46:08 pmSuper relatableQuote from: Martinn on April 23, 2025, 07:38:14 pmI have a 10kW motor from Aliexpress, couldn't tell you the model number if I tried as I have no idea who makes it. They give you some clues on the aliexpress page but it appears that multiple different power ratings correspond to the exact same part number. It seems to be really robust though, which is very impressive. The reason it is such a massive motor (I would have gone smaller) is that they don't really make super small PMSM machines. I wanted to ensure the back-EMF was sinusoidal, so it needed to be PMSM. 1kW options do exist (couldn't find any below 1kW), but my plan was to sell this motor to a friend after I'm done testing (assuming it survives, lol). I couldn't just buy both as they're expensive enough already, and the price differential between 1kW and 10kW wasn't very high.Here's the link:https://www.aliexpress.us/item/3256807612633571.html?spm=a2g0o.order_detail.order_detail_item.3.2d20f19ccGYqRS&gatewayAdapt=glo2usaNothing is preventing me from just lowering the current limit to something sane, and the voltage is only 72 so not crazy. Shouldn't have any major risk of electrocution with that, but definitely a risk of FET failure.If by "control platform" you mean microcontroller, then yes. I plan to use whatever latest model of ESP32 (I believe the ESP32-S3?) as they are blazing fast. 20kHz is my target control frequency, and 240MHz ESP32 should be plenty to work with. The motor itself won't get past about 100Hz, so the sinusoids themselves will be super sluggish in comparison to my control frequency and my MCU.And as far as current measurement goes, I have plans for that as well. I plan on getting some pretty significantly oversized shunt resistors (10-15 Watt) to minimize heat resistance fluctuations, then using a current shunt isolation amplifier (Skyworks SI8921A) as this is what I would use when designing a larger system. Then, as the signal is larger, SNR should be better and a more general purpose differential amplifier can be used to bring it up to voltages I can compare with.Was unaware dev kits existed for a thing like this.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: April 23, 2025, 09:39:37 pm
content: Your first part about FOC is completely correct: you (attempt to) create a magnetic field in the stator, with a 90 degree phase shift with the magnetic field of the rotor. (And maintain the phase shift during rotation of the motor.I was unfamiliar with the term SVPWM, but apparently it's a normal term. See for example this document from TI.https://www.ti.com/lit/an/sprabs6/sprabs6.pdfI am not exactly sure about the difference between FOC and Space Vector modulation. They are quite similar. I think the main difference is that FOC theory assumes a motor with a (virtual) GND point, such as the stator connected in a star configuration (that has a real star point you can connect to some virtual GND). while Space Vector modulation connects one of the three poles to either the positive or the negative power supply. The currents are still (ideally) sinusoidal, but because the "GND" reference of the motor continuously switches between the positive and negative power supply, the currents in the graph look weird, because the graph can show only one reference.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: April 23, 2025, 10:47:13 pm
content: Also, there is very little difference between a PMSM motor and a BLDC motor. Apparently the main difference is that PMSM is optimized for linearity (such as for servo motors in CNC machines), while BLDC is optimized for power efficiency (and has trapezoidal profile instead of sinusoidal.But the difference between trapezoids and sines is just software, while motor efficiency is baked into the motor hardware itself.Another factor, and one I'm a bit puzzled about, is why you start with a big (10kW) motor. The theory and firmware for a 10W motor is the same as for a 10kW motor, but the hardware (motor, driver stage) is much cheaper, and if it burns out (for example due to software error) then damage is much smaller. Old HDD's are an easy source of BLDC (or PMSM, whatever) motors. If you want to get the ideal current form of an (unknown) motor, you can drive it with another motor, and put on some load resistors. Then you can measure the voltage / current waveforms.

author: moffy
author_rank: Super Contributor
timestamp: April 23, 2025, 11:19:58 pm
content: Quote from: TSOL on April 23, 2025, 08:14:07 pmFor a motor sim in LTSpice you need some way to model the back EMF, have done it for a DC motor not for an AC.

author: TSOL
author_rank: Contributor
timestamp: April 23, 2025, 11:21:42 pm
content: Quote from: Doctorandus_P on April 23, 2025, 10:47:13 pmPMSMs have sinusoidal back EMF, meanwhile BLDCs has trapezoidal. From a physics perspective, I'm not entirely sure how this is possible, but that isn't my point. The jury is out online whether or not they all are actually trapezoidal or not. Some see some BLDCs with sinusoidal back EMF, and some still claim trapezoidal.I had searched quite a bit for PMSM motors that were low power (1kW or below), and BLDC motors seemed to be the only option. Theoretically they should be basically identical, and BLDC motors are cheap enough I could easily buy one right now and pivot my project as I haven't built anything yet. I still have the big motor as I still plan to build a big driver regardless of whether I build a small one first. Difference between a 1kW motor and 10kW motor on aliexpress was less than $100, and iirc less than $50.The other thing is that the big motor is likely to be compatible with a proper encoder like the RLS RM44 series, while BLDCs tend to only be compatible with hall sensors. I have a 3d printer so I can probably make the RM44 compatible with the big motor if it isn't already by printing a bracket.Quote from: moffy on April 23, 2025, 11:19:58 pmI mean yeah but it isn't STRICTLY necessary. All the back EMF does is adjust the slew rate of the current by providing more or less voltage at the load, unless I'm wildly misunderstanding something. It shouldn't affect how the motor is controlled basically at all.

author: moffy
author_rank: Super Contributor
timestamp: April 23, 2025, 11:44:46 pm
content: Quote from: TSOL on April 23, 2025, 11:21:42 pmI think it is important because your current depends upon the difference between applied and back EMF, a very dynamic thing.

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 24, 2025, 12:26:17 am
content: Quote from: Doctorandus_P on April 23, 2025, 09:39:37 pmThe defining aspect of FOC is that the negative feedback is done within a rotating reference frame (i.e. the rotor's reference frame). The rotating reference frame (d and q) relate to the stationary reference frame (u, v, and w) via the clarke and park transforms. This allows the controller to have a bandwidth much lower than what you would need to control the phase currents in a conventional manner. For example, let's say your rotor is spinning at 10krpm, that means each leg is generating sinusoidal voltages/currents at 167Hz. With conventional control, you would need a control bandwidth much higher (like >2kHz) to get good control. But with FOC, the feedback loop doesn't see these 167Hz sine waves, it only sees torque, which changes far slower than the 167Hz seen in the stationary frame.QuoteComparing FOC to SVM/SVPWM is like comparing inductors to capacitors. They are completely different things, which complementary, not mutually exclusive.That link shows another application of SVM with three level inverters. Again, the inverters offer more degrees of freedom/modes than required by the motor, and those extra modes can be exploited for purposes besides motor control. For multilevel converters, this can be useful for ensuring that flying capacitors or capacitive dividers maintain their DC voltages. FOC can, of course, be used with multilevel inverters as well.

author: 44kgk1lkf6u
author_rank: Regular Contributor
timestamp: April 24, 2025, 01:02:44 am
content: Third harmonic injection makes the voltage on a single wire non-sinusoidal. But the differential mode voltage (say U - V or U - (U + V + W) / 3) is still sinusoidal. The common mode voltage should not affect the current. That is why the current is sinusoidal.If the current position is -10°, the current command should be 80°. The voltage command is usually calculated in the current loop. That is, a PI controller whose target is 0 D axis current and whatever Q axis current commanded by the other control loops. Exactly what the phase of the voltage command the calculation gives will depend on things like how much load there is, how fast the motor is turning, and how fast it is accelerating.

author: dukelec
author_rank: Contributor
timestamp: April 24, 2025, 03:04:07 am
content: The voltage of SVPWM is also a sine wave for the motor, but there is an additional varying common-mode voltage superimposed between the motor and the driver board. You can check out this article I wrote, which provides a very simple introduction and implementation of SVPWM:https://blog.d-l.io/svpwm

author: TSOL
author_rank: Contributor
timestamp: April 24, 2025, 04:26:33 am
content: Alright, I finally got around to getting those schematics. The first is my Sinusoidal control loop (it is just bit-banged at 50khz, which is honestly fine by me). The second is the output that I got out of it. It's a bit choppy, but since there is no Back EMF, this should be smooth as butter if it were actually built. This is at 134 Hz (which is 8000 rpm iirc), so definitely worst case scenario. I wish I had saved my schematic of the one I did with 3rd harmonic injection, but I didn't have it saved and it's too late to make it again. Imagine the exact same schematic, except it has a class D amplifier comparing a 3rd-harmonic injected sine wave to a triangle wave with literally no feedback.I am trying to figure out how to drop the PWM rates based on current. Is that something that needs to be done in software? It doesn't feel like it needs to be. I have a buck converter that I designed that doesn't use a PI controller but smoothly goes from one current setpoint to the next (load step) using both current and voltage as controls... I'll have to think on it. I'm fried now.Edit:Oops I put the inductance in wrong. Its 30uH phase to phase, so L_{ab} is 30uH, for example. The way I have currently, the phase to phase inductance is 45uH. Maybe gotta switch faster now. Also, ignore the fact that I'm feeding my comparator -5V (and therefore my D Flip flop -5V), as this was purely for simulation purposes cause it was a fast fix. The real thing will use an op amp before the comparator to shift the feedback signal from being 0V referenced to 2.5V referenced.As far as "How to read this schematic", start reading it from the right hand side. Anything to the left of the D Flip flop is for gate drive purposes, and the gate drive works great. It's got good dead time and all that. To the right of the flip flop, there is a comparator comparing the current feedback from its respective phase and a reference sinusoid. Increase or decrease the current magnitude by increasing or decreasing the magnitude of the reference signal.

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 24, 2025, 12:53:55 pm
content: Quote from: dukelec on April 24, 2025, 03:04:07 amIt's important to remember that there are many variations of SVM/SVPWM. The one you demonstrate here often referred to as the Alternating Reversing Sequence, which allows for higher utilization of the bus voltage. This is by far the most common variation of SVM, to the point that many simply refer to it as SVM. But there are other useful variations, like Null V0, which results in lower switching losses by only applying PWM to each phase for 2/3 of the cycle.Here's part of an excellent series of motor control lectures which explains the general aspects of SVM, and shows these two variations. The whole series is worth watching for those who want to understand FOC and motor control:https://youtu.be/5eQyoVMz1dY?si=EV9o86PISTSeifJW&t=402For multilevel inverters, the potential applications for SVM explode into countless variations which take advantage of the additional degrees of freedom. It's here where the vector and phase diagrams get really scary, but for basic SVM variations for two-level inverters such tools aren't necessary IMO.

author: TSOL
author_rank: Contributor
timestamp: April 24, 2025, 04:03:46 pm
content: Quote from: mtwieg on April 24, 2025, 12:53:55 pmOoh thanks for the reminder that this series exists! I was gonna watch it and completely forgot about its existence instead.

author: Martinn
author_rank: Frequent Contributor
timestamp: April 24, 2025, 04:49:03 pm
content: Quote from: TSOL on April 23, 2025, 08:14:07 pmOK... BLDC vs. PMSM - to my knowledge those are both generic terms and there is no way to know if BEMF is more trapezoidal or sinusoidal. AFAIK motors meant for 6-step control like compressor motors have trapezoidal, while precision motion servo motors have more sinusoidal waveforms. Anyway it's not black and white. To be sure consult the manufacturer. The monster you selected is probably a 6-step one, so more likely to be trapezoidal. Easy to check, turn the axle (power drill) and watch the phase voltage with a scope.In any case it does not really matter. You can control any type of BEMF with both 6-step and FOC. Only difference is that the torque ripple might be larger one way or another, which erodes a bit the gain margin (mostly relevant for position control).Once you have implemented FOC you can also discretize the rotor angle to mimic 6-step, which might improve efficiency by a few percent depending on the motor.If you are really annoyed with the torque ripple... For fun I once implemented an adaptive rotor position (note that for a multi pole pair motor, ripple will be different over the entire mechanical rotation) gain correction by keeping track of the average position controller output vs. mechanical angle. But in a production design I wouldn't have to rely on that.As I said, I'd forget that motor and go for something smaller. Maybe even 10 W. There are tons of small BLDC on Ali, however finding one with mounted encoder is not easy. Here's one I foundhttps://www.aliexpress.us/item/1005003845953240.htmlOr maybehttps://www.omc-stepperonline.com/dc-servo-motor?mfp=294-rated-power-w , remove driver and reverse engineer encoder connection.Or just a basichttps://www.omc-stepperonline.com/bldc-motor(small one!) where you can mount an encoder.ESP32: Don't know about that. I'm a STM32 developer. For motor control, you'll need a few things (PWM, ADC, calculation) to be synchronized in hardware. So my personal choice would be STM32 (G4 probably), there's tons of tools, debuggers, monitors, even the pretty sophisticated motor control library you could try out to see how things might work if done correctly (you can still program your own controller).Also I'd go for a complete STM32 kit with power stage and maybe even with motor, so you have a known good starting point to begin with. I guess attempting FOC with zero prior experience and unproven hardware might be tough.https://www.st.com/content/st_com/en/ecosystems/stm32-motor-control-ecosystem.htmlMaybe this boardhttps://www.st.com/en/evaluation-tools/b-g431b-esc1.htmland add a motor with encoder.

author: TSOL
author_rank: Contributor
timestamp: April 24, 2025, 07:04:53 pm
content: Quote from: Martinn on April 24, 2025, 04:49:03 pmOne of the first things I did was to check the BEMF with an oscilloscope and a power drill. Definitely sinusoidal. The terms are definitely both generic to some extent but from my experience, BLDC refers to motors with trapezoidal BEMF because the input waves are square (or "DC"). That was always the impression I got anyways, not sure if it's correct. So far I'm 1 for 1 though.Quote from: Martinn on April 24, 2025, 04:49:03 pmThanks for the links! I'm sure I'll come up with something to use.Quote from: Martinn on April 24, 2025, 04:49:03 pmESP32 is awesome, but programming it can be less than ideal for this kind of application. You can program it using arduino IDE (this is the way I am most familiar with, but I am sure there are other ways of doing so). The resource intensive nature of arduino code makes me a little hesitant. With STM32 (I have used STM32 as part of a class before), you know very well what your code is doing, and roughly how long it is taking to do whatever it is. The catch is, perhaps the class wasn't the most informative, but I despised that class. I did not have fun programming the STM32 MCU we had at all. I did REALLY like the interrupts on the one that we had though (very cheap model, either 32MHz or 8MHz, can't remember). Interrupts will make the STM basically the only option for me if I cannot find a workaround on ESP32 (as fixed frequency operation for the CPU is basically required to ensure "dt" is identical between encoder position polls), but this shouldn't be an issue as ESP32 is dual core, and each core has 32 interrupts. It also has hardware PWM capability (40MHz, will have to see how often that can be changed), WiFi(not necessary), ADCs with known linearity curves, fast processor for calculations(240MHz dual core), Timers and loads of other stuff. That, and ESP32 is way less expensive at like $4-5 a pop. Will definitely have to do more research.Quote from: Martinn on April 24, 2025, 04:49:03 pmThe power stage is the part I actually enjoy designing and is the major reason I took on this project. That, and I like coming up to my own solutions to problems, then learning the way the "engineering" world solves them, as I like to think about the issue first. The others (MCU and Motor) I will be buying, but the power stage will likely be designed by me.

author: Infraviolet
author_rank: Super Contributor
timestamp: April 28, 2025, 06:26:54 pm
content: Two useful tips for you:1.Virtually all outrunner brushless motors have a sinusoidal, or close-to-sinusoidal, waveform, inrunners can be trapezoidal but outrunners are effectively all PMSM type2.Just because a motor is big and high power doesn't mean you have to drive it that way in testing, so long as the current you drive through it is enough to overcome its own cogging torques it will move at a limited current, and with a limited voltage it will simply limit the speed at which the motor can be run before it's back-emf becomes high enough that the provided voltage can't make it spin any faster. Also, it is best to consider a motor's power rating and it's current rating separately, the current rating tells you how much it can cope with without overheating, at slow speeds a motor can be at the maximum long-term-permissible current whilst consuming far less overall wattage than it is rated for. A small 1000KV RC-plane-style outrunner can take hundreds of watts, but only perhaps a peak of 10 or 20 amps, if you're running it like a servo (I've done this, it can work when you add some sort of position sensor) then you can find yourself (at slow speeds) at maximum current whilst only drawing perhaps 10 watts.

author: TSOL
author_rank: Contributor
timestamp: April 28, 2025, 07:50:15 pm
content: Quote from: Infraviolet on April 28, 2025, 06:26:54 pm1. Interesting. Thank you!2. The plan was certainly not to give it full power straight off the line lol. I don't remember where I typed it, but I remember typing that I meant to do work with it at low currents first. Low currents mean low losses, but unfortunately also means current ripple accounts for a higher percentage of overall current without dropping voltage. Since it is a 72V motor, my initial plan was to test at 36V or 24V first, but honestly I may want to test even lower than that, and perhaps by a considerable amount, just to ensure the feedback loop has time to properly control it if it is unexpectedly slow by a substantial amount. Perhaps even something like 5V would be in order because motor resistance is so low. I don't have a milliohm meter yet, but my LCR meter (DER EE DE5000) says DCR is 0.00 Ohms, so sub 10 milliohms if this is to be believed. Of course, gate drive voltage would need to be sourced from somewhere, maybe I put in provisions to be supplied by a bench supply. I remember also that for the final version, I intended to have a buck controller IC (by Texas instruments) that uses external FETs and passives to drop 72V down to 15V for gate drive and then maybe a linear regulator to get down to 5V for the logic and op-amps. Then again, a 10V drop is significant enough to maybe warrant another switching converter if I have to power a microcontroller that draws a few hundred milliamps off of this...The same LCR meter provided phase-to-phase inductance readings of roughly 30uH. Of course, this varies based on rotor position but the vast majority of the readings were in the 30uH range, so this is the value I am designing around. Just FYI.Hopefully I won't be using the motor like a servo for any extended period of time. I don't have a use case where it might end up like this, but I suppose I do need to have it aligned properly for the encoder to be lined up, and one would do that by powering one phase of the motor, so I would need to have a current limit for that.Thanks for the advice!

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 29, 2025, 12:04:46 pm
content: Regarding embedded controllers, I'll throw in my anecdotal experiences:STM32: We had triedthis evaluation hardware. Worked fine, but the motor is absolutely tiny, and they don't offer any other daughterboards suited for motor drive. If you want to test at higher power then you'll need to design custom PCBs first. Also was dubious as to whether one could drive two motors, even with custom hardware.iMX RT1024: basically usedthis evaluation hardware. Overall a dumpster fire which we were forced to pursue. Even when sticking exactly to their recommended motor, their FreeMASTER debugging approach was awful, even their own FAEs couldn't figure out what was going on. If you really like NXP, go for a Kinetis instead (if they are still available).TI C2000: Usedthis main boardwiththese daughterboards. Was able to control two motors with sensorless FOC within the span of a weekend. They don't rely on a fancy GUI like STM or NXP for an interface, instead it just uses its IDE's debugging capabilities. Only downside is that the C2000 architecture as a whole is a bit weird. But it just works.

author: TSOL
author_rank: Contributor
timestamp: April 29, 2025, 01:25:53 pm
content: Quote from: mtwieg on April 29, 2025, 12:04:46 pmThanks for your input! The TI one looks nice and so does the STM. I may take a peek at them if my ESP32 doesn't work out for me. That being said, to my complete and utter surprise, the ESP32 hashardware-level support for motor control PWM.Here's the link to the part in the datasheet about this.It even specifically talks about doing SVPWM for FOC in one of the talking points! It also talks about being a good PWM source for power conversion, and since the controller is fast enough, this may genuinely be true.I love Espressif more and more, the more I work with them. It's wild, lol.

author: Siwastaja
author_rank: Super Contributor
timestamp: April 29, 2025, 04:31:57 pm
content: Quote from: TSOL on April 29, 2025, 01:25:53 pmThat's a pretty obvious feature present in nearly all except the smallest 8-bitters. All that is needed is three compare registers / output pins in a timer/counter module and a center-aligned PWM mode. Present in every smallest STM32, and most of 8-bit ATMega for example. Bonus points for cycle-by-cycle PWM termination routable from analog comparator, and deadtime generation (complementary output pins), but you can do without (software interrupts, gate drivers with deadtime generation). It would be a mistake to design a new MCU in more-than-$0.50, 20+ pins class without such timer.

author: TSOL
author_rank: Contributor
timestamp: April 29, 2025, 08:11:22 pm
content: Quote from: Siwastaja on April 29, 2025, 04:31:57 pmWell that is good because I was not aware of that.I prefer hardware dead-time generation (I'd prefer hardware everything if given the opportunity) because the hardware still functions if the MCU fails for any particular reason. Even if its a failure due to user error, that is still a short circuit that is prevented, assuming it is properly set up (I suppose the same can be said for the software!).Admittedly, I've never heard ofthisQuote from: Siwastaja on April 29, 2025, 04:31:57 pmfeature before, could you explain?

author: Siwastaja
author_rank: Super Contributor
timestamp: April 30, 2025, 07:23:38 am
content: Quote from: TSOL on April 29, 2025, 08:11:22 pmOf course, but if you look at the gate driver ICs, especially in low-cost range, nearly every one of them already does dead-time generation in hardware, so doing that twice adds no value.If you look further, you can find gate driver ICs with dead-time of zero (so basically just last resort protection against cross-conduction), or some with no cross conduction prevention at all. Or you can construct your own gate driver from discretes. Only in such cases you need the MCU deadtime generation.But ignoring really high-end designs where you want very exact configurability of dead time, you can live with the dead time generators in the most commonly used gate driver ICs.QuoteThis is one of the most fundamental things in motor controller, weird if you have missed that. It is absolutely mandatory to prevent your MOSFETs from exploding. You turn outputs off if maximum allowable current is exceeded. You will do that with:1) Dedicated hardware2) analog comparator (MCU integrated or external comparator through a digital IO pin) controlling the timer directly,3) Same as 2, but lacking timer peripheral feature, trigger software interrupt instead and there instantly bypass the timer / set the timer to 0Later you can tune your FOC PI loops such that this current limit never triggers, but during development, and in edge cases, it is pretty much mandatory.

author: TSOL
author_rank: Contributor
timestamp: April 30, 2025, 01:29:58 pm
content: Quote from: Siwastaja on April 30, 2025, 07:23:38 amVery true. Basically any half-bridge driver worth its salt has decent dead time, but if you have a high voltage range (greater than 600V), it becomes a lot harder to shop for gate drivers. This is just an example, my purpose falls well within that limit and I have no issue shopping for gate drivers. Above this point, it may seem that making your own gate driver from discretes may have some level of merit to it. At the same time, one could just get an isolated half-bridge driver for a few dollars and be good to go as well.It is not hard at all to implement dead time in hardware. You need two buffers of the original logic signal, send one into an RC filter that gets sent to another comparator that will output high when the RC filter reaches a certain voltage, and send that signal and the other one you just buffered into an AND gate. This will allow dead time for one side of the signal. To add dead time to the other, add the same circuit to the low side driver.I have done a write up on this here.It isn't a perfect circuit by any stretch, looking back I should have isolated both sides of the half-bridge and used a PNP instead of double-inversion, but you live and learn.Quote from: Siwastaja on April 30, 2025, 07:23:38 amPerhaps it is just the terminology that I don't understand. Are you just talking about OCP (Over-current Protection)? That was certainly going to be in my circuit. If one is really concerned about OCP, why not take the signal from your comparator, route a copy to the MCU and another into a 1k resistor into an NPN base. The collector should be attached to the output of the MCU, with a 1k resistor in between. This will immediately shunt all PWM activity from the MCU straight to ground through a 1k resistor, turning off your gate drive circuitry immediately. Alternatively, if your gate drive chip has an "enable" pin, it would be very easy to route it there instead.

author: langwadt
author_rank: Super Contributor
timestamp: April 30, 2025, 02:10:52 pm
content: Quote from: mtwieg on April 29, 2025, 12:04:46 pmhttps://www.st.com/en/evaluation-tools/b-g431b-esc1.html

author: langwadt
author_rank: Super Contributor
timestamp: April 30, 2025, 02:14:57 pm
content: Quote from: TSOL on April 30, 2025, 01:29:58 pmas soon as you turn off the output the OC disappear and the output will immediately turn on again

author: TSOL
author_rank: Contributor
timestamp: April 30, 2025, 02:40:26 pm
content: Quote from: langwadt on April 30, 2025, 02:14:57 pmOkay. One can make a circuit with a D flip flop that would provide a latching behavior. Run a clock from the MCU that samples the output every so often and when it goes high, it turns the circuit off. A few clock cycles later, when the MCU catches up and turns the clock off, it wont turn back on until the MCU turns the clock back on. So, it will be under your control. That is just an example (perhaps even a poorly thought out one) that I came up with in 5 minutes. There are better circuits to deal with this, certainly. Maybe a JK flip flop is better, not sure. I haven't thought about it long enough.

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 30, 2025, 03:45:28 pm
content: Quote from: langwadt on April 30, 2025, 02:10:52 pmInteresting, I don't recall seeing this back when this project was active. Ultimately our project required controlling two motors from the same MCU, so this also wouldn't have fulfilled our requirement. But for doing something like RC projects this would be awesome.Quote from: Siwastaja on April 29, 2025, 04:31:57 pmYeah from what I can tell the PWM for the ESP32 is fairly basic, I'd expect to find it in most general purpose MCUs which cost a dollar or more.At least it claims the ability to synchronize multiple PWM channels to each other, which is important for BLDC/PMSM control.Dead time generation is a pretty niche feature, only useful if you plan to dynamically adjust dead time in order to optimize efficiency and/or EMI. Most applications don't bother, in which case its better to let hardware take care of dead time generation.Being able to override the PWM outputs depending on real time events can be very useful, seems the ESP32 refers to this as "MCPWM Fault". The ESP32 apparently has one analog comparator. Unclear if it can act as a fault source for this. Unclear if this function can work on a cycle-by-cycle bases (but that's probably not useful for motor control).It's also unclear if the ESP32's internal ADC is suitable for motor control. Needs to have sufficient speed and SNR, and needs to be synchronized to the PWMs.

author: langwadt
author_rank: Super Contributor
timestamp: April 30, 2025, 04:49:58 pm
content: Quote from: TSOL on April 30, 2025, 02:40:26 pmor just use an MCU that has it all build in, like the STM

author: TSOL
author_rank: Contributor
timestamp: April 30, 2025, 06:30:51 pm
content: Quote from: langwadt on April 30, 2025, 04:49:58 pmAhhh I see your pointI must admit I am terrible with low-level coding. I learned it through my time in uni (I have used an STM board prior), but even using the manuals provided by ST, our finished code always had extra code that I felt wasn't listed anywhere in the manual, or formatting of said code wasn't necessarily obvious.I had a good deal of help from classmates in that class. I learned coding through Unity doing game dev (I was never good) and learned a bit more through Arduino, then learned a bit of C.This is to say, those assignments (even as simple as turning an LED on/off) were very difficult for us as a class (mix of EE/Comp E) and took multiple hours. I have a hard time justifying the development time of doing it in software when it takes a few minutes to add it to the schematic in hardware. I am not constrained by time as this is a personal project, but the less late nights sitting at my computer trying to get code to compile, the better. Admittedly, there is no harm in being a less-terrible digital engineer, but I avoid digital like the plague if I can.It's a skill I will have to learn eventually, but when... I'm not sure. Perhaps now is a good time, but where to start?

author: Martinn
author_rank: Frequent Contributor
timestamp: May 01, 2025, 05:36:09 pm
content: Quote from: TSOL on April 30, 2025, 06:30:51 pmMotor control needs some realtime basics that you just can't do in an Arduino while(1) loop. If it's a consolation, even as a professional I don't really like STM32 peripheral coding. There are several thousands of pages of documentation (I can give you some pointers on what you most likely have missed) and making many peripherals work together is a time consuming challenge.Here's what you need:Set up a timer for generating a center aligned PWM.Have the timer center position trigger an ADC sequence measuring the currents (at precisely the same position, mid of low period if you do low side sensing)Set up DMA to write the ADC results in a bufferSet up an interrupt after DMA completionYes, it is some effort to make it work, but a G4 (or even a F1) is made for that, there is a code generator, the STM32 forum, google search and with luck AI to help you.Key is that everything is linked in hardware. No polling or asynchronous buffering - any jitter will ruin controller performance. Low latency is the key ingredient to high performance control. Run everything at PWM rate 20 kHz, any processor with floating point hardware will do.Scale every value to physical units directly, work with Amperes not ADC counts.In the interrupt, you runPosition control PIVelocity control PIPark/clarke transformD/Q PI current controllersInverse P/C transformMapping to PWM including centering/midpoint shift (zero sequence modulation)Write to PWMYou wrote you'd like to to your own driver and current measurement. That's not a big thing unless you go high power. But as you seem to be a total beginner, in your place I'd reduce possible failure points at the beginning.Get ahttps://www.st.com/en/evaluation-tools/p-nucleo-ihm03.htmlIHM03 board and get it running (possibly with your own motor with encoder). Design your own driver board and simply swap it with the original one.With luck you can even use their demo code where all peripherals work already as intended (wouldn't count on that though).

author: TSOL
author_rank: Contributor
timestamp: May 01, 2025, 07:08:55 pm
content: Quote from: Martinn on May 01, 2025, 05:36:09 pmCertainly, I had no intentions of doing so. My plan was to set an interrupt to run every X microseconds, and call a function every time it interrupts to grab the motor currents and recalculate PWMs. Any extra actions were to occur past this point. PWM frequency was either gonna be 20khz or 50khz (probably 50k if I can swing it, motor inductance is rather low). I got a script to output the sine function into an array so I can copy-paste it into my code. I'd rather have a huge array of each degree of sine than have to calculate it every cycle.Quote from: Martinn on May 01, 2025, 05:36:09 pmYeah it isn't always the most enticing activity to spend 6 hours coding like this:That's actually why I quit my comp sci degree and swapped to EE haha. Any pointers you can offer would be greatly appreciated when they arise. It will be at least a few weeks before I get any prototype boards to test with given how long OshPark's lead times are, I will post updates to this thread when I get themQuote from: Martinn on May 01, 2025, 05:36:09 pmI'm certain I will ask more questions about this stuff as I'm not super familiar with how hardware interacts with software like this. What I mean is: I don't understand "what's going on" when I make a file with a few variables and somehow a timer starts working.Every company is going to do this process differently as far as I am aware, so knowing what is required to make a function work (like a timer) is most of the battle.Quote from: Martinn on May 01, 2025, 05:36:09 pmDefinitely was planning to link everything I possibly could in hardware, and anything extra could be processed on the other core to keep cycle times as low as possible (I'd imagine that's possible, haven't looked into it yet). I'll need to look into what kind of datastream I want from this encoder I plan to get, they can be configured with like 14 options. I'm thinking I2S or I2C. Uart is an option as well.Quote from: Martinn on May 01, 2025, 05:36:09 pmYup, that sounds exactly like what my plan was for this MCU. Any extra stuff towards the end, but if it was gonna take too long, it was going to have to be put on another core or even another MCU entirely.Quote from: Martinn on May 01, 2025, 05:36:09 pmI'm not entirely certain what you mean by "high power". Like 1kW+? 10kW? 100kw()?I've been studying motor control for a while now and I built my first H bridge a few years ago. It had some issues where the FETs would die shorted always conducting in the same direction. The gate drivers would die too (which was likely the bigger issue), and a guess is that a voltage transient made it through the gate driver and destroyed the gate of the FET, turning it on permanently. It NEVER failed in a shoot-through fashion, it ONLY ever failed with two mosfets shorted on, making the motor spin permanently. When this driver was designed, the switch node size was not optimized so there was about 1 inch between the source of one FET and the drain of the other. I also didn't use any ceramic caps (I did use electrolytic). My idea is that this may have caused some inductive ringing, but I never saw any on the oscilloscope and at the currents I was working at, it would be little more than a few milli/volts. I used 30V FETs on a 12.6V motor/supply, so surely there couldn't have been too much issue. This motor was for an RC car, so perhaps the ~25V experienced for a brief moment in time when immediately swapping polarity is what killed everything?All I know is that it took forever to solder the boards and it wasn't a guarantee that doing that would kill them. I went through probably 6 PCBs this way. When the board wasn't blowing up though, it worked exactly how I wanted it to. The motor controlled exactly how I designed it to and nothing ever got hot, there was apparently just some catastrophic issue somewhere.Anyways, the point of this is to say that I'm trying again with an H-bridge for a 12V motor. Just got done soldering the majority of it yesterday, will test it today if I get time. If I can't get a 12V brushed motor driver layout right, there's absolutely no reason I should be trying for anything higher power than that. The schematics of the revised version are below. I'm not sure how much you're into PCB design, but if you see any glaring issues, I more than welcome you to add any critiques you see. I had a group of others from a different thread give me criticism already, but the more, the better.

author: Martinn
author_rank: Frequent Contributor
timestamp: May 02, 2025, 06:26:13 pm
content: Maybe one more thing to consider when you choose the toolchain.With control system development, you need both good monitoring (graphical real time data of e.g. step responses) and real time parameter tuning. That means if you tune any of the many parameters in the system (like PI current control P and I gain), you need to be able to enter new parameters and see the result graphically. Edit-compile-download cycle is far too inefficient for this.ST has the CubeMonitor for the realtime graphical display and the CubeIDE can both show and update parameters in realtime.Of course you can write your own software to do this, that just adds to the effort.

author: djsb
author_rank: Super Contributor
timestamp: July 14, 2025, 08:55:57 am
content: Interesting reading. Has anyone used Microchips MCU's for motor control? They seem to have quite a wide offeringhttps://www.microchip.com/en-us/solutions/technologies/motor-control-and-driveI only mention this as I'm most familiar with PIC's and so it maybe would be easier for me to learn more about advanced motor control if I stuck with what I already know. I wonder if small drones mainly use BLDC motors. I also have noticed that AC synchronous motors are used in CNC applications. Using have voltage/current motors are a non-starter for me and the students I work with.PS, I'm not trying to hijack the thread. Hope I've not upset anyone.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 14, 2025, 09:03:54 am
content: Quote from: djsb on July 14, 2025, 08:55:57 amAny microcontroller is fine, really. Ignoring some of the very smallest/simplest that do not have three PWM generation units that could be synchronized together, or even an ADC. But any MCU which mentions motor control is going to have the necessary peripherals. Rest is software so applies regardless of brand, and any MCU made in 2000's has enough CPU performance to do the necessary calculations.AC synchronous and BLDC are basically the "same thing", with potentially small differences in physical construction leading to small differences is optimal waveform for minimized torque ripple, but this is more about fine-tuning than a fundamental difference, you don't need to think about it in the beginning at all.

author: motor-guy
author_rank: Newbie
timestamp: August 21, 2025, 08:20:11 am
content: @TSOLI worked on a similar project recently and thought I’d share a few hardware tips that might help:1. Keep PWM around 20kHz or lower – Higher frequencies (like 50kHz) make PCB layout more challenging and can cause waveform distortion or even board damage if not done right. Also, at higher frequencies, you may need to compensate for inverter non-linearity in software (e.g., dead-time insertion is a non-linearity for example).2. Check if your PWM frequency suits the motor – Use the formula: motor PWM frequency should be 10xR/2*pi*L . If your motor inductance is 30uH and resistance is 300 milli ohms, the required PWM frequency is ~16kHz.3. MOSFET voltage rating – Choose MOSFETs rated for at least 2× your DC bus voltage4. Current sensing – It’s best to use an external op-amp. While many MCUs have internal amps, they require very careful ground layout to avoid noise issues.TI has some great motor control PCB layout resources. Pay special attention to minimizing inductance in the gate-driver to MOSFET return paths and the DC link cap returns.