PWM Deadtime compensation

The waveform link doesnā€™t work for me

Oups, can you try again ?

Anybody interested in giving this a try ?
It should already give good results in openloop at slow speed/low load.
I just want to make sure I am not fighting with a problem only I have with my setup.

I can summarize what I did so far.

I declared a global variable for deadtime compensation so I can update it and observe the waveform.

float dtcomp = 0;

Here I added the code for the deadtime compensation.

if (dtcomp > 0){
  center = driver->voltage_limit/2;
  Ua += (Ua > center ? 1:-1) * dtcomp;
  Ub += (Ub > center ? 1:-1) * dtcomp;
  Uc += (Uc > center ? 1:-1) * dtcomp;
}
// set the voltages in driver
driver->setPwm(Ua, Ub, Uc);

Here, I compensate the voltage command so that the amplitude is same with or without the deadtime compensation.

if (dtcomp > 0 && abs(dtcomp) > abs(Uq)) Uq -= _sign(Uq) * dtcomp; 

I ended up compensating for 0.70V, which in my case is almost the power supply voltage * Deadtime% * 2.
I am not sure if itā€™s a coincidence, based on this paper I am compensating both for the deadtime and the stiction.

A supplementary test using a current
sensor and the torque sensor on motor M4 found that, while
current production starts at d = 0.071, external torque is not
felt until d = 0.083. This indicates that the deadtime ddt =
0.071 is the deadtime duty cycle for this motor driver and the
stiction is dst = 0.012 or Vst = 60 mV at the tested location

I want to experiment by checking at what minimum pwm duty cycle the current starts flowing, and at what minimum pwm duty cycle movement is visible. I think this could even be measured by software.

This method is not taking all the ripple/cogging sources as does the anticogging map mentioned in the paper, but can probably already give good results with little tuning without an encoder.

@runger I believe this thread was created because of the deadtime compensation discussions, but please feel free to move my posts to a new thread if you think it doesnā€™t belong here, because I have more bla bla and screenshots coming :rofl: Thanks in advance

Iā€™m interested in the stiction-compensation part, because a windturbine likes no_load conditions to start. But Iā€™m not planning to use this ESC1 board.
I guess the code is universal for other powerstages as well? At least, when they use the same current sensing method?

[OT]
Iā€™m surprised to see everyone playing with this evaluation board. To me it seems, it has major issues with excessive heat under load?
Currently Iā€™m looking for the most mature mid-power range controller availableā€¦and the list of candidates is pretty short :frowning:

I think the effect of deadtime is relevant for any board.
The stiction might depend on the motor.

Bring them on!! :smiley:

From my point of view this is all fine, but if you want me to split the thread or something, let me know.

No wonder given the price of this (subsidized) hardware!
I think people underestimate the difficulty of interfacing with its minuscule solder pads, and donā€™t check the integration options (eg no SPI) in advance, because itā€™s actually quite complex to do soā€¦

I believe Valentine has produced an updated design, renamed to Quadrans, thereā€™s a forum post about itā€¦
Iā€™ve done an updated version based on the STM32G431, which Iā€™ll test and then share as soon as I can.

@Anthony_Douglas what do you say? Itā€™s your thread

Uh oh, IDK, take the discussion however you like, it will not undo what has been done, people can still read the stuff above, which mostly answers the question of how to change dead time on the board. I think we are mostly done with that subject, I would just make a new post for organizational reasons of the forum if the subject is changed but all good to me.

Moved to new thread by popular demand :smiley:

Thanks @runger, and sorry for creating that mess.

Here is another illustration of the problem with the deadtime.
This is the pwm waveform when running in openloop. The vertical lines are when the hall sensors change state, it should happen at the pwm waveform zero crossing (red arrows), with possibly a slight shift if the hall sensors are missaligned. But here itā€™s completely off, it means the magnetic angle generated by the windings is shifted.

Now this is with deadtime compensation. Itā€™s much cleaner and the hall sensor signal can be used to identify the start and end electrical angle of each sector(autodetect)

That is an impressive difference, Iā€™m really surprised!

is this with SimpleFOC code? Are the settings otherwise the same except for the deadtime compensation?

What do you mean by PWM waveform? The phase to GND voltage? Or the phase current?

Yes this is simplefoc with the changes mentioned here, I am just making the compensation 0(OFF) or 0.7V.
By PWM waveform, I mean the output duty cycles of the SVPWM sorry. I assume itā€™s in sync with the BEMF with low speed and load.

Now I tried something else, I halved the timers deadtime (60 to 30 cycles, it was too high anyway), and I still had to compensate by 0.5V instead of 0.7V to have a nice sinusoidal phase current waveform.
So that means I am not only compensating for the deadtime but probably also the stiction, otherwise I would have to halve the compensation as well.
If I still remember my middle school math, the deadtime compensation is 0.40V and stiction compensation is 0.30V. And by halving the deadtime, I get 0.20V deadtime compensation and still 0.30V stiction or black energy compensation.

This makes senseā€¦

Ah, so weā€™re looking at the computed value for the PWM duty cycle, rather than the PWM itself or a measured voltage/current. This also makes more sense to me now.

The position of the HallSensor interrupts is an indirect feedback confirming it is probably working as intended? But to really see the effect weā€™d have to look at a phase current measurement?

Yes it is visible here, the phase current waveform improves as I increase the compensation.

So nice, the improvement is very visible!

Congratulations, I must say this is a very nice result. I think we should add it to SimpleFOC for the next release. I love the fact that it is implemented in a completely hardware-independent way.

We can introduce a motor.dtcomp and default it to 0 for the next release. That way existing code would not be immediately impacted, but the feature would be available to those who want to test itā€¦

What do you think? Would you like to contribute it?

Remember I cheated by taking the easiest example (velocity openloop with slow speed and low load).
It should help get feedback from others if it works well on different controllers and motors, and with what compensation value.

Eventually I should be using the sign of the current to add or substract the compensation, but when the phase current jumps below and above zero because of noise, itā€™s not working well. So I need to still work on this.

Are you using a LPF on the measured current? The zero crossings would occur far less frequently than the measurements, so a good deal of filtering should be possible?

I think your solution is appropriate to the open-loop, but also the closed loop modes that donā€™t use current sensing. I wonder if the BEMF estimation and lag compensation we already have (when you enter the motor resistance, KV and inductance) are sufficient to also make it work at higher speeds and currents? Of course it would be subject to the same limitations as everything else when you donā€™t have the real current sensing, but the voltage control or estimated current control does pretty well on a wide class of motors and applications, I would say.

I think it would be cool if people could test it out if they are interested (certainly I want to try it :slight_smile: ) but I donā€™t have any kind of feeling yet for how hard it will be to pick good values, whether they vary a lot by setup (presumably yes because it will depend on the FETs and voltages being used) and how to give people guidelines for using it with their setupā€¦

But looking at where it goes in the code it isnā€™t something we can easily add on with a new class in the drivers repositoryā€¦ so perhaps putting it in the code but deactivated by default for now is the way to goā€¦

But if you think its better to wait a bit more, then thatā€™s fine too!

I havenā€™t tried the LPF on the phase current sensing yet. So far my gd32 current sensing is not using any interrupt at all. But I will try it to see if itā€™s useful.

So far my only way to pick the right compensation value is to look at the phase current waveform, so current sensing will be needed for sure.
If I wanted to automate this by measuring the deadtime, I would increase the duty cycle until the phase current is visible, but that means we still need current sensing.
Maybe one idea would be to move to a specific position, and increase the duty cycle until the position changes. This could measure the deadtime + stiction without current sensing. But this is then getting closer to the anticogging map.

I would be happy to get feedback, I want to make sure itā€™s not only helping on a few setups, otherwise itā€™s not worth spending too much time.

We could add a freewheeling parameter, which tells the FOC loop what the minimum PWM should be. It would be the sum of deadtime_shift + stiction_PWM
The stiction_PWM could be measured during the init process I guess?

I have to think about this. ā€œFreewheelingā€ is usually associated with the idea of switching all the FETs off (Hi-Z mode, also called ā€œslow decayā€).
What youā€™re suggesting is I think already possible with current control - by setting a 0 current target?

The stiction part I donā€™t fully understand yet. The dead time compensation is somewhat clear, this is a fix at the electrical level for asymmetry caused by the FET switching times and dead-time.

But the stiction seems to me to have little to do with the PWM and FET switching, but rather this is a function of the motorā€™s physical properties and bearing etc, as well as of course the load in a loaded situation? One would also expect the stiction to be independent of the PWM cycle/frequency?
How is it tied back to the PWM timings fix?

ā†’ After reading through the paper you linked quickly, I think I get it. I have to read it properly this evening.