Motor rotating at opposite direction, giving negative velocity and breaking velocity control

I run the calibration code find_pole_pairs_number.ino, and it gives me the following output:

MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Skip dir calib.
MOT: Align current sense.
MOT: Success: 1
MOT: Ready.
MOT: Init
MOT: Enable driver.
Pole pairs (PP) estimator
-

Estimated PP : 7
PP = Electrical angle / Encoder angle 
1080.00/154.58 = 6.99

If PP is estimated well your motor should turn now!
 - If it is not moving try to relaunch the program!
 - You can also try to adjust the target voltage using serial terminal!
MOT: Align sensor.
MOT: sensor_direction==CW
MOT: PP check: OK!
MOT: Align current sense.
MOT: Success: 1
MOT: Ready.

The pole pairs result is correct and the motor does rotate smoothly clockwise.

However when I manually apply motor.sensor_direction = CW in my application, the motor is actually rotating anti-clockwise and the velocity reported by motor.monitor() is negative.

# setup()
...
motor.sensor_direction = CW;
motor.torque_controller = TorqueControlType::voltage;
motor.controller = MotionControlType::torque;
motor.linkSensor(&encoder);
motor.linkCurrentSense(&sense);
motor.linkDriver(&driver);
motor.init();
motor.initFOC();
...

# loop()
...
const auto now_us = micros();
static unsigned long foc_last = 0;
if (now_us - foc_last > 500) {
  foc_last = now_us;
  motors[idx].move(1);
  motors[idx].loopFOC();
  motors[idx].monitor();
  cmder.run();
}
...

This has completely broken the velocity control. I’ve tried switching motor phases and changing sensor_direction to CCW, and the motor then rotated clockwise, and the reported velocity is still negative. How is this even possible?

Hi @XCYRKDSDA , welcome to SimpleFOC!

The sensor_direction parameter can be set in open loop mode, and it will change the direction the motor turns when you apply a “positive voltage” (meaning a positive Q-axis voltage).

In closed loop FOC mode, the parameter cannot be chosen by the user. Is is calibrated by the system to ensure that positive voltage corresponds to positive angle. This is what we call “CW” direction.
If the natural direction of the sensor compared to the motor is such that positive voltage corresponds to negative sensor angle, then we set the motor_direction to “CCW” to correct this problem and keep the positive correspondence in the motor algorithm even though the sensor class is the opposite.

So you can’t change the parameter in closed loop mode, you have to set the correct value.

If you want to change the direction that the motor turns you can swap two of the phase wires. This should result in the opposite setting for motor_direction during the calibration.

Of course, for a given mounting orientation of the sensor within some setup, the physical “clockwise” direction is always the same. The sensor_direction parameter relates only to the relationship of the electrical commutation to the sensor. If you want to change the direction of the motor you would just use negative target values.

Thanks for your help. I’ve figured out what went wrong. It’s kind of silly and has almost nothing to do with the code. I have multiple AS5047P connected to the same SPI bus, but I didn’t pull down their CS pins in the circuit. This caused the other CS pins to remain floating when I initialized only some of the sensors. This messed up the communication. The sensors returned no data, and the zero electric angle was incorrectly calibrated to 6.28, which is almost 180° away from the correct value of 3.97. I changed the order of initialization. I initialized all the sensors first before initializing the motors, and then everything worked fine.