SPI on B-G431B-ESC1

Hello,

I would like to use a “B-G431B-ESC1” board with an “IFlight iPower Gimbal Motor GM3506/AS5048A”.

The motor has an AS5048A encoder in “SPI/PWM”.

I find 5 pins available on B-G431B-ESC1:

#define PB3                     35  // USART2_TX
#define PB4                     36  // USART2_RX

#define PB6                     38  // HALL1/ENCODER_A
#define PB7                     39  // HALL2/ENCODER_B
#define PB8                     40  // HALL3/ENCODER_Z

Do you think I can use these pins to route SPI communication with SimpleFOC?

Exemple:

#define MOSI ????
#define MISO ???
#define CLK ???
#define CSN ???

MagneticSensorSPI spi_sensor = MagneticSensorSPI(CSN, 14, 0x3FFF);
SPIClass spi_sensor(MOSI, MISO, CLK)

Is it possible?
Sorry, I haven’t mastered all of SimpleFOC’s features yet.

Unfortunately it is very difficult…

Please take a look here: B-G431B-ESC1: Beginner guide + I2C guide - #88 by Magneon

Ok thanks Richard :slight_smile:

Is it possible to use out PWM from the AS5048A
to use the B-G431B-ESC1 board in SimpleFOC’s “TORQUE” mode?

EDIT/
I read the post, sorry my English is very bad…

I have used an as5600 with pwm in torque mode. There is a dead spot at the top dead center which may be smoothed over with the new smoothing angle thing that I think Deku developed. If you put the frequency at 920 hz or whatever it seems like a reasonable proposition for many applications but it is not as good as having a good digital bus.

There were complications that I never solved, the motor stopped increasing in speed at some point inexplicably.

Thanks Anthony :slight_smile:
I’m going to test PWM because for this project I don’t need speed,
I just need to maintain a stable resistance
This is a project for students (I work in a University FabLab)

-First manual test with “find_raw_min_max.ino” return:
22:46:51.269 -> angle:-111.74 , raw:198 , min:3 , max:932

-Second test with “magnetic_sensor_pwm_example.ino” return:
ok :slight_smile:

-Third test in open loop mode
ok :slight_smile:
Code test:

// Open_loop_motor_control_example

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

// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(11);
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);

//target variable
float target_velocity = 0;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) {
  command.scalar(&target_velocity, cmd);
}
void doLimit(char* cmd) {
  command.scalar(&motor.voltage_limit, cmd);
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // limit the maximal dc voltage the driver can set
  // as a protection measure for the low-resistance motors
  // this value is fixed on startup
  driver.voltage_limit = 12;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor movements
  // limit the voltage to be set to the motor
  // start very low for high resistance motors
  // current = voltage / resistance, so try to be well under 1Amp
  motor.voltage_limit = 3;   // [V]

  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // Limits
  motor.current_limit = 0.8f; // 1.0 [Amps]

  // general settings
  // motor phase resistance // I_max = V_dc/R
  motor.phase_resistance = 5,57; // 5,57 [Ohm]
  // motor KV rating [rpm/V]
  motor.KV_rating = 197; // [rpm/volt] - default not set

  // init motor hardware
  motor.init();

  // add target command T
  command.add('T', doTarget, "target velocity");
  command.add('L', doLimit, "voltage limit");

  Serial.println("Motor ready!");
  Serial.println("Set target velocity [rad/s]");
  _delay(1000);
}

void loop() {

  // open loop velocity movement
  // using motor.voltage_limit and motor.velocity_limit
  motor.move(target_velocity);

  // user communication
  command.run();
}

-Test four, closed loop
ok :slight_smile:
For the moment, it’s a perfect vibrating massager for the lady.
I’m working on improving :-p
On vacation this weekend, back on Monday …

look at the examples, there is one that finds the max and min pulse width for you.

Hello,

SimpleFOCMini is really easy to use.
On the other hand, “B-G431B-ESC1” is really very complex, it really lacks “SPI” support for me …

After a lot of reading of your documents (thank you) and time spent testing,
-I now have an “angle” mode that works well.
-a “velocity” mode that works perfectly,
-However, I haven’t managed to get a stable “torque” mode…

Too bad, for this project I need to maintain an adjustable tension on a cable.
It’s for lab rats that need to be relieved of 40% of their weight by a suspension system, to measure muscle loss.

For the moment I’ve got what I want to do via the “velocity” mode by limiting “motor.current_limit” in “setup”.
In my opinion, it would have been preferable to achieve this using the “torque” mode.

If you see any errors in my example, please don’t hesitate to advise me.

The current code:

/*
  Sensor zero offset is:
  21:07:12.763 -> 1.2046
  21:07:12.763 -> Sensor natural direction is:
  21:07:12.763 -> Direction::CW
  21:07:12.763 -> To use these values provide them to the: motor.initFOC(offset, direction)
  21:07:13.758 -> If motor is not moving the alignment procedure was not successfull!!
*/

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

// BLDC motor instance BLDCMotor(polepairs, (R), (KV))
BLDCMotor motor = BLDCMotor(11, 5.57, 197);

//this line must be changed for each board
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
// https://docs.simplefoc.com/low_side_current_sense
// LowsideCurrentSense constructor
//  - shunt_resistor  - shunt resistor value
//  - gain  - current-sense op-amp gain
//  - phA   - A phase adc pin
//  - phB   - B phase adc pin
//  - phC   - C phase adc pin (optional)
LowsideCurrentSense currentSense = LowsideCurrentSense(0.003f, -64.0f / 7.0f, A_OP1_OUT, A_OP2_OUT, A_OP3_OUT);

//sensor @PWM
MagneticSensorPWM sensor = MagneticSensorPWM(PB6, 3, 920); //3, 932   OK pour moi frafa

// instantiate the commander
Commander command = Commander(Serial);

// SimpleFOCStudio
void doMotor(char* cmd) {
  command.motor(&motor, cmd);
}

// target
void onTarget(char* cmd) {
  command.target(&motor, cmd);
}

//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬setup▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
void setup() {
  // 1(Amp)/1023(Val Pot) = 0,000977517
  float map_pot = analogRead(A_POTENTIOMETER) * 0.000977517;

  // initialise magnetic sensor hardware
  sensor.init();

  // driver config

  // pwm frequency to be used [Hz]
  // for atmega328 fixed to 32kHz
  // esp32/stm32/teensy configurable
  driver.pwm_frequency = 100000; // 100000

  // power supply voltage [V]
  driver.voltage_power_supply = 12;

  // Max DC voltage allowed - default voltage_power_supply
  driver.voltage_limit = 12; // [V]

  // init driver
  if (driver.init())  Serial.println("Driver init success!");
  else {
    Serial.println("Driver init failed!");
    return;
  }

  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // link the motor and the driver
  motor.linkDriver(&driver);

  // link current sense and the driver
  currentSense.linkDriver(&driver);

  // current sensing
  currentSense.init();
  // no need for aligning
  currentSense.skip_align = true;
  motor.linkCurrentSense(&currentSense);

  //▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬SimpleFOCStudio_config▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

  // torque mode
  motor.torque_controller = TorqueControlType::foc_current;

  // Control loop type
  // MotionControlType::torque      - torque control
  // MotionControlType::velocity    - velocity motion control
  // MotionControlType::angle       - position/angle motion control
  //motor.controller = MotionControlType::angle; // angle velocity torque
  //motor.controller = MotionControlType::torque; // angle velocity torque
  motor.controller = MotionControlType::velocity; // angle velocity torque

  motor.motion_downsample = 0.0; // https://docs.simplefoc.com/bldcmotor

  // pwm modulation settings
  motor.foc_modulation = FOCModulationType::SinePWM;
  motor.modulation_centered = 1.0;

  // velocity loop PID
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20.0;
  motor.PID_velocity.D = 0.001;
  motor.PID_velocity.output_ramp = 1000.0;
  //motor.PID_velocity.limit = 1.0;  // ? current_limit [Amps]
  // Low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;

  // angle loop PID
  motor.P_angle.P = 14.0;
  motor.P_angle.I = 0.0;
  motor.P_angle.D = 0.0;
  motor.P_angle.output_ramp = 10000.0;
  //motor.P_angle.limit = 50.0; // ? velocity_limit [rad/s]
  // Low pass filtering time constant
  motor.LPF_angle.Tf = 0.001;

  // current q loop PID
  motor.PID_current_q.P = 0.1;
  motor.PID_current_q.I = 30.0;
  motor.PID_current_q.D = 0.0;
  motor.PID_current_q.output_ramp = 0.0;
  motor.PID_current_q.limit = 12.0;
  // Low pass filtering time constant
  motor.LPF_current_q.Tf = 0.005;
  // current d loop PID
  motor.PID_current_d.P = 0.1;
  motor.PID_current_d.I = 30.0;
  motor.PID_current_d.D = 0.0;
  motor.PID_current_d.output_ramp = 0.0;
  motor.PID_current_d.limit = 12.0;
  // Low pass filtering time constant
  motor.LPF_current_d.Tf = 0.005;

  // Limits
  motor.velocity_limit = 50.0; // [rad/s] cca ~500rpm
  motor.voltage_limit = 12.0; // [Volts]
  //motor.current_limit = 1.0f; // 1.0 [Amps] - if phase resistance defined
  motor.current_limit = map_pot; // 1.0 [Amps] - if phase resistance defined

  // sensor zero offset - home position
  motor.sensor_offset = 0.0;

  // general settings
  // motor phase resistance // I_max = V_dc/R
  //motor.phase_resistance = 5.57; // 5.7 5.57 [Ohm]
  // motor KV rating [rpm/V]
  //motor.KV_rating = 197; // [rpm/Volt] - default not set
  // direction
  motor.sensor_direction = Direction::CW;

  //▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_SimpleFOCStudio_config▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬


  // monitoring port
  Serial.begin(115200);
  //delay(1000);
  // tell the motor to use the monitoring
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 0; // 0 = disable monitor at first - optional


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

  // https://docs.simplefoc.com/theory_corner
  // https://github.com/simplefoc/Arduino-FOC/blob/dev/src/common/defaults.h
  // https://docs.simplefoc.com/cheetsheet/options_reference
  // https://docs.simplefoc.com/commander_interface
  // https://docs.simplefoc.com/commander_motor
  // https://docs.simplefoc.com/commander_target

  // https://docs.simplefoc.com/studio
  // add the motor to the commander interface
  // The letter (here 'M') you will provide to the SimpleFOCStudio
  command.decimal_places = 4; // default 3
  command.add('M', doMotor, "motor");
  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target current using serial terminal:"));

  // T
  command.add('T', onTarget, "Target setting");

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

  Serial.println("A_POTENTIOMETER Limit Amps:" + String(map_pot) + " [Amps]");

  _delay(1000);
} // End_setup
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_setup▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬


//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬loop▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
void loop() {

  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move();

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  motor.monitor();

  // user communication
  command.run();
} // End_loop
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_loop▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

Well velocity mode is built on top of torque mode. I don’t know exactly how to get it working but I am sure it must be possible. I would start with the examples and carefully modify them and weave them together with your existing code until you got something that worked to some degree. I would get voltage mode working first as it’s basically just as good as current mode. I mean the torque is only approximate anyway, you get more or you get less, whether you are upping current or voltage makes little difference in this context I think. Just try to get voltage torque mode working.

There would be a glitch at top dead center remember, IDK if that’s an issue for you, if you use pwm mode. I think you should be able to use I2C, I had little issue with noise as long as I kept the wires apart from the motor wires. Also IDK why you cannot put the board closer to the motor?

Oh right you are set on this particular encoder. PWM is probably fine, these support analog too but it has similar inconveniences at top dead center.

Thanks Anthony,
I’m going back into “simpleFOCStudio” to try and get the “torque” mode working.

Hello;

I can’t control speed in torque mode

In “velocity” mode:
if I use Commander with command M10 0.5
it’s ok I have velocity at 10 and current at 0.5

  motor.torque_controller = TorqueControlType::foc_current;
  motor.controller = MotionControlType::velocity;

In “torque” mode:
if I use Commander with command M0.5 10
it doesn’t work, I can only control “current ==> 0.5” the speed remains at maximum (velocity 130)
impossible to control speed

  motor.torque_controller = TorqueControlType::foc_current;
  motor.controller = MotionControlType::torque;

How do I control the speed in torque mode ?

You can’t control speed in torque mode, only torque, that’s why it’s called torque mode.

Ok, thanks Antony for your answer :slight_smile:

I have a forceless position at encoder zero
Is it due to the PWM mode of my encoder ?
sorry for my brooken English …

Hm, a position where the motor stops turning? That could be due to the dead spot at the top of a motor which uses a sensor with PWM output, however the dead spot is quite small, I think only less than half a degree. You aren’t likely to notice it but it does cause some clicking and glitching noises, that is the only reason I noticed it.

If I put 1 amps on my motor and hold it by hand to force it,
I can feel it losing power at the same point.
Motor GM3506

This problem is present in “torque” or “Velocity” mode.

Actual code test:

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

// https://docs.simplefoc.com/cheetsheet/build_flags ==> buils_opt.h

// BLDC motor instance BLDCMotor(polepairs, (R), (KV))
BLDCMotor motor = BLDCMotor(11, 5.57, 197);

//this line must be changed for each board
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
// https://docs.simplefoc.com/low_side_current_sense
// LowsideCurrentSense constructor
//  - shunt_resistor  - shunt resistor value
//  - gain  - current-sense op-amp gain
//  - phA   - A phase adc pin
//  - phB   - B phase adc pin
//  - phC   - C phase adc pin (optional)
LowsideCurrentSense currentSense = LowsideCurrentSense(0.003f, -64.0f / 7.0f, A_OP1_OUT, A_OP2_OUT, A_OP3_OUT);

//sensor @PWM https://docs.simplefoc.com/magnetic_sensor_pwm
MagneticSensorPWM sensor = MagneticSensorPWM(PB6, 3, 920); //3, 932   OK pour moi frafa

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

// instantiate the commander
Commander command = Commander(Serial);

// motor SimpleFOCStudio ==> M
void doMotor(char* cmd) {
  command.motor(&motor, cmd);
}

// target ==> T
void onTarget(char* cmd) {
  command.target(&motor, cmd);
}


//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬setup▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
void setup() {
  // monitoring port
  Serial.begin(115200);
  _delay(1000);

  // 1(Amp)/1023(Val Pot) = 0,000977517
  float map_pot = analogRead(A_POTENTIOMETER) * 0.000977517;

  // Magnetic Sensor PẄM
  // https://docs.simplefoc.com/magnetic_sensor_pwm
  sensor.min_elapsed_time = 0.0001; // 100us by default
  // initialise magnetic sensor hardware
  sensor.init();
  // comment out to use sensor in blocking (non-interrupt) way
  sensor.enableInterrupt(doPWM);
  Serial.println("Sensor ready");
  _delay(1000);

  // driver config
  // pwm frequency to be used [Hz]
  // for atmega328 fixed to 32kHz
  // esp32/stm32/teensy configurable
  driver.pwm_frequency = 40000; // 100000

  // power supply voltage [V]
  driver.voltage_power_supply = 12;

  // Max DC voltage allowed - default voltage_power_supply
  driver.voltage_limit = 12; // [V]

  // init driver
  if (driver.init())  Serial.println("Driver init success!");
  else {
    Serial.println("Driver init failed!");
    return;
  }

  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // link the motor and the driver
  motor.linkDriver(&driver);

  // link current sense and the driver
  currentSense.linkDriver(&driver);

  // current sensing
  currentSense.init();
  // no need for aligning
  currentSense.skip_align = true;  // true/false
  motor.linkCurrentSense(&currentSense);

  //▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬SimpleFOCStudio_config▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

  // index search velocity [rad/s]
  // https://docs.simplefoc.com/index_search_loop
  //motor.velocity_index_search = 3; // rad/s
  //motor.voltage_sensor_align = 4; // Volts

  // set torque mode
  // https://docs.simplefoc.com/foc_current_torque_mode
  motor.torque_controller = TorqueControlType::foc_current; // foc_current || dc_current || voltage

  // Control loop type
  // MotionControlType::torque      - torque control
  // MotionControlType::velocity    - velocity motion control
  // MotionControlType::angle       - position/angle motion control
  //motor.controller = MotionControlType::angle; // angle velocity torque
  //motor.controller = MotionControlType::torque; // angle velocity torque
  motor.controller = MotionControlType::torque; // angle velocity torque

  // pwm modulation settings
  //motor.foc_modulation = FOCModulationType::SinePWM;
  //motor.modulation_centered = 1.0;

  /*
    Pour de nombreuses applications de contrôle de mouvement, il est judicieux d'exécuter
    plusieurs boucles de contrôle de couple pour chaque boucle de contrôle de mouvement.
    Cela peut avoir un impact important sur la fluidité et peut fournir de meilleures performances à grande vitesse.
    C'est pourquoi cette bibliothèque permet une stratégie de sous-échantillonnage très simple pour la fonction move()
    qui est définie à l'aide du paramètre

    La stratégie de downsampling fonctionne de manière très simple, même si la fonction motor.move()
    est appelée dans chaque boucle arduino, elle ne sera exécutée qu'à chaque fois que motor.motion_downsample sera appelé.
    Ce paramètre est optionnel et peut être configuré en temps réel.
  */
  motor.motion_downsample = 0; // https://docs.simplefoc.com/bldcmotor

  //▬▬▬▬▬▬▬▬▬▬▬▬ALL_PID▬▬▬▬▬▬▬▬▬▬▬▬
  // velocity loop PID
  motor.PID_velocity.P = 0.8; // 1.2
  motor.PID_velocity.I = 20.0;
  motor.PID_velocity.D = 0.001; // 0.001
  motor.PID_velocity.output_ramp = 1000.0;
  //motor.PID_velocity.limit = 1.0;  // ? current_limit [Amps]
  // Low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01; //0.01

  // angle loop PID
  motor.P_angle.P = 14.0; // 14.0
  motor.P_angle.I = 0.0;
  motor.P_angle.D = 0.0;
  motor.P_angle.output_ramp = 10000.0; // 10000.0
  //motor.P_angle.limit = 50.0; // ? velocity_limit [rad/s]
  // Low pass filtering time constant
  motor.LPF_angle.Tf = 0.001;

  // current q loop PID
  motor.PID_current_q.P = 0.5; // 3
  motor.PID_current_q.I = 50.0; // 300
  //motor.PID_current_q.D = 0.0;
  //motor.PID_current_q.output_ramp = 0.0;
  //motor.PID_current_q.limit = 12.0;
  // Low pass filtering time constant
  //motor.LPF_current_q.Tf = 0.005;
  // current d loop PID
  motor.PID_current_d.P = 0.5; // 3
  motor.PID_current_d.I = 50.0; // 300
  //motor.PID_current_d.D = 0.0;
  //motor.PID_current_d.output_ramp = 0.0;
  //motor.PID_current_d.limit = 12.0;
  // Low pass filtering time constant
  //motor.LPF_current_d.Tf = 0.005;

  //▬▬▬▬▬▬▬▬▬▬▬▬Limits▬▬▬▬▬▬▬▬▬▬▬▬
  motor.velocity_limit = 3.0; // [rad/s]
  //motor.voltage_limit = 12.0; // [Volts]
  motor.voltage_limit = 5.6; //  // Calcul ==> 5.57[Ohms]*1.0[Amps]=5,57[Volts]
  //motor.current_limit = 1.0f; // 1.0 [Amps] - if phase resistance defined
  motor.current_limit = map_pot; // 1.0 [Amps] - if phase resistance defined

  //▬▬▬▬▬▬▬▬▬▬▬▬general settings▬▬▬▬▬▬▬▬▬▬▬▬
  // motor phase resistance // I_max = V_dc/R
  motor.phase_resistance = 5.57; // 5.7 5.57 [Ohms]
  // motor KV rating [rpm/V]
  //motor.KV_rating = 197; // [rpm/Volt] - default not set

  // sensor zero offset - home position
  //motor.sensor_offset = 0;
  // zero_electric_angle
  motor.zero_electric_angle = 1.2046; // 1.2046

  // direction
  motor.sensor_direction = Direction::CW; // Cw/CCW

  //▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_SimpleFOCStudio_config▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

  /*
    SimpleFOCDebug::enable();
    build_flags =
    -D SIMPLEFOC_STM32_DEBUG
    -D SERIAL_UART_INSTANCE=2
  */

  // tell the motor to use the monitoring
  // https://docs.simplefoc.com/monitoring
  motor.useMonitoring(Serial);
  motor.monitor_downsample = 0; // 0 = disable monitor at first - optional

  // initialize motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();
  //motor.initFOC(1.2046, Direction::CCW); // compile pas ?

  // https://docs.simplefoc.com/low_side_current_sense
  // https://docs.simplefoc.com/theory_corner
  // https://github.com/simplefoc/Arduino-FOC/blob/dev/src/common/defaults.h
  // https://docs.simplefoc.com/cheetsheet/options_reference
  // https://docs.simplefoc.com/commander_interface
  // https://docs.simplefoc.com/commander_motor
  // https://docs.simplefoc.com/commander_target

  // https://docs.simplefoc.com/studio
  // add the motor to the commander interface
  // The letter (here 'M') you will provide to the SimpleFOCStudio
  command.decimal_places = 4; // default 3
  command.add('M', doMotor, "motor");
  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target current using serial terminal: (Exemple M0.5 10)"));

  // Target setting Exemple ==> T10 0.2
  command.add('T', onTarget, "target vel (+ torque limit)");

  // set the inital target value
  //motor.target = -10; // -10

  Serial.println("A_POTENTIOMETER Limit Amps:" + String(map_pot) + " [Amps]");

  _delay(1000);
} // End_setup
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_setup▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬


//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬loop▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
void loop() {

  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move();

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  motor.monitor();

  // user communication
  command.run();
} // End_loop
//▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬End_loop▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

How large is the region? I would print out the values of the sensor (it’s a sensor not an encoder, they are a bit different although the terms are often exchanged). If it’s top dead center i.e. very close to maximal value or very close to minimal, that could lead to some glitching in motor torque due to changes in motor timing however for the most part I think it would still work, you wouldn’t really notice it like that to such a degree.

Did you do the thing where it measures the maximum and minumum pulse time from the PWM and plug those numbers into your code? If not that could explain it. If you don’t do that you get a larger dead zone, the sensor will de facto read 2pi or zero in that zone, so the commutation would halt and you would feel a sort of detent, however it would still tend to snap to one particular position…

Just print everything that might be affecting it and try to ascertain which part of the system isn’t doing what you thought it was supposed to, this is what I always say but it works.

Yes, I did all the calibration tests.
https://github.com/simplefoc/Arduino-FOC/tree/master/examples/utils/calibration

Tomorrow I’ll make a video, you’ll see better.
And another problem: if I reverse the direction of the motor (Example M-0.8), it’s a disaster,
it always vibrates in the same place…

Just wanted to chime in with my own observations: I had this dead spot everytime with the sFOC mini. Even in openloop…
Maybe it’s just caused by a little longer control loop due to the turnover from 2PI to 0?

Did you define the variables A_PHASE… etc. somewhere? Or are there default values because you are using a specific board?

In open loop? IDK what’s going on there, there are a lot of things that could be going on when you roll your own system like this with a novel microcontroller and so forth. I never noticed this with the g431 board and I did a lot of stuff with open loop. There was a mysterious glitch once per revolution I think at top dead center however it appeared to mostly go away when I used a core with floating point hardware.