BDC Driver

The BdcDriver component wraps the ESP MCPWM Peripheral to provide dual-PWM control for brushed DC motors and H-bridge style drivers.

It supports direct duty-cycle control of the two motor outputs as well as a signed speed helper that maps positive commands to output A and negative commands to output B.

API Reference

Header File

Classes

class BdcDriver : public espp::BaseComponent

Driver for brushed DC motors controlled by two PWM outputs.

The component uses one MCPWM operator per motor channel and is intended for H-bridge style drivers that accept two PWM inputs. Positive signed speed commands drive output A, negative commands drive output B, and zero disables both outputs.

Example

  constexpr gpio_num_t motor_gpio_a = GPIO_NUM_16;
  constexpr gpio_num_t motor_gpio_b = GPIO_NUM_17;

  espp::BdcDriver driver({
      .gpio_a = motor_gpio_a,
      .gpio_b = motor_gpio_b,
      .group_id = 0,
      .log_level = espp::Logger::Verbosity::INFO,
  });

  if (!driver.initialized()) {
    logger.error("Failed to initialize BDC driver");
    return;
  }

  float phase = 0.0f;
  while (true) {
    float command = 0.8f * std::sin(phase);
    driver.set_speed(command);
    auto duty = driver.duty_cycle();
    auto raw = driver.raw_duty();
    logger.info("cmd={:.3f} | pwm_a duty={:.1f}% raw={}/{} | pwm_b duty={:.1f}% raw={}/{}", command,
                duty[0] * 100.0f, raw[0], driver.max_raw_duty(), duty[1] * 100.0f, raw[1],
                driver.max_raw_duty());
    phase = std::fmod(phase + 0.15f, 2.0f * std::numbers::pi_v<float>);
    vTaskDelay(pdMS_TO_TICKS(500));
  }

Public Functions

explicit BdcDriver(const Config &config)

Construct the brushed DC motor driver.

Parameters:

config – Driver configuration.

~BdcDriver()

Destroy the driver and release all MCPWM resources.

bool initialized() const

Check whether initialization completed successfully.

Returns:

True if the MCPWM resources were created and the outputs were initialized; false otherwise.

bool enable()

Enable the motor driver output.

Returns:

True if the timer started successfully and the optional enable pin was asserted; false otherwise.

bool disable()

Disable the motor driver output.

Returns:

True if the outputs were forced low and the timer was stopped; false otherwise.

bool is_enabled() const

Check whether the driver is currently enabled.

Returns:

True if the timer is running; false otherwise.

bool set_duty(float duty_a, float duty_b)

Set the normalized duty cycles for the two driver outputs.

Parameters:
  • duty_a – Duty cycle for output A in the range [0.0, 1.0].

  • duty_b – Duty cycle for output B in the range [0.0, 1.0].

Returns:

True if both outputs were updated successfully; false otherwise.

bool set_speed(float speed)

Set a signed normalized motor command.

Parameters:

speed – Signed speed command in the range [-1.0, 1.0]. Positive values drive output A, negative values drive output B, and zero disables both outputs.

Returns:

True if the outputs were updated successfully; false otherwise.

bool stop()

Stop the motor by disabling both PWM outputs.

Returns:

True if both outputs were set low; false otherwise.

std::array<float, 2> duty_cycle() const

Get the last commanded normalized duty cycles.

Returns:

Array containing output A then output B duty cycles in the range [0.0, 1.0].

std::array<uint32_t, 2> raw_duty() const

Get the last commanded raw duty counts.

Returns:

Array containing output A then output B raw compare values.

uint32_t max_raw_duty() const

Get the maximum raw duty count for this driver’s timer configuration.

Returns:

Maximum raw duty count corresponding to 100% duty.

size_t pwm_frequency_hz() const

Get the configured PWM carrier frequency.

Returns:

PWM carrier frequency in Hz.

size_t timer_resolution_hz() const

Get the configured timer resolution.

Returns:

MCPWM timer resolution in Hz.

int group_id() const

Get the configured MCPWM group.

Returns:

MCPWM group index used by this driver.

gpio_num_t gpio_a() const

Get output A’s GPIO.

Returns:

Output A GPIO.

gpio_num_t gpio_b() const

Get output B’s GPIO.

Returns:

Output B GPIO.

inline const std::string &get_name() const

Get the name of the component

Note

This is the tag of the logger

Returns:

A const reference to the name of the component

inline void set_log_tag(const std::string_view &tag)

Set the tag for the logger

Parameters:

tag – The tag to use for the logger

inline espp::Logger::Verbosity get_log_level() const

Get the log level for the logger

Returns:

The verbosity level of the logger

inline void set_log_level(espp::Logger::Verbosity level)

Set the log level for the logger

Parameters:

level – The verbosity level to use for the logger

inline void set_log_verbosity(espp::Logger::Verbosity level)

Set the log verbosity for the logger

See also

set_log_level

Note

This is a convenience method that calls set_log_level

Parameters:

level – The verbosity level to use for the logger

inline espp::Logger::Verbosity get_log_verbosity() const

Get the log verbosity for the logger

See also

get_log_level

Note

This is a convenience method that calls get_log_level

Returns:

The verbosity level of the logger

inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)

Set the rate limit for the logger

Note

Only calls to the logger that have _rate_limit suffix will be rate limited

Parameters:

rate_limit – The rate limit to use for the logger

Public Static Attributes

static constexpr size_t DEFAULT_TIMER_RESOLUTION_HZ = 80 * 1000 * 1000

Default MCPWM timer resolution used by the driver.

static constexpr size_t DEFAULT_PWM_FREQUENCY_HZ = 20 * 1000

Default PWM carrier frequency used by the driver.

struct Config

Configuration for one brushed DC motor driver.

Public Members

gpio_num_t gpio_a = {GPIO_NUM_NC}

PWM GPIO for forward/output A.

gpio_num_t gpio_b = {GPIO_NUM_NC}

PWM GPIO for reverse/output B.

gpio_num_t gpio_enable = {GPIO_NUM_NC}

Optional active-high enable pin.

int group_id = {0}

MCPWM group to allocate the timer and operator from.

size_t timer_resolution_hz = {DEFAULT_TIMER_RESOLUTION_HZ}

MCPWM timer clock resolution in Hz.

size_t pwm_frequency_hz = {DEFAULT_PWM_FREQUENCY_HZ}

PWM carrier frequency in Hz.

bool invert_output_a = {false}

True to invert output A at the GPIO matrix.

bool invert_output_b = {false}

True to invert output B at the GPIO matrix.

Logger::Verbosity log_level = {Logger::Verbosity::WARN}

Component log verbosity.