Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vedderb/bldc/llms.txt

Use this file to discover all available pages before exploring further.

VESC firmware supports trapezoidal (six-step) BLDC commutation as an alternative to FOC. BLDC mode has lower computational overhead and can work well for high-speed, low-torque applications where smooth sinusoidal current waveforms are not required.
The default motor type is FOC. To use BLDC mode, set MCCONF_DEFAULT_MOTOR_TYPE to MOTOR_TYPE_BLDC or change the motor type in VESC Tool.

PWM modes

The PWM switching scheme is selected via mc_pwm_mode in datatypes.h:
typedef enum {
    PWM_MODE_NONSYNCHRONOUS_HISW = 0,  // Not recommended
    PWM_MODE_SYNCHRONOUS,              // Recommended
    PWM_MODE_BIPOLAR                   // Use with caution
} mc_pwm_mode;

NONSYNCHRONOUS_HISW

High-side switching only. The low-side switch freewheels. Not recommended — higher losses and less reliable current sensing.

SYNCHRONOUS

Both high-side and low-side switches are actively controlled. This is the recommended and most tested mode. Default.

BIPOLAR

Drives both phases of the active pair simultaneously. Doubles the effective switching frequency. Can cause MOSFET failures — use with caution.
The default is PWM_MODE_SYNCHRONOUS (MCCONF_PWM_MODE).

Commutation modes

The commutation zero-crossing detection strategy is set via mc_comm_mode:
typedef enum {
    COMM_MODE_INTEGRATE = 0,
    COMM_MODE_DELAY
} mc_comm_mode;
ModeDescription
COMM_MODE_INTEGRATEIntegrates the BEMF signal and commutates when the integral reaches a threshold. More robust to noise. Default.
COMM_MODE_DELAYCommutates after a fixed time delay from the zero-crossing. Simpler but more sensitive to speed changes.
The default is COMM_MODE_INTEGRATE (MCCONF_COMM_MODE). You can switch modes at runtime:
void mcpwm_set_comm_mode(mc_comm_mode mode);
mc_comm_mode mcpwm_get_comm_mode(void);
void mcpwm_switch_comm_mode(mc_comm_mode next); // schedule a mode switch

Sensor modes

BLDC sensor mode is set via mc_sensor_mode:
typedef enum {
    SENSOR_MODE_SENSORLESS = 0,
    SENSOR_MODE_SENSORED,
    SENSOR_MODE_HYBRID
} mc_sensor_mode;
ModeDescription
SENSOR_MODE_SENSORLESSBEMF-based commutation. No position sensor required. Default.
SENSOR_MODE_SENSOREDHall sensors control commutation at all speeds.
SENSOR_MODE_HYBRIDHall sensors are used below MCCONF_HALL_ERPM (default: 2000 ERPM); sensorless above.
The hall sensor angle-to-commutation mapping is stored in a lookup table. Initialize it with:
void mcpwm_init_hall_table(int8_t *table);
Default hall table values (BLDC mode):
IndexDefault
MCCONF_HALL_TAB_0-1 (invalid)
MCCONF_HALL_TAB_11
MCCONF_HALL_TAB_23
MCCONF_HALL_TAB_32
MCCONF_HALL_TAB_45
MCCONF_HALL_TAB_56
MCCONF_HALL_TAB_64
MCCONF_HALL_TAB_7-1 (invalid)

Sensorless parameters

Sensorless BLDC commutation depends on the BEMF flux integrator. Key parameters:
ParameterDefaultDescription
MCCONF_SL_MIN_RPM150 ERPMAuto-commutate (open-loop startup) below this RPM
MCCONF_SL_CYCLE_INT_LIMIT62.0Flux integrator limit at 0 ERPM
MCCONF_SL_MIN_ERPM_CYCLE_INT_LIMIT1100 ERPMMinimum ERPM for calculating BEMF coupling
MCCONF_SL_BEMF_COUPLING_K600.0Input voltage to BEMF coupling constant
MCCONF_SL_PHASE_ADVANCE_AT_BR0.8Integrator limit percentage at MCCONF_SL_CYCLE_INT_BR
MCCONF_SL_CYCLE_INT_BR80000 ERPMRPM boundary between start and low-speed intervals
MCCONF_SL_MAX_FB_CURR_DIR_CHANGE10.0 AMaximum brake current during which direction changes are allowed

Switching frequency

In BLDC mode the switching frequency scales with motor speed between a minimum and maximum:
ParameterDefaultDescription
MCCONF_M_BLDC_F_SW_MIN3000 HzMinimum switching frequency
MCCONF_M_BLDC_F_SW_MAX35000 HzMaximum switching frequency
For DC motor mode, a fixed switching frequency is used:
ParameterDefaultDescription
MCCONF_M_DC_F_SW25000 HzDC mode switching frequency

Current control (BLDC mode)

ParameterDefaultDescription
MCCONF_CC_GAIN0.0046Current controller error gain
MCCONF_CC_MIN_CURRENT0.05 AMinimum current in current control mode
MCCONF_CC_STARTUP_BOOST_DUTY0.01Minimum duty cycle in current control mode
MCCONF_CC_RAMP_STEP0.04Maximum duty cycle ramp step in current control mode

RPM measurement

#define MCPWM_RPM_TIMER_FREQ  1000000.0  // Hz — timer frequency for RPM measurement

The mcpwm API

The mcpwm module implements the BLDC algorithm directly. Use mc_interface for normal operation; the mcpwm API is available for low-level access:
// Initialization
void mcpwm_init(volatile mc_configuration *configuration);
void mcpwm_deinit(void);
bool mcpwm_init_done(void);
void mcpwm_set_configuration(volatile mc_configuration *configuration);

// Control
void mcpwm_set_duty(float dutyCycle);
void mcpwm_set_duty_noramp(float dutyCycle);
void mcpwm_set_pid_speed(float rpm);
void mcpwm_set_pid_pos(float pos);
void mcpwm_set_current(float current);
void mcpwm_set_brake_current(float current);
void mcpwm_brake_now(void);
void mcpwm_release_motor(void);
void mcpwm_stop_pwm(void);

// State and telemetry
mc_state mcpwm_get_state(void);
float mcpwm_get_duty_cycle_set(void);
float mcpwm_get_duty_cycle_now(void);
float mcpwm_get_switching_frequency_now(void);
float mcpwm_get_rpm(void);
float mcpwm_get_kv(void);              // motor KV (RPM/V)
float mcpwm_get_kv_filtered(void);
int mcpwm_get_comm_step(void);         // current commutation step (1-6)

// Current
float mcpwm_get_tot_current(void);
float mcpwm_get_tot_current_filtered(void);
float mcpwm_get_tot_current_directional(void);
float mcpwm_get_tot_current_directional_filtered(void);
float mcpwm_get_tot_current_in(void);
float mcpwm_get_tot_current_in_filtered(void);

// Tachometer
int mcpwm_get_tachometer_value(bool reset);
int mcpwm_get_tachometer_abs_value(bool reset);
int mcpwm_set_tachometer_value(int steps);

// Hall sensor utilities
void mcpwm_init_hall_table(int8_t *table);
void mcpwm_reset_hall_detect_table(void);
int mcpwm_get_hall_detect_result(int8_t *table);
int mcpwm_read_hall_phase(void);
void mcpwm_set_detect(void);
float mcpwm_get_detect_pos(void);

// Commutation mode
void mcpwm_set_comm_mode(mc_comm_mode mode);
mc_comm_mode mcpwm_get_comm_mode(void);
void mcpwm_switch_comm_mode(mc_comm_mode next);

// Diagnostics
float mcpwm_read_reset_avg_cycle_integrator(void);
mc_rpm_dep_struct mcpwm_get_rpm_dep(void);
bool mcpwm_is_dccal_done(void);
float mcpwm_get_last_adc_isr_duration(void);
float mcpwm_get_last_inj_adc_isr_duration(void);

Detect mode

The detect mode applies test pulses to each phase to locate the hall sensor positions:
void mcpwm_set_detect(void);                        // enter detect mode
float mcpwm_get_detect_pos(void);                   // read estimated position
void mcpwm_reset_hall_detect_table(void);           // clear results
int mcpwm_get_hall_detect_result(int8_t *table);    // get detected hall table
Run the hall sensor detection from VESC Tool instead of calling these functions directly. The tool automates the process and writes the result to the configuration.