Motor looses phases/location if pushed against movement

Dear Colleagues,

I have this library working with a WROOM ESP32 beautifully. Unfortunately I run into a snag which can result in motor runaway.

If I stall the motor and push it against the movement direction far enough in voltage control mode with target > 50% of supply voltage - it jumps over the phase and looses positioning. When this happens shaft_angle stops updating as well.

Wondering what’s the best way to recover from this error to start motor calibration again?

Thank you for any leads,

Hey @rz2za

Interesting issue.
It seems to me like sensing problem, what is the sensor you are using?

If it is an I2C sensor, that might be the EM filed that kills the communication.
If it would have been Encoder, your shaft_angle would not stop updating even after misalignment (if these isn’t some bigger problem :slight_smile: ) .

Regarding the re-calibration, you would need to start from the sensor.
If you are using the spi sensor you could do:

sensor.close(); // closing spi communication
sensor.init(); // start SPI

// and then maybe align  motor if necessary (should not be necessary)
motor.initFOC();

In my experience so far, SPI communication is very robust and usually EM field issues are not too common.

For encoders, I did not really make a detach interrupt code, so that would mean there is no real close() function. So you can do it by hand:

detachInterrupt(digitalPinToInterrupt(sensor.pinA)); // disable interrupts
detachInterrupt(digitalPinToInterrupt(sensor.pinB)); 

sensor.enableInterrupts(doA,doB); // reinitialize the encoder (no need for sensor.init());

motor.initFOC();  // this time it is necessary to calibarte FOC

If it is an encoder issue, I would suggest you to use the index channel. This channel will give you once per rotation calibration signal.

At the end, for the I2C sensors, it is not as easy. I did not implement the close() function as well. Because it is a bit more complicated to restart the I2C communication from failed state.
What I can suggest you to do is add the 4.7Kohm pull-ups. This might help a bit.

Thank you - this pointed me to a right direction.

I am using an SPI AS5048 sensor. Seems some code is excessive for ESP32 - here is what fixed the problem - for the record:

[1] in read() in magneticSensorSPI.cpp comment out double pulldowns/pullups, so only single one stays:

digitalWrite(chip_select_pin, LOW);

digitalWrite(chip_select_pin,HIGH);

set delayMicroseconds to 50 instead of 10 in between the write and read:

delayMicroseconds(50);

and [2] commending out this bit in the init():

SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
SPI.setDataMode(SPI_MODE1);
SPI.setClockDivider(SPI_CLOCK_DIV8);

Appreciate your help!

Thanks a lot for the feedback @rz2za!

I’ll look into it a bit more and I’ll include it to the library code.

Hi Guys, I seem to be having a similar issue.

As @rz2za, when I apply a small amount of force to the motor, it seems to loose encoder positioning. As I check the serial monitor, it gains or loses 50-1000 radians randomly, and then resumes rotation from the new position. This seems to only happen when I set the current limit above 1 amp. Is anybody familiar with such an issue or have seen this before? Below are some reasons that could be possible that I came up with, but perhaps someone with more experience has a better understanding of what is happening:

  • increasing amperage → increase magnetic field interference to AS5047p sensor
  • increasing amperage → increase magnetic field interference to SPI interface

Please see video demo below:

Current limit at 1 amp (no issue):

Current limit at 2 amps:

Thanks in advance!
Amit