Problems starting a BLDC motor with a homemade driver

Hello everyone, I’ll just say that I’m using Google Translate to write this text. I apologize in advance for any distorted words.

I’m trying to run a MT5208 340kV BLDC motor on an Arduino NANO microcontroller using a homemade IR2401S driver (The driver is powered separately from the motor). I assembled it according to the schematic below:

I’m using the code from the Simple FOC example to move the motor between 1 radian and -1 radian every second. If I specify open-loop control in the code, i.e., “motor.controller = MotionControlType::angle_openloop,” the motor does indeed rotate at the specified angles every second, but some vibration is felt (the motor is fully functional and operates via an ESC controller). Here’s code:

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);


void setup() {

  driver.init();
  motor.linkDriver(&driver);
  motor.controller = MotionControlType::angle_openloop;
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0.001;
  motor.PID_velocity.output_ramp = 1000;
  motor.LPF_velocity.Tf = 0.01;
  motor.P_angle.P = 20;
  motor.velocity_limit = 4;
  motor.voltage_limit = 10;
  Serial.begin(115200);
  motor.useMonitoring(Serial);
  motor.init();
  Serial.println("Motor ready.");
  _delay(1000);
}

float target_angle = 1;
long timestamp_us = _micros();

void loop() {

  if(_micros() - timestamp_us > 1e6) {
      timestamp_us = _micros();
      target_angle = -target_angle;   
  }

  motor.loopFOC();
  motor.move(target_angle);
}

But if I simply specify “motor.controller = MotionControlType::angle” and connect the as5600 magnetic encoder, the motor starts to jerk violently, but still turns at the specified angles. (The encoder is also working; for one motor rotation, the encoder shows 6.28 radians.) Here’s the code with the encoder connected:

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);
MagneticSensorI2C encoder = MagneticSensorI2C(AS5600_I2C);

void setup() {
  encoder.init();
  motor.linkSensor(&encoder);
  driver.init();
  motor.linkDriver(&driver);
  motor.controller = MotionControlType::angle;
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0.001;
  motor.PID_velocity.output_ramp = 1000;
  motor.LPF_velocity.Tf = 0.01;
  motor.P_angle.P = 20;
  motor.velocity_limit = 4;
  motor.voltage_limit = 10;
  Serial.begin(115200);
  motor.useMonitoring(Serial);
  motor.init();
  motor.initFOC();
  Serial.println("Motor ready.");
  _delay(1000);
}

float target_angle = 1;
long timestamp_us = _micros();

void loop() {

  if (_micros() - timestamp_us > 1e6) {
    timestamp_us = _micros();
    target_angle = -target_angle;
  }

  motor.loopFOC();
  motor.move(target_angle);
}

Unfortunately, I can’t provide the driver output data via an oscilloscope, as I don’t have one. Please help me figure out what I’m doing wrong.

Try motor.voltage_limit = 1.0; or less. That motor only has 83 milliohms resistance, so with 10V you may be getting over 100 amps. I’m surprised nothing exploded.

Hi @Vortex , welcome to SimpleFOC!

please don’t go directly from open loop to angle mode…

First, please try the closed loop torque voltage mode. This needs only your sensor to work, and does not use any PIDs.

Once torque-voltage mode is working, please try velocity mode next. For this you will need to tune the PID for velocity.

Once velocity mode is working well, angle mode is next. That should not be hard after the lower level modes are working well.