# Open loop 6 step PWM generation

**URL:** <https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503>\
**Category:** Uncategorized\
**Created:** [February 23, 2024, 7:50am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503 "2024-02-23T07:50:56Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ara\_FOC](https://community.simplefoc.com/user_avatar/community.simplefoc.com/ara_foc/32/6205_2.png) [@Ara\_FOC](https://community.simplefoc.com/u/Ara_FOC)\
**Post date:** [February 23, 2024, 7:50am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/1 "2024-02-23T07:50:56Z")

</div>

Hi,  
To understand better SimpleFOC I decided to recode the Open Loop 6 step commutation software on my stm32 with CubeIDE.  
My question is how SimpleFOC software is generating 3 shifted PWM signals from the same timer ?  
Is it linked with CCR values ?  
Thanks

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 8:23am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/2 "2024-02-23T08:23:19Z")

</div>

Have you checked the [documentation](https://docs.simplefoc.com/bldcdriver) ?

---

<div class="post-metadata">

**Author:** ![Owen\_Williams](https://community.simplefoc.com/user_avatar/community.simplefoc.com/owen_williams/32/105_2.png) [@Owen\_Williams](https://community.simplefoc.com/u/Owen_Williams)\
**Post date:** [February 23, 2024, 10:11am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/3 "2024-02-23T10:11:05Z")

</div>

Yep - you are right about it using CCR:

> <https://github.com/simplefoc/Arduino-FOC/blob/6eed7b00c9bc1e9f7ea7984aa02a9f7ea98db19b/src/drivers/hardware_specific/stm32/stm32_mcu.cpp#L42>

All 3xpwm are on the same timer (different channels), all centre aligned. All pwm running at the same frequency. From this perspective they are not shifted.

They share an autoreload count I forget the exact calculations but it somthing like pwm clock / desired PWM frequency \* 2 . e.g 60mhz/20000 \* 2 = 1500. The 2x is because centre aligned counts up then down taking twice as long). So every 3000 counts the timer will start at zero go up to 1500 and back down to 0.

Now we just need to change how long each channel is activated for. This, I think is done in capture/compare register. With 6 step commutation - assuming 120 degree trapezoidal, We have 3 states ON/OFF/HIZ e.g. looking at electrical angle 0 → 360

```auto
angle dutyA, dutyB, dutyC
0-59 1500, 0, Hi-Z
60-119 1500, HI-Z , 0
120 - 179 HI-Z, 1500, 0
180 - 239 0, 1500, HI-Z
240 - 299 0, HI-Z, 1500
300 - 359 HI-Z, 0, 1500

```

The above will be using full voltage (dangerous!) . For Hi-Z it could be set to zero (from a timer perspective) but we have disabled that phase (assuming your gate driver has the capability of putting each phase to hi-z).

Take the above with a pinch of salt (be careful) - I’m just a hobbyist not an expert. If your gate drive doesn’t have shoot through protection, then I wouldn’t try this out as you’ll likely damage your mosfets before you work out the correct pattern.

The above assumes a 3PWM. You’d need to adjust for 6PWM

---

<div class="post-metadata">

**Author:** ![Ara\_FOC](https://community.simplefoc.com/user_avatar/community.simplefoc.com/ara_foc/32/6205_2.png) [@Ara\_FOC](https://community.simplefoc.com/u/Ara_FOC)\
**Post date:** [February 23, 2024, 11:04am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/4 "2024-02-23T11:04:04Z")

</div>

Thank you very much.  
Thanks for the caution advices, for now I don’t use any power, just my nucleo board and oscilloscope so I shoul dnot burn anything.  
I am using 3 PWM too.  
The thing I don’t get on your explanation is “now we just need to change how long each channel is activated for”. For me, if we change that we change duty cycle, so each phase won’t be activated for same time on a period. And in my opinion that is not what we should aim for. But I may be wrong.  
Thanks!

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 11:06am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/5 "2024-02-23T11:06:29Z")

</div>

What you look for is called space vector pwm or svpwm. Look it up

---

<div class="post-metadata">

**Author:** ![Ara\_FOC](https://community.simplefoc.com/user_avatar/community.simplefoc.com/ara_foc/32/6205_2.png) [@Ara\_FOC](https://community.simplefoc.com/u/Ara_FOC)\
**Post date:** [February 23, 2024, 11:11am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/6 "2024-02-23T11:11:45Z")

</div>

I think SVPWM is the use of V0 and V7 vectors to be able to virtually lower the Kv value of the motor, I am not sure that this is needed to implement the simple open loop 6 step control. But I may be wrong.

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 11:16am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/7 "2024-02-23T11:16:51Z")

</div>

6 step and svpwm are just 2 types of modulation  
It’s all handled here

> <https://github.com/simplefoc/Arduino-FOC/blob/master/src%2FBLDCMotor.cpp#L478>

---

<div class="post-metadata">

**Author:** ![Ara\_FOC](https://community.simplefoc.com/user_avatar/community.simplefoc.com/ara_foc/32/6205_2.png) [@Ara\_FOC](https://community.simplefoc.com/u/Ara_FOC)\
**Post date:** [February 23, 2024, 11:35am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/8 "2024-02-23T11:35:28Z")

</div>

Ok, so my precise question is : do you know ho pwm are generated at the stm32 timer level to do a 6 step commutation ?

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 11:39am UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/9 "2024-02-23T11:39:42Z")

</div>

the code I shared calculates the duty cycles.  
Owen shared how the duty cycles are applied to the timer channels.

---

<div class="post-metadata">

**Author:** ![runger](https://community.simplefoc.com/user_avatar/community.simplefoc.com/runger/32/395_2.png) [@runger](https://community.simplefoc.com/u/runger)\
**Post date:** [February 23, 2024, 12:07pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/10 "2024-02-23T12:07:01Z")

</div>

> [@Ara\_FOC](#):
>
> do you know ho pwm are generated at the stm32 timer level to do a 6 step commutation ?

The library does not support 6-step commutation.

Setting the PWM to the timers is not a big problem, it’s just unfortunately very complicated to configure the timers in STM32 HAL. Owen has already linked the code that does it.

The problem is to know _when_ to switch between the steps in 6-step commutation. Normally this is done by BEMF sensing, which our library does not support. With BEMF sensing, you can detect the BEMF zero-crossings and use these to drive the switching between the 6-step states.

If you decide to implement this in combination with SimpleFOC, we would be very happy to see your results!

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 12:11pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/11 "2024-02-23T12:11:07Z")

</div>

isn’t 6step just trapezoidal ?

> **[Six Step Commutation - Generate switching sequence for six-step commutation...](https://fr.mathworks.com/help/mcb/ref/sixstepcommutation.html)**
>
> The Six Step Commutation block uses a 120-degree conduction mode to generate a switching sequence to implement six-step commutation (or trapezoidal commutation) on a three-phase BLDC motor.

---

<div class="post-metadata">

**Author:** ![runger](https://community.simplefoc.com/user_avatar/community.simplefoc.com/runger/32/395_2.png) [@runger](https://community.simplefoc.com/u/runger)\
**Post date:** [February 23, 2024, 12:21pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/12 "2024-02-23T12:21:42Z")

</div>

In principle it has the same pattern as what we have in FOCModulationType::Trapezoid\_120. So if you just want open-loop 6-step commutation, then you can just choose this modulation type.

But for closed loop, the expectation is normally that 6-step is driven by BEMF detection, and not a position sensor. That’s the part we don’t support. If you’re happy to read a position sensor, and drive the 6-step based on that, then again you can just choose the modulation type FOCModulationType::Trapezoid\_120. But personally I don’t see an advantage here for most setups compared to the default SinePWM modulation.

---

<div class="post-metadata">

**Author:** ![Candas1](https://community.simplefoc.com/user_avatar/community.simplefoc.com/candas1/32/5296_2.png) [@Candas1](https://community.simplefoc.com/u/Candas1)\
**Post date:** [February 23, 2024, 12:23pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/13 "2024-02-23T12:23:17Z")

</div>

I think he is just learning/experimenting, so he started with open-loop 6step.

---

<div class="post-metadata">

**Author:** ![Ara\_FOC](https://community.simplefoc.com/user_avatar/community.simplefoc.com/ara_foc/32/6205_2.png) [@Ara\_FOC](https://community.simplefoc.com/u/Ara_FOC)\
**Post date:** [February 23, 2024, 1:11pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/14 "2024-02-23T13:11:21Z")

</div>

Thanks for you support !  
As Candas said, in fact I am for now just doing some open loop, but yes if one day I have bemf foc results I won’t forget to show you.  
For now my question was just how the pwm is generated at the controller level. I wasn’t able to see that directly on Owen’s code but I am investigating.  
Thanks.

---

<div class="post-metadata">

**Author:** ![VIPQualityPost](https://community.simplefoc.com/user_avatar/community.simplefoc.com/vipqualitypost/32/4420_2.png) [@VIPQualityPost](https://community.simplefoc.com/u/VIPQualityPost)\
**Post date:** [February 23, 2024, 2:13pm UTC](https://community.simplefoc.com/t/open-loop-6-step-pwm-generation/4503/15 "2024-02-23T14:13:43Z")

</div>

> [@Ara\_FOC](#):
>
> For now my question was just how the pwm is generated at the controller level.

Please read the documentation for STM32 timers. The PWM is generated by the timer (hardware peripheral), so there is no real firmware involvement to drive the PWM as in bit banging. You just set some configuration bits and away it goes. The firmware is then just adjusting the CCR registers so that the PWM output is sinusoidal.
