Closed runger1101001 closed 2 years ago
Could this be realted to this issue #177 ?
Doesn't seem so - it's STM32 rather than ESP32, and Adharsh doesn't have the phase resistance set. An interesting difference in his setup is that he has pre-aligned the sensor to the motor, and so he initialises initFOC() with a value of 0.0f - that's probably a fairly unique feature of his setup. But otherwise he's just doing velocity control, no current limiting.
I did some debugging, and void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el)
is being fed NaN for Uq, which seems to be coming from the PID of loopFoc.
Normalized angle was reading correct values, even when the motor was stalled.
Yes @markovica, the value Uq is being fed NaN, I did some testing and my findings are updated in the forum thread. https://community.simplefoc.com/t/inrush-current-problem-with-our-bldc-driver-board/2052/38?u=adharsh_k
The problem is coming from Sensor::getVelocity()
returning INF
one time while running and this screws up all other functions which rely on this value. And in the end the Uq is fed NaN and the motor stops.
The function getVelocity()
continues to work.
sens_vel: -3.26 lpf_velo: -3.26 retVal: -3.15 sens_vel: -3.26 lpf_velo: -3.26 retVal: -3.19 sens_vel: 0.00 lpf_velo: 0.00 retVal: -2.00 sens_vel: -3.09 lpf_velo: -3.09 retVal: -2.40 sens_vel: inf lpf_velo: inf retVal: inf <- This is where the problem happens ie: Sensor::getVelocity() returning INF sens_vel: 0.00 lpf_velo: nan retVal: inf sens_vel: 0.00 lpf_velo: nan retVal: inf sens_vel: 0.00 lpf_velo: nan retVal: inf sens_vel: 0.00 lpf_velo: nan retVal: inf
where sens_vel
is the value returned by Sensor::getVelocity()
lpf_velo
is the value after low pass filter,
retVal
is the value returned by the function FOCMotor::shaftVelocity()
For a quick fix you can modify the function FOCMotor::shaftVelocity()
like this:
float FOCMotor::shaftVelocity() {
// if no sensor linked return previous value ( for open loop )
if(!sensor) return shaft_velocity;
float vel = sensor->getVelocity();
if(vel < -1000 || vel > 1000) vel = 0; //if velocity is out of range then make it zero
return sensor_direction*LPF_velocity(vel);
}
Thank you @kadharsh
I moved your fix to HallSensor::getVelocity() as it makes more sense to me since this seems to be a hall sensor issue and it seems it's working perfectly.
float HallSensor::getVelocity(){
if (pulse_diff == 0 || ((long)(_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old
return 0;
} else {
// quick fix https://github.com/simplefoc/Arduino-FOC/issues/192
float vel = direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f);
if(vel < -1000 || vel > 1000) vel = 0; //if velocity is out of range then make it zero
//return direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f);
return vel;
}
as it makes more sense to me since this seems to be a hall sensor issue and it seems it's working perfectly.
Yes, you are right, I just put it there just in case.
That's nice work and you guys are able to solve the issue, but I was looking at the source code, and over there vel is not declared. Kindly you can highlight where you declared the vel value. Thanks
That's nice work and you guys are able to solve the issue, but I was looking at the source code, and over there vel is not declared. Kindly you can highlight where you declared the vel value. Thanks The actual
HallSensor::getVelocity()
code in src/sensors/HallSensor.cpp isfloat HallSensor::getVelocity(){ if (pulse_diff == 0 || ((long)(_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old return 0; } else { return direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f); }
}
just replace it with this:
> Thank you @kadharsh
>
> I moved your fix to HallSensor::getVelocity() as it makes more sense to me since this seems to be a hall sensor issue and it seems it's working perfectly.
>
> ```
> float HallSensor::getVelocity(){
> if (pulse_diff == 0 || ((long)(_micros() - pulse_timestamp) > pulse_diff) ) { // last velocity isn't accurate if too old
> return 0;
> } else {
> // quick fix https://github.com/simplefoc/Arduino-FOC/issues/192
> float vel = direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f);
> if(vel < -1000 || vel > 1000) vel = 0; //if velocity is out of range then make it zero
> //return direction * (_2PI / (float)cpr) / (pulse_diff / 1000000.0f);
> return vel;
> }
> ```
And it should work!
Happy hacking : )
This is a simplified template, feel free to change it if it does not fit your case.
Describe the bug The motor stops sometimes when it changes direction. The calculated voltages are NaN - causing this behaviour. See: https://community.simplefoc.com/t/inrush-current-problem-with-our-bldc-driver-board/2052/25
Describe the hardware setup For us it is very important to know what is the hardware setup you're using in order to be able to help more directly
IDE you are using
Tried the Getting started guide? - if applicable See forum post - we've been trying to get the motor driver running, and have run into this problem.