I'm making a ESC for my BLDC motor. I used a STM32 (to generate my PWM), 3 IR2101 mosfet drivers (https://www.infineon.com/dgdl/ir2101.pdf?fileId=5546d462533600a4015355c7a755166c) and 6 mosfets to control the differents phases of the motor.

My schematic:

enter image description here enter image description here

I generate my phase with a PWM on the High side and a GPO on le Low side.

HIGH side of my PWM (phase A,B and C)

enter image description here

PHASE A (going below 0V!)

enter image description here

The signal seems correct but when I connect my motor we can see that the BEMF is backward compared to a good BEMF.

PHASE A B C enter image description here

BEMF A B C enter image description here

I try to change the frequency of the PWM, change the duty cycle or the delay between each phase but nothing change (and sometime it's worse...). Do you have an idea why ?

My STM run at 8MHz. PWM frequency : 900Hz with a duty cycle of 5%. During this test my motor consumes 12V / 0.8 A.


I don't know why my BEMF is reversed compared to a good one. enter image description here

Below you can see my phase C (yellow), the virtual ground of my motor (light blue), the mathematical operation Phase C - Virtual ground (dark blue) and the output of my LM339 (pink). enter image description here

I saw multiples subject about this problem on Stack exchange but each time the answer isn't clear. (enter link description here).

I guess that my PWM and BEMF aren't 'in phase'.. I need some explanations.

  • \$\begingroup\$ You have two images showing bemf and you say one is good and the other isn't. What differentiates those two images in terms of electrical stuff like loading or unknown things and, what makes you think the last image is somehow problematic whereas the previous one wasn't. \$\endgroup\$
    – Andy aka
    Commented Nov 5, 2020 at 18:48
  • \$\begingroup\$ The second image is the voltage of the PHASE A, B and C. The third image is BEMF_A, B and C. Check the schematics is you want to see the difference :) . I don't understant why the BEMF is so low (1V) and so noisy... \$\endgroup\$
    – E.T
    Commented Nov 5, 2020 at 23:03
  • \$\begingroup\$ Back EMF is the phase voltage. Explain exactly how you are taking the two measurements - eg, are you measuring after your divider? Also zoom in and look at a particular commutation cycle in detail. \$\endgroup\$ Commented Nov 6, 2020 at 16:54
  • \$\begingroup\$ I know that Back EMF is part of the phase voltage. What I don't know is why my BEMF is reverse and noisy... \$\endgroup\$
    – E.T
    Commented Nov 7, 2020 at 17:22
  • \$\begingroup\$ Are you using hall sensors to determine when to switch? Could they be off somehow? \$\endgroup\$
    – user57037
    Commented Nov 10, 2020 at 4:03

2 Answers 2


Welcome to StackExchange! Well done first post.

You are correct, your forcing voltage is out of phase with your motor.

Looks to me like you are sampling in the incorrect location during your PWM cycle. Ensure that your ADC sample occurs at the center of the PWM cycle when the PWM cycle is high. There may be a minimum duty cycle required in order to get a proper sample, but that may not be the case as 900Hz is a pretty low frequency.

It is difficult to surmise from your scope screenshots, but it appears that the phase is negative going on the low side of your PWM and positive-going on the up-side of your PWM... so your code is likely doing exactly what you are telling it to do, but in the wrong place in the cycle.

I like to check my interrupt timing (roughly) by setting up a pin to turn on when the ADC interrupt starts and turn off when the ADC interrupt ends. I can usually gather good information from that.

If you verify/fix your ADC sample time, and the problem persists, then post a screenshot of one phase as it is rising, full-scale Y-axis.

Stick with it! Problems are solved by putting your head down and working at it. But remember to walk away and get some sleep. Problems look very different in the morning!

edited to add

Based on your comments, I am getting the sense that there may be some basic misunderstandings (I may be wrong).

Calculating Neutral Voltage

First off, you don't need to measure a neutral voltage. This is a wasted ADC module. You can calculate your neutral voltage: neutral = (phaseA + phaseB + phaseC) / 3;. Recommend you convert that to a fixed-point notation for speed, but the math is correct. Now that is one less ADC that you require!

Your neutral looks pretty much correct. If you mentally do the math that I just described, you will see that the neutral voltage is indeed the average (or very nearly) of the phase voltages.

Configure Registers to do the Work

Next, if you configure your TIM1 and ADC12 registers in center-aligned and triggered at the peak of counter mode, then no calculation is necessary to sample correctly.

When to Commutate

In your comment, you wrote

if the floating phase - the virtual ground = 0. If it's true, then I theoretically know the duration to wait before commutating the next phase to high

This is true only half the time and I just want to word it with clarity. Note that the BEMF phase is alternating between rising on one phase and falling on another.

    if(phaseVoltage > neutral)
    if(phaseVoltage < neutral)

If you correctly implement the above code, you will be able to operate the motor, but 30 degrees advanced. Believe me, it will look much better than it does in your screenshots.

Further Work

If you get this far, I will leave it to you to determine how to shift the commutation event by 30 degrees.

  • \$\begingroup\$ For now, I'm driving the motor in open loop because when I measured my BEMF - my VIRTUAL GROUND I don't have a trapezoidal curve. I added some graph in my question about that. \$\endgroup\$
    – E.T
    Commented Nov 10, 2020 at 17:30
  • \$\begingroup\$ Thanks for your help ! Thanks to your answer, I'm going to change my schematic and send the BEMF and the virtual ground to differents ADC of my uC (it's easier to process). According to your answer, I have to check each time my PWM go high, if the floating phase - the virtual ground = 0. If it's true, then I theoretically know the duration to wait before commutating the next phase to high. \$\endgroup\$
    – E.T
    Commented Nov 10, 2020 at 18:00
  • \$\begingroup\$ Use center aligned PWM and trigger your ADC when the PWM timer is at zero or max, depending on other registers. Much less calculation. \$\endgroup\$ Commented Nov 10, 2020 at 23:31
  • \$\begingroup\$ Edited answer to add more info. \$\endgroup\$ Commented Nov 11, 2020 at 1:59
  • \$\begingroup\$ Thank you ! :) Now, I'm able to detect when the bemf cross the zero line. \$\endgroup\$
    – E.T
    Commented Nov 12, 2020 at 22:05

E, I am curious about this case and I have suspicions. Can you post the data for your motor, please ? Poles, Kv, Rs, Ls. I need them to confirm my suspicions with simulation. In general I think that your motor is running out of synchronization. Your caps on the BEMF dividers seems to be too large. You will get big delay in ZC detection and this will distort the wave. Also your 30 degrees delay after ZC is wrong. Thank you. I guessed some motor and the simulation looks like this: waves the LTSpice circuit

  • \$\begingroup\$ Hello Fobi, when you say "running out of synchronization" do you have a idea of a good timing ? Because I tried to control a BLDC motor with hall sensor and I had the same problem (my bemf was reversed). Characteristic about my motor : KV: 4000KV Watts: 400 Max Voltage: 12.6V Max Amps: 32A Resistance: 0.012 Max RPM: 50000 Poles: 4 \$\endgroup\$
    – E.T
    Commented Feb 19, 2021 at 11:05
  • \$\begingroup\$ Hello E*T. The question is not quite right. You can detect ZC with comparator or ADC. After ZC detection the code must introduce 30 degrees delay. You can also detect when to switch the bridge step with hall sensors or encoder. No need of delay here. If you are using comparators the best way to introduce the delay is to use BEMF integration method. If you are using ADC the best way is to measure the time between ZC and delay the switching with Tzc/12 or 30 degrees. I'm on two weeks trip and is hard to be more detailed answring from a phone. See you soon, cheers. \$\endgroup\$
    – fobi
    Commented Feb 21, 2021 at 9:59
  • \$\begingroup\$ Hi Fobi, yes i know that I don't need a delay between the rising/faling of the hall sensors and the switch of the bridge. However I have implemented an algorithm to control my motor(bldc with hall sensor) and I switch my phase depending of the rising/falling of the hal sensors. The process between the detection and the switch of the bridge takes 15us (limitation of my microprocessor). Maybe this 'delay' is too long and that is why my BEMF is reversed. \$\endgroup\$
    – E.T
    Commented Feb 22, 2021 at 12:55
  • \$\begingroup\$ I think there is additional delay in your code. Vemf=VsDuty sqrt (3)/2. Fe=Vemf*Kv*(poles/120)*(2/sqrt(3)). T30=Fe*12. Or Fe=12*4000*4/120=1600 Hz in your case with maximum speed. The 30 Deg delay should be less than 52us. \$\endgroup\$
    – fobi
    Commented Feb 23, 2021 at 11:04
  • \$\begingroup\$ Hi Fobi, I'm driving my motor with hall sensors I don't need to add 30 degrees delays no ? I'm confused with your last comment. I need to switch my bridge when one of my hall state change (without any delay) \$\endgroup\$
    – E.T
    Commented Mar 1, 2021 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.