The B-G431B-ESC1 with the AS5048A encoder does not work in MotionControlType::angle mode

Hello everyone,

I’ve been trying for weeks to get SimpleFOC working in MotionControlType::angle mode, but I’m not getting the correct motor behavior and have already tried all the solutions I found on this forum.
I’m really asking for help to figure out what the issue is.

I have:

  • B-G431B-ESC1
  • A lab power supply set to output 12V and 0.7A
  • A 2807 1300KV BLDC motor with 7 pole pairs
  • An AS5048A encoder connected in PWM mode
  • Arduino IDE 2.0, where the STM32 Discovery board with part number B-G431B-ESC1 is available on COM4
  • Simple FOC library version 2.3.4

In the sketch provided below, the mode is set to MotionControlType::angle, and the motor should rotate to 90 degrees and return to 0 degrees every 2 seconds.

However, depending on the motor’s initial position, it either moves to an incorrect angle, doesn’t move at all, or exhibits unstable jittering.

Interestingly, the motor holds its position relative to some angle, but switching angles doesn’t happen.
Somehow, the algorithm does not move the motor to the specified Target angle, even though both the Angle encoder and Angle shaft differ from the set value.

Here’s a video of the incorrect behavior MotionControlType::angle https://youtu.be/5b5FqBA_Vbc

Here’s a photo of the wiring:



I checked and separately output the encoder readings to the serial port, and if I’m not mistaken, the direction and angle are correct. When I rotate it by hand, the value changes within 3.14 radians per rotation.

In motor.controller = MotionControlType::velocity mode, the behavior is also incorrect: the motor holds its position but doesn’t rotate or doesn’t resist at all.
In motor.controller = MotionControlType::velocity_openloop mode, everything works successfully, and despite the rapid temperature rise of the MOSFETs, the rotation is stable and consistent.

Here’s a video of the correct behavior MotionControlType::velocity_openloop https://youtu.be/IIp-zh_hLyQ

All parameters are always the same; I only change motor.controller.

Here’s the sketch and Serial monitor data:


#include <SimpleFOC.h>

float targetAngle = 0; // start angle (0 rad)
bool moveTo90 = true;  // Flag for switching between 0 and 90 degrees
unsigned long lastSwitchTime = 0;

double temp = 0;
unsigned long time_stamp = 0;

BLDCMotor motor = BLDCMotor(7, 0.35, 1300);  // 2807 : 7 poles pairs, 0.35 16 , 1300 KV
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
MagneticSensorPWM sensor = MagneticSensorPWM(A_HALL1, 1, 1024);  // PWM mode , encoder on A_HALL1

void doPWM() { sensor.handlePWM(); }

void setup() {
  Serial.begin(115200);
  pinMode(A_TEMPERATURE, INPUT);

  // init sensor
  sensor.init();
  sensor.enableInterrupt(doPWM);
  motor.linkSensor(&sensor);

  // init driver
  driver.voltage_power_supply = 12; 
  driver.voltage_limit  = 12; 
  driver.pwm_frequency = 30000; 
  driver.init();
  motor.linkDriver(&driver);


  // 🔧 velocity settings PID 
  motor.PID_velocity.P = 0.1;            // Increase if the motor is sluggish.
  motor.PID_velocity.I = 0;              // Eliminates speed error
  // motor.PID_velocity.D = 0.0001;      // Smooths out oscillations
  motor.PID_velocity.output_ramp = 300;  // Smooth acceleration

  // Speed filter (reduces noise)
  motor.LPF_velocity.Tf = 0.01;

  // ⚠️ Limits  
  motor.velocity_limit = 300;    // Max. speed (rad/s)
  motor.voltage_limit = 6;       // Voltage 
  motor.current_limit = 2.0;     // Max. current (A)


  motor.controller = MotionControlType::angle;
  // motor.controller = MotionControlType::angle;
  // motor.controller = MotionControlType::velocity_openloop;


  motor.foc_modulation = FOCModulationType::SinePWM; 

  motor.sensor_direction = Direction::CW;

  // Monitoring in Serial
  motor.useMonitoring(Serial);

  // init FOC
  motor.init();

  if (motor.initFOC()) {
    Serial.println("FOC OK! The motor is ready.");
    Serial.print("Zero Electric Angle: ");   Serial.println(motor.zero_electric_angle);
    Serial.print("Direction: ");             Serial.println(motor.sensor_direction == Direction::CW ? "CW" : "CCW");
  } else {
    Serial.println("FOC Error!");
    while (1);
  }
}

void loop() {

      motor.loopFOC();

      // Automatic angle switching every 2 seconds (2000 ms)
      if (millis() - lastSwitchTime > 2000) {
        lastSwitchTime = millis();
        
        if (moveTo90) {
          targetAngle = 1.57; //  90 degrees (π/2 radians)
          Serial.println("Moving to 90 degrees...");
        } else {
          targetAngle = 0.0; // Return to 0 degrees
          Serial.println("Moving back to 0 degrees...");
        }
        
        moveTo90 = !moveTo90; // invert Flag
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // BLinking LED
      }


      // Motor control
      motor.move(targetAngle);

      // Data print every 1 second (1000 ms)
      if(millis()-time_stamp > 1000) {

          temp = map(analogRead(A_TEMPERATURE),0,1024,-49,125);
          Serial.print("Temperature: "); Serial.print(temp); Serial.print(" degrees ");
        
          Serial.print(" | Angle move: ");     Serial.print(targetAngle);
          Serial.print(" | Angle encoder: ");  Serial.print(sensor.getAngle());
          Serial.print(" | Angle shaft: ");    Serial.print(motor.shaftAngle());
          Serial.print(" | Velocity: ");       Serial.print(motor.shaftVelocity());
          Serial.print(" | Voltage q: ");      Serial.println(motor.voltage.q);

          time_stamp = millis();
      }
}

Serial Monitor

15:16:28.653 → Temperature:MOT: Monitor enabled!
15:16:29.579 → MOT: Init
15:16:30.090 → MOT: Enable driver.
15:16:30.585 → MOT: Align sensor.
15:16:30.585 → MOT: Skip dir calib.
15:16:31.276 → MOT: Zero elec. angle: 1.93
15:16:31.482 → MOT: No current sense.
15:16:31.482 → MOT: Ready.
15:16:31.482 → FOC OK! The motor is ready.
15:16:31.482 → Zero Electric Angle: 1.93
15:16:31.526 → Direction: CW
15:16:31.526 → Temperature: 19.00 degrees | Angle move: 0.00 | Angle encoder: 3.87 | Angle shaft: 3.87 | Velocity: -0.07 | Voltage q: -0.11
15:16:31.572 → Moving to 90 degrees…
15:16:32.491 → Temperature: 20.00 degrees | Angle move: 1.57 | Angle encoder: 3.97 | Angle shaft: 3.97 | Velocity: -2.58 | Voltage q: -0.70
15:16:33.522 → Temperature: 21.00 degrees | Angle move: 1.57 | Angle encoder: 3.98 | Angle shaft: 3.98 | Velocity: 2.95 | Voltage q: -0.70
15:16:33.569 → Moving back to 0 degrees…
15:16:34.543 → Temperature: 21.00 degrees | Angle move: 0.00 | Angle encoder: 3.98 | Angle shaft: 3.98 | Velocity: 0.25 | Voltage q: -0.70
15:16:35.542 → Temperature: 22.00 degrees | Angle move: 0.00 | Angle encoder: 3.97 | Angle shaft: 3.97 | Velocity: -0.16 | Voltage q: -0.70
15:16:35.589 → Moving to 90 degrees…
15:16:36.510 → Temperature: 23.00 degrees | Angle move: 1.57 | Angle encoder: 3.97 | Angle shaft: 3.97 | Velocity: -0.10 | Voltage q: -0.70
15:16:37.515 → Temperature: 24.00 degrees | Angle move: 1.57 | Angle encoder: 3.96 | Angle shaft: 3.96 | Velocity: -0.45 | Voltage q: -0.70
15:16:37.548 → Moving back to 0 degrees…
15:16:38.565 → Temperature: 24.00 degrees | Angle move: 0.00 | Angle encoder: 3.98 | Angle shaft: 3.98 | Velocity: 0.33 | Voltage q: -0.70
15:16:39.525 → Temperature: 25.00 degrees | Angle move: 0.00 | Angle encoder: 3.98 | Angle shaft: 3.98 | Velocity: 4.02 | Voltage q: -0.70
15:16:39.567 → Moving to 90 degrees…
15:16:40.530 → Temperature: 25.00 degrees | Angle move: 1.57 | Angle encoder: 3.97 | Angle shaft: 3.97 | Velocity: -0.07 | Voltage q: -0.70
15:16:41.535 → Temperature: 26.00 degrees | Angle move: 1.57 | Angle encoder: 3.97 | Angle shaft: 3.97 | Velocity: 5.00 | Voltage q: -0.70