Current consumption

Hello. By trial, I found out that at an electric angle of 0.63, the motor consumes a minimum amount of current and at the same time rotates very gently clockwise. But for such parameters, when rotating counterclockwise, I need to set an electric angle of 1.82. Since I want to use the motor function in both directions, I would like to know where I can specify in the firmware code both values of the electric angle depending on the direction of rotation?
motor.initFOC(1.82, Direction::CCW);- counterclockwise 0,1amp
motor.initFOC(0.63, Direction::CCW);- clockwise 0.1amp
motor.initFOC(1.22, Direction::CCW); -both directions 1.8amp
In addition, if you specify the electric angle, then when the controller is turned on, it stops looking for the encoder index. This is really bad

Hey @nikolaewich1988!
So many interesting issues, I love it.

You are using the encoder right?
What is the velocity you are trying to run your motor on?

Electric angle of the motor should not change, at all. Especially not 0.6 rad (35 degrees). This is not possible. So SimpleFOC does not support adding two different electric zero offsets simply because there is only one. :smiley:

However, if you are trying to spin your motor at very high velocities, you will definitely see some strange behaviors. For example if the electric angle is wrong by a small postive number, your motor will spin faster in the posititve side and if the electrical angle is wrong by a small negative number your motor will spin faster in the negative side.
If you are using the closed loop control for relatively normal range of velocities there will be no differences.

If you are going to the velocities of >200 rad/s then you will start seeing the issues. There are multiple facters that come to play and electrical angle is only one of them:

  1. loop time is becoming comparable to the motor electrical rotation period and that means that your the microcontroller is not able to set the phase voltages fast enough. Your rotor will no longer be exactly at 90 degrees from the vector of the magnetic filed because the mcu takes too much time to calculate and set the appropriate phase voltages.
  2. Not measuring the phase current. If you’re not measuring the phase current, you assume that the phase current is proportional to the phase voltage I=U/R which is only true for low velocitites. The higher the velocity the less this relationship is true, and the higher the misalignment.
  3. Finally having evena small error in the electric angle offset estimation will lead to the issues on very high velocities. The maximal velocity on one side will be slower than on the other and the motor can even become unstable.

In most cases, we have to deal with a combination of all of these issues at once.

Fortunately there is a simple fix to help avoid issues 1 and 2 using the zero electric angle 3.
It is called field weakening and the simplest way to implement is to change the electric zero angle depending on the velocity direction you are spinning your motor with.

In you Arduino program you can add a new variable zero_angle_toremember to remember the zero angle found by the library. Then in the loop function you can change the zero_electric_angle proportional to the velocity.


float zero_angle_toremember;
void setup(){

....
motor.initFOC();
...
zero_angle_toremember= motor.zero_electric_angle; // remember the zero angle

}

float gain= 0.001; // a gain factor - to try out
float delta_angle_max = 0.3; // something to try, but I would not go much higher than 0.3-0.4
void loop(){

// calculate the field weakening delta angle
float delta_el_angle = _constrain(motor.shaft_velocity*gain, -delta_angle_max ,delta_angle_max );
// set the new angle
motor.zero_electric_angle = zero_angle_toremember+ delta_el_angle ;

...
motor.loopFOC();
motor.move();
}

Thanks for your help, but I’m getting a compilation error.

Replace

motor.zero_electric_angle = zero_angle_toremember+ motor.shaft_velocity*gain;

by

motor.zero_electric_angle = zero_angle_toremember+ delta_el_angle;

Unfortunately, it didn’t help. The angle is automatically determined by 1.06. At this angle, the counterclockwise rotation is very slow, noisy and a large current is consumed. Clockwise is better, but also not good. In my case, as I wrote above, the ideal angles are 0.63 for clockwise rotation and 1.82 for counterclockwise rotation. The middle is 1.22, at this angle, the speed and current consumption are equal when rotating in both directions, but worse.
Безымянный

I could send you a video of the work, but I don’t know how to do it

What is the voltage_sensor_align value you are using?

Have you tried to change it?

motor.voltage_sensor_align = 1; // Volts

Put this before motor.init();

Video would help, yes!

tried from 1 to 5
in any case, I found the angle at which the engine rotates equally in both directions 1.22.
But this angle is also not correct, because I also found angles for the direction of rotation at which maximum energy efficiency is achieved. There must be a way to specify them, right?

There is only one electrical angle. You cannot have more of them. Simplefoc does not allow to set them that way.
You’re using Arduino nano?

50 rad/s should be close to the limits of its capacity with 600 ppm encoder.
50/rads = 8 turns per second making for 46008 = 19200 interrupts per second. In my experience everything above 20000 interrupts per second is too much for atmga328.
This basically means that you’re probably asking too much from your mcu and that you’re hitting the limits of your hardware.

If you really think that in your case there is absolutely no other way but to force these two angles.
I would advise you to augment the gain value in the code that I’ve sent you. gain=0.1 for example

Otherwise you can do this:


float almost_zero_velocity = 1; // rad/s
void loop(){

if(motor.shaft_velocity > almost_zero_velocity){
    motor.zero_electric_angle = 1.82;
}else if(motor.shaft_velocity < -almost_zero_velocity){
    motor.zero_electric_angle = 0.63;
}else{
    motor.zero_electric_angle = 1.22;
}
....

motor.loopFOC();
motor.move();
}
1 Like

Thanks for your help, but I’m getting a compilation error

put this before the loop fuinciton.

float almost_zero_velocity = 1; // rad/s

try different values to see which one works the best for you.

1 Like

I sent you a video, did you watch it?

now it works great in both directions. Hooray, I’ve been struggling with this problem for two weeks. Thank you so much for your help

Hi,
Can you share, how you were able to solve this?

Thanls

I am having a similar kind of problem but in torque mode.

In clockwise rotation the current consumption is high and the motor speed is slow, while in anti-clockwise the motor consumes less current and has a high speed.

Any recommendations on how to solve it.

Thanks

@nikolaewich1988 has been able to solve his issue which in a very dirty way.
It works but not more than that :smiley:
The fix works but is not a general solution and most probably there is some other issue that we are not aware of.
The description of possible issues and one potential solution is here: Current consumption - #2 by Antun_Skuric

@MoidKhan, can you give us insight in your setup first?
Which motor/driver/mcu…
Which torque mode?
Is it always the same direction?
What is the velocity you are spinning you motor with (roughly)?

thanks for your reply.

I am using a 4 pp motor with esp 32 MCU and DRV 8302 board. Currently using voltage torque mode to move my motor at desired torque based on changing the voltage. In my setup, When applying the + voltage the motor consumes a large current ( checking by PSU) and the velocity/speed of the motor is lower compared to when - voltage is given. At - voltage, the motor consumes less current and high speed.

Thanks

What would the effect of a large sensor latency be?
Could this be a possible explanation for needing two values of the electrical angle?
In fact, neither of them is correct, but the difference is accounting for the sensor latency, which would have a opposite effect depending on direction of rotation (i.e. in one case actual position would be lower than received position, and in the other case actual position would be larger than the received position)?