Quiet enable & disable or: how to freewheel a motor?

Hi there,

is there any way to enable and disable the motor without any audible clicks?
i am currently trying to have an algorithm which can set the motor to freewheel (no current whatsoever) and then enable to do some rotation.

the setup:
simplefoc mini, bldc with AS5048A encoder (https://shrl.pfcace.de/YUmH) connected to esp32 (also tried Arduino Mega with the same results.

So for testing i wanted to have the following setup: Motor is paused and freewheeling for a second, then for a second rotating, and then repeat this.

what i have tried:

Attempt 1: Direct enable/disable with immediate target
Approach: Call motor.enable(), immediately set target and call motor.move()
if (motorOn) {
motor.enable();
motor.target = RUN_TARGET;
motor.move();
} else {
motor.disable();
}
Result: clicking on both enable and disable. The abrupt transition causes mechanical response.

Attempt 2: Keep motor enabled, only change target + PID output ramp
Approach: Enable motor once at startup, only change target between RUN_TARGET and 0

// In setup()
motor.PID_velocity.output_ramp = 100.0f; // Limit PID output change rate
motor.enable(); // Only once
// In loop()
motor.target = motorOn ? RUN_TARGET : 0.0f;
motor.move();

Result: No clicking! But motor actively holds position at 0 (no freewheeling).

Attempt 3: Ramp down before disable
Approach: Gradually reduce target to 0, then disable

if (isRampingDown) {
unsigned long elapsed = now - rampStartTime;
if (elapsed < RAMP_DOWN_MS) {
float progress = 1.0f - (float(elapsed) / float(RAMP_DOWN_MS));
motor.target = RUN_TARGET * progress;
motor.move();
} else {
motor.disable();
isRampingDown = false;
}
}

Result: Clicking still present when motor.disable() is called.

Attempt 4: Ramp down + settle time before disable
Approach: Add settle time at target=0 before calling disable

if (elapsed < RAMP_DOWN_MS) {
    // Ramp down
float progress = 1.0f - (float(elapsed) / float(RAMP_DOWN_MS));
motor.target = RUN_TARGET * progress;
motor.move();
} else if (elapsed < RAMP_DOWN_MS + SETTLE_MS) {
    // Settle at 0
motor.target = 0.0f;
motor.move();
} else {
motor.disable();
isRampingDown = false;
}

Result: Clicking reduced but still audible. Even with motor stationary, enable pin switching causes noise.

Attempt 5: Manual phase control instead of motor.disable()
Approach: Set PWM to 0, phases to high-impedance, disable internally without using motor.disable()

// Set PWM to 0
driver.setPwm(0, 0, 0);
// Set phases to high-impedance
driver.setPhaseState(PhaseState::PHASE_OFF, PhaseState::PHASE_OFF, PhaseState::PHASE_OFF);
// Mark motor as disabled internally
motor.enabled = 0;


Result: No freewheeling - motor still has holding force. The enable pins stay active.

Attempt 6: Manual phase control + disable enable pins

Approach: Same as above but manually toggle enable pins

driver.setPwm(0, 0, 0);
driver.setPhaseState(PhaseState::PHASE_OFF, PhaseState::PHASE_OFF, PhaseState::PHASE_OFF);
motor.enabled = 0;
// Manually disable enble pins
if (_isset(driver.enableA_pin))
digitalWrite(driver.enableA_pin, !driver.enable_active_high);
if (_isset(driver.enableB_pin))
digitalWrite(driver.enableB_pin, !driver.enable_active_high);
if (_isset(driver.enableC_pin))
digitalWrite(driver.enableC_pin, !driver.enable_active_high);

Result: True freewheeling achieved, but clicking still present. The enable pin switching is the source of the noise (i guess)

Question:

Is there a way to achieve true freewheeling (complete motor coast) without audible clicking from enable pin switching?

Hardware: ESP32 + BLDCDriver3PWM with single enable pin (MOTOR_ENABLE connected to all three enable inputs)

The clicking appears to be mechanical/electrical response to the enable pin state change. Even with motor at complete standstill and PWM at 0, switching the enable pin causes an audible click.

Any suggestions appreciated!

Hi @pcace ,

some comments:

When setting the phase state, you have to call setPwm() afterwards for the new phase state to take effect.

So you should change the order of your calls in examples #5 and #6 and call setPwm() after setting the phase state.

Also note that setting phase state isn’t supported on all the MCU types, and generally only when using a 6-PWM driver. On ESP32 it’s supported only in 6-PWM mode, so not useful in your setup.

On the ATMega MCUs it’s also not supported in 3PWM.

Since all your driver enable signals are connected to the same pin there is not much point in setting them individually like in example #6

One thing you can try is ramping down the motor.voltage_limit before setting the disable. This would have the effect of reducing the output torque and phase voltages gradually before the disable, and may help against the clicking, which is presumably caused by the sudden removal or application of power to the motor.