Hoverboard main board with simpleFOC

You can #define whatever you like, it does not have to over-write anything. Try adding #define Rumpelstilzchen!

The reasons that some defines change program behaviour is because the code is written using them as control statements to change what parts of code are compiled.

OK, but it would only be valid after that line (locally)

If you want to globally define Rumpelstilzchen (during and after compilation) you can add it in the build flags, like this:
-D Rumpelstilzchen
Which is more what @runger was talking about earlier with the compliler/ linker.

OK, now what about the gate signals? The H_in is high active, the L_in is low active. To me it looks like I get a through-shoot with that pattern?

If they are inverted logic (which you said they are?) then it looks fine, although the time between switching (dead time) does look a little short, but this could be an artifact of the oscilloscope too. I might just hook a motor up and give that a try, with a low max current.

Yes, you need to globally define the low side active-high flag to false…

However, your fortior driver will prevent the shoot-through, normally. Best not to stress it out too much though :wink:

That’s what I read from this graphic. They always reference LIN with an * which is also a sign of being inverted

You are right, I tried to overwrite it in my code, but it doesn’t change… :blush:
Time to dig deeper
Found the definition in hardware_api.h and boldy set it to false. Et voilá

I also increased the dead-time and reduced PWM-frequency to 25kHz
Do we have a winner?

1 Like

Yes we have!
:fireworks: :partying_face: :sparkler:
It spins smooth at lower speed, but above target_velocity =25 it sound like it looses sync sometimes. (misfires)

Thanks again today for all the help. You are great!
:+1:

1 Like

I am actually using the same sketch on a gd32 single controller and a stm32 dual controller(with only one motor).
I completely forgot that I am using 16Khz as default for the gd32 driver, but I think the default for the stm32 driver is 25Khz.

Be careful not to saturate the waveform.

I use this with SVPWM

motor.voltage_limit = driver.voltage_power_supply * 0.58;

and this with SinePWM

motor.voltage_limit = driver.voltage_power_supply * 0.50;

An that’s also my maximum voltage target.

Here is a comparison I just did of the consumption at different PWM frequencies on those motors:
12000Hz → 0.208A 7.82-7.9 rad/s
14000Hz → 0.210A 7.76-7.84 rad/s
16000Hz → 0.211A 7.64-7.74 rad/s
18000Hz → 0.213A 7.6-7.68 rad/s
20000Hz → 0.215A 7.5-7.6 rad/s
22000Hz → 0.217A 7.44-7.54 rad/s
24000Hz → 0.222A 7.5-7.4 rad/s

As I increase the PWM frequency, the consumption increases and the velocity decreases.
So I think the efficiency is reducing because of the switching losses.
The deadtime represents a bigger and bigger proportion of the pwm period.
12Khz is too low, there is audible noise.
Usually we use 16Khz with those motors.

That’s probably good for the M4 core, but mine only runs at 48MHz IIRC. I should go lower,too.

I’ve seen the deadtime is expressed in %.
It varies with frequency or duty cycle?

Foc is not running at that frequency, so you don’t need a faster mcu to set higher pwm frequency.

Hmm, yes deadtime is a percentage of the pwm period in simplefoc, which is a bit misleading because it means if you change the pwm frequency you should also change de deadtime.

So during my test, while increasing the pwm frequency, the deadtime should decrease? :thinking:

[EDIT] I need to try with gd32, there I have a fixed deadtime

I think the dead time is a percentage of the full scale voltage, which is the PWM range, not the period. It should not have to change when you change the PWM frequency.

Look here

You’re right, but this is probably a bug. I have to think about whether it’s the correct or only way to do it when using STM32 hardware dead-time.

If you check the software dead-time implementation, you’ll see that the “percentage”, which is really out of 1.0f, is applied directly to the output duty cycle, meaning its interpretation is like a voltage, or proportion of the PWM range.
I believe the other drivers should work in the same way.

I think the conversion based on duty cycle is a special case, a way to convert it into a time, since the STM32 HAL APIs want a number in nanoseconds.

But thinking about this more, this is really a total mess, since in STM32 we work with a fixed PWM range, but most of the MCU types the PWM range varies with the PWM frequency.

So on STM32 HW dead time and maybe some other MCUs the duration of the dead-time will vary with the PWM frequency. That’s not really the point of it!!

I propose we fix this in the next release, and make all the architectures work in the same way. In addition, we could add in your dead-time compensation, if you feel its ready then :slight_smile:

1 Like

Yes that will make much more sense.
One thing I was also thinking about is a kind of target correction in the same way phase_resistance is used in move() function.
In voltage mode, when your target is 3v, you’re not really getting 3v because of the deatime, and you will actually never reach the power supply voltage. You could add the deadtime (twice?) to the the target.

Does this mean maximum RPM usable with SinePWM is only half of battery voltage x kv?

No no.
The amplitude is half, but the phase to phase voltage is higher.
It’s explained well here.

1 Like

Based on @Candas1 recommendation yesterday, I changed the PWM frequency to various other frequencies.
To me it seems the frequency setting is similar to BAUD-rate: You can’t just set any value.
It has to fit in the timers and MCU clock schedule, right?
If we’ve found the sweet spot for the specific MCU, you should only go higher or lower by binary factors (2x, 4x, 1/2, 1/4 etc)

//edit Somehow I can’t make my motor run smooth anymore. There must have been some Gremlins at work last night.
I tried to set all parameters as they were yesterday, but the motor runs jerky and won’t spin fast. I even re-activated my heartbeat LED-sgnal with delay(100), because I thought, maybe the loop refreshes too often.