AS5600 MOT: init FOC Failed

Hi guys, I’m now trying to run a gimbal motor with as5600 and mega2560 for my project. My problem now is that the motor is spinning during the init process but the serial shows that this process failed because no movement was detected from the sensor. I’ve also checked the sensor with the magnet sensor iic test example in the utils and it works fine.

These are the messages I got from the serial:

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.

and here is my program:

#include <SimpleFOC.h>
// magnetic sensor instance - analog output
MagneticSensorAnalog sensor1 = MagneticSensorAnalog(A1, 0, 1023);
// BLDC motor & driver instance
BLDCMotor motor1 = BLDCMotor(7);
BLDCDriver3PWM driver1 = BLDCDriver3PWM(11, 10, 9, 8);
float target_angle = 4;
// commander interface
Commander command = Commander(Serial);
void doTarget(char* cmd) {
command.scalar(&target_angle, cmd);
}

void setup()
{
// initialise magnetic sensor hardware
sensor1.init();
// link the motor to the sensor
motor1.linkSensor(&sensor1);
// driver config
// power supply voltage [V]
driver1.voltage_power_supply = 24;
driver1.init();
// link driver
motor1.linkDriver(&driver1);

// control loop type and torque mode
motor1.torque_controller = TorqueControlType::voltage;
motor1.controller = MotionControlType::angle;
motor1.motion_downsample = 10.0;

// velocity loop PID
motor1.PID_velocity.P = 0.4;
motor1.PID_velocity.I = 0.0;
motor1.PID_velocity.D = 0.0;
motor1.PID_velocity.output_ramp = 0.0;
motor1.PID_velocity.limit = 12.0;
// Low pass filtering time constant
motor1.LPF_velocity.Tf = 0.01;
// angle loop PID
motor1.P_angle.P = 29.0;
motor1.P_angle.I = 0.2;
motor1.P_angle.D = 0.0;
motor1.P_angle.output_ramp = 0.0;
motor1.P_angle.limit = 100.0;
// Low pass filtering time constant
motor1.LPF_angle.Tf = 0.02;
// Limits
motor1.velocity_limit = 25.0;
motor1.voltage_limit = 20.0;
motor1.current_limit = 5.0;
command.add(‘T’, doTarget, “target angle”);
// use monitoring with serial for motor init
// monitoring port
Serial.begin(115200);
// comment out if not needed
motor1.useMonitoring(Serial);
// initialise motor
motor1.init();
// align encoder and start FOC 1.14, Direction::CCW
motor1.initFOC();
_delay(1000);
}

void loop() {
// iterative setting FOC phase voltage
motor1.loopFOC();
// iterative function setting the outter loop target
// velocity, position or voltage
// if tatget not set in parameter uses motor.target variable
//Serial.println(sensor1.getAngle());
motor1.move(target_angle);
command.run();
}

You’re using MagneticSensorAnalog. Is your AS5600 configured for analog output? If you check the output with a multimeter, do you get an analog signal that changes as you turn the motor?

The error you are seeing means the sensor is not working correctly. This can be a misconfiguration of the sensor, a power problem of the sensor, or a software issue.

Hi runger, thank you for your reply. I’ve tried to replace my own driver board with the official simplefoc shield, and it works without problem this time. I think it could be the problem caused by my own driver, which uses btn7960s to control the BLDC.

Hey, I’m glad to hear you got it working!

Hi Runger, thanks for helping me with this problem. Recently I’m working with DualFOC board from Makerbase with esp32 as microcontroller and now I’m facing the same problem again as before. All hardware connections are correct and the magnet sensor is working as well, but during the MOT init process it again doesn’t recongize the movement of the motor. This time the code looks like this:

#include <Arduino.h>

#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(26,27,14,12);

// encoder instance
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);


// inline current sensor instance
// check if your board has R010 (0.01 ohm resistor) or R006 (0.006 mOhm resistor)
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50.0, 39, 36, _NC);

// commander communication instance
Commander command = Commander(Serial);
void doMotor(char* cmd){ command.motor(&motor, cmd); }

void setup() {

  I2Cone.begin(23, 5 , 400000UL);
  sensor.init(&I2Cone);
  motor.linkSensor(&sensor);
  driver.voltage_power_supply = 12;
  driver.init();
  // link driver
  motor.linkDriver(&driver);

  // TorqueControlType::foc_current
  // TorqueControlType::voltage TorqueControlType::dc_current 
  motor.torque_controller = TorqueControlType::foc_current; 
  // set control loop type to be used
  motor.controller = MotionControlType::angle;

  // contoller configuration based on the controll type 
  motor.PID_velocity.P = 0;
  motor.PID_velocity.I = 0;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 5;
  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;
  motor.voltage_sensor_align= 12;
  // angle loop controller
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 1;

  // use monitoring with serial for motor init
  // monitoring port
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 0; // disable intially
  
  // current sense init and linking
  current_sense.init();
  current_sense.gain_b *= -1;
  motor.linkCurrentSense(&current_sense);

  // initialise motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC(); 

  // set the inital target value
  motor.target = 2;

  // subscribe motor to the commander
  command.add('M', doMotor, "motor");
  
  delay(1000);
}


void loop() {
  // iterative setting FOC phase voltage
  motor.loopFOC();

  // iterative function setting the outter loop target
  motor.move();
  // motor monitoring
  motor.monitor();
  Serial.println(sensor.getAngle());
  // user communication
  command.run();
}

and this is what I got from output with the “Serial.println(sensor.getAngle());” function when I manually turn the motor:

but for the MOT init the result is always like this :

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: fail - estimated pp: 13.70
MOT: Zero elec. angle: 5.47
MOT: Align current sense.
CUR: No driver linked!
MOT: Align error!
MOT: Init FOC failed.

or this:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.

This problem is really confusing me now and I really don’t know how to solve this.

If you manually turn motor 360, does sensor angle change 6.28 radians? (it should)

If it does return 6.28, then simplest explanation to what you are seeing is that you are using a 14pp motor.

During the alignSensor method the motor is requested to move 1 electrical revolution in one direction and then 1 electrical revolution in the other direction. It measures what the sensor thinks it has moved and shows a message like you see:

MOT: PP check: fail - estimated pp: 13.70

if it doesn’t move the amount expected.
If the motor is 7pp then you should see it moving a 7th of a full rotation in one direction followed by a 7th in the other direction during the align process. This is because there will be 7 electrical rotations for each physical rotation in a 7pp motor.

Hi Owen, thank you for the reply, I’ll check it out later. :slight_smile: