SimpleFOC studio not working

Hi guys,

I’ve been developing a code to control a BLDC motor with SimpleFOC on ESP32.

The problem is i can not get to work properly. If i send target values through serial the motor moves to the position without a problem but when I try to do it slowly it doesn’t go smooth at all. When using velocity open loop there’s no problem with the low speed movement, but in closed loop there is.

I’m using a AS5048_I2C and a Tmotor GB2208.

I’ve read that maybe my problem is the PID values but when I try to use SimpleFOCStudio in order to tune it, it only says “Unknown cmd err” even though I added commander to my standard code. My motor doesn’t move at all in this case.

Is there anybode else experiencing this? Does anyone know what’s going on?

The code:

#include <Arduino.h>
#include <SimpleFOC.h>

#define SDA_PIN 25
#define SCL_PIN 26
#define I2C_FREQ 400000UL

float target_angle = 0;
MagneticSensorI2C sensor = MagneticSensorI2C(AS5048_I2C);
//InlineCurrentSense current_sense  = InlineCurrentSense(250, 34, _NC, 35);

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(19, 18, 5, 4);

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

void serialLoop() {
  static String recieved_chars;
  
  while (Serial.available()) {
    
    char inChar = (char)Serial.read();
    recieved_chars += inChar;

    if (inChar == '\n') {
      target_angle = recieved_chars.toFloat();
      Serial.print("target_angle = ");
      Serial.println(target_angle);
      recieved_chars = "";
    } 
    
  }
}

void setup() {

  Serial.begin(115200);
  delay(1000);

  Wire.begin(SDA_PIN, SCL_PIN);
  Wire.setClock(I2C_FREQ);

  sensor.init();
 // current_sense.init();

  driver.voltage_power_supply = 7;
  driver.voltage_limit = 4;
  driver.init(); 

  motor.linkDriver(&driver);
 // current_sense.linkDriver(&driver);
  
  motor.voltage_limit = 4;
  motor.voltage_sensor_align = 47;

  motor.linkSensor(&sensor);
  //motor.linkCurrentSense(&crrent_sense);


  // velocity PI controller parameters
  motor.PID_velocity.P = 0;
  motor.PID_velocity.I = 0;
  motor.PID_velocity.D = 0;
  // maximal voltage to be set to the motor
  motor.PID_velocity.output_ramp = 50;

  motor.controller = MotionControlType::angle;
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  
  
  //motor.LPF_velocity.Tf = 0.1f;
  motor.P_angle.P = 0;
  motor.P_angle.I = 0;
  motor.P_angle.D = 0;

  motor.velocity_limit = 500;

  motor.useMonitoring(Serial);

  motor.init();
  motor.initFOC();

  command.add('M',doMotor,"motor");
  // tell the motor to use the monitoring
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 0; // disable monitor at first - optional

}

void loop() {
  
  serialLoop();

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

  motor.monitor();

  command.run();
  
}

Problem Analysis and Core Cause

Conflict Point: SimpleFOC Studio sends commands (e.g., M1.5\n or T10\n) through the serial port. It relies on command.run() to read and parse these commands.

Your Code: Your serialLoop() also runs at the beginning of the loop() function. It preemptively reads all incoming data from the serial port, including commands from SimpleFOC Studio.

Result: When command.run() executes, the serial buffer has already been emptied by your serialLoop(), so the Commander receives no commands, resulting in a lack of interactivity.

Solution: Remove Custom Parsing and Use Commander Directly

To solve this problem, we must remove the custom serialLoop() and let SimpleFOC Commander handle the target angle setting directly.

I have modified the code for you, and now you can use the built-in T (Target) command in SimpleFOC Studio to set the target angle.