# Can't control the velocity of a BLDC Motor with Simplefoc mini V1.0, Help please!

**URL:** https://community.simplefoc.com/t/cant-control-the-velocity-of-a-bldc-motor-with-simplefoc-mini-v1-0-help-please/7276
**Category:** hardware support
**Tags:** esp32
**Created:** [June 5, 2025, 3:24pm UTC](https://community.simplefoc.com/t/cant-control-the-velocity-of-a-bldc-motor-with-simplefoc-mini-v1-0-help-please/7276 "2025-06-05T15:24:23Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Jose\_Francisco\_Arias](https://community.simplefoc.com/user_avatar/community.simplefoc.com/jose_francisco_arias/32/8800_2.png) [@Jose\_Francisco\_Arias](https://community.simplefoc.com/u/Jose_Francisco_Arias)
#### Post date: [June 5, 2025, 3:24pm UTC](https://community.simplefoc.com/t/cant-control-the-velocity-of-a-bldc-motor-with-simplefoc-mini-v1-0-help-please/7276/1 "2025-06-05T15:24:23Z")

</div>

Hey everyone,

I’m working on a project where I need to control the rotational speed of a BLDC motor from 0 up to 3000 RPM. I’m using a **42BLS40-24-01** motor, which is rated for up to 4000 RPM, with a **phase resistance of 1.9 ohms** and a **maximum current of 1.8 A**. The setup includes an **ESP32** and a **SimpleFOC Mini v1.0** driver.

I was able to get the motor running smoothly in **open-loop velocity mode** , but when switching to **closed-loop velocity control** using **Hall sensors** , I’ve been running into serious issues. The motor only moves in large, jerky steps and the `shaftVelocity()` always reports **0 rad/s** in the serial monitor.

What I’ve tried so far:

- Swapping the Hall sensor pin order (A, B, C in different combinations)
- Swapping motor phases
- Tuning the PID controller (P, I, D). This _slightly_ improved performance and let the motor rotate at ~1 rad/s, but it’s still far from stable or usable
- Verified Hall sensor signals using an oscilloscope – they look fine and respond to movement, and if I rotate the shaft with my hand the reported speed changes.
- I’m also using a **Schmitt trigger inverter** to shift the Hall signals from 5 V to 3.3 V, two times to keep the same signal, and I’ve added **pull-up resistors** on the signal lines

In open-loop, the motor behaves as expected but obviously I can’t use it for accurate speed control. Below are a couple of the test codes I’ve been working with, but so far no luck getting reliable closed-loop behavior.

If anyone has ideas on what might be going wrong—timing, sensor configuration, PID settings, etc.—I’d really appreciate some help.

Thanks in advance!

Opoen loop code:  
#include \<Arduino.h\>  
#include \<Wire.h\>  
#include \<LiquidCrystal\_I2C.h\>  
#include \<SimpleFOC.h\>

// DRV8313  
const int IN1 = 25;  
const int IN2 = 13;  
const int IN3 = 26;  
const int EN\_PIN = 32;  
BLDCMotor motor = BLDCMotor(4);  
BLDCDriver3PWM driver = BLDCDriver3PWM(IN1, IN2, IN3, EN\_PIN);

void setup() {  
Serial.begin(9600);  
Serial.println(“Iniciando…”);

// Driver setup  
pinMode(EN\_PIN, OUTPUT);  
digitalWrite(EN\_PIN, HIGH);

driver.voltage\_power\_supply = 24;  
driver.voltage\_limit = 6.0;  
driver.init();

// Motor setup  
motor.linkDriver(&driver);  
motor.controller = MotionControlType::velocity\_openloop;  
motor.voltage\_limit = 6.0;  
motor.init();  
motor.target = 1.0; // rad/s inicial  
}

void loop() {  
motor.loopFOC();  
motor.move();

// Aumentar gradualmente la velocidad  
static float velocidad = 1.0;  
static unsigned int count = 0;  
count++;  
if (count \>= 250) {  
velocidad += 5;  
if (velocidad \> 150) velocidad = 1.0;  
motor.target = velocidad;  
Serial.print("Velocidad objetivo: ");  
Serial.println(velocidad\*60/ (2 \* PI));  
count = 0;  
}

delay(5);  
}

Closed loop code 1:  
#include \<Arduino.h\>  
#include \<Wire.h\>  
#include \<LiquidCrystal\_I2C.h\>  
#include \<SimpleFOC.h\>

//DRV8313  
const int IN1 = 25;  
const int IN2 = 13;  
const int IN3 = 26;  
const int EN\_PIN = 32;

//Hall  
const int HALL\_A = 4;  
const int HALL\_B = 16;  
const int HALL\_C = 17;

// Motor y driver  
BLDCMotor motor = BLDCMotor(4,1.9);//Pole pairs and phase resistance  
BLDCDriver3PWM driver = BLDCDriver3PWM(IN1, IN2, IN3, EN\_PIN);  
HallSensor sensor = HallSensor(HALL\_A, HALL\_B, HALL\_C, 4);

void doA() { sensor.handleA(); }  
void doB() { sensor.handleB(); }  
void doC() { sensor.handleC(); }

void setup() {  
Serial.begin(9600);  
Serial.println(“Iniciando closed-loop con sensores Hall…”);

sensor.init();  
sensor.enableInterrupts(doA, doB, doC);

driver.voltage\_power\_supply = 24;  
driver.init();

motor.linkDriver(&driver);  
motor.linkSensor(&sensor);  
motor.current\_limit = 1.8;  
motor.controller = MotionControlType::velocity;

motor.PID\_velocity.P = 0.2f;  
motor.PID\_velocity.I = 5.0f;  
motor.PID\_velocity.D = 0.0f;

motor.LPF\_velocity.Tf = 0.02f;  
motor.PID\_velocity.output\_ramp = 1000;

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

motor.target = 5.0;  
Serial.println(“Motor listo en closed-loop”);  
}

void loop() {  
motor.loopFOC();  
motor.move();

float vel\_rad\_s = motor.shaftVelocity();  
float vel\_rpm = vel\_rad\_s \* 60.0 / (2.0 \* PI);

Serial.print("Sensor angle: ");  
Serial.println(sensor.getAngle());  
Serial.print("Sensor velocity: ");  
Serial.println(sensor.getVelocity());  
delay(200);  
}

Closed loop code 2:  
#include \<Arduino.h\>  
#include \<Wire.h\>  
#include \<LiquidCrystal\_I2C.h\>  
#include \<SimpleFOC.h\>

//DRV8313  
const int IN1 = 25;  
const int IN2 = 13;  
const int IN3 = 26;  
const int EN\_PIN = 32;

//Hall  
const int HALL\_A = 4;  
const int HALL\_B = 16;  
const int HALL\_C = 17;

// Motor y driver  
BLDCMotor motor = BLDCMotor(4);  
BLDCDriver3PWM driver = BLDCDriver3PWM(IN1, IN2, IN3, EN\_PIN);  
HallSensor sensor = HallSensor(HALL\_A, HALL\_B, HALL\_C, 4);

void doA() { sensor.handleA(); }  
void doB() { sensor.handleB(); }  
void doC() { sensor.handleC(); }

void setup() {  
Serial.begin(9600);  
Serial.println(“Iniciando closed-loop con sensores Hall…”);

// Habilitar driver  
pinMode(EN\_PIN, OUTPUT);  
digitalWrite(EN\_PIN, HIGH);

// Inicializar sensor Hall  
sensor.init();  
sensor.enableInterrupts(doA, doB, doC);

// Inicializar driver  
driver.voltage\_power\_supply = 24;  
driver.voltage\_limit = 12;  
driver.init();

// Configurar motor  
motor.linkDriver(&driver);  
motor.linkSensor(&sensor);  
motor.voltage\_limit = 12; // Voltaje máximo de salida  
motor.controller = MotionControlType::velocity;

// Parámetros PID de velocidad  
motor.PID\_velocity.P = 0.4f;  
motor.PID\_velocity.I = 0.025f;  
motor.PID\_velocity.D = 0.0f;

// Filtro pasa bajas y rampa de salida  
motor.LPF\_velocity.Tf = 0.01f;  
motor.PID\_velocity.output\_ramp = 1000;

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

motor.target = 2.0;  
Serial.println(“Motor listo en closed-loop”);  
}

void loop() {  
motor.loopFOC();  
motor.move();

float vel\_rad\_s = motor.shaftVelocity();  
float vel\_rpm = vel\_rad\_s \* 60.0 / (2.0 \* PI);

Serial.print("Sensor angle: ");  
Serial.println(sensor.getAngle());  
Serial.print("Sensor velocity: ");  
Serial.println(sensor.getVelocity());  
delay(200);  
}

 ![42bls](https://community.simplefoc.com/uploads/default/original/2X/6/658e9634aa1279651e3e0ad24952d92279c232e9.jpeg)
