Back to engineering archive

Record 069 / Firmware and control

ESP32 motor and power stage controller

ESP32 firmware converts throttle and brake inputs into a ramped PWM command shared by two motor-control outputs.

Firmware development
ESP32ADC inputsPWMMotor control

Firmware flow

Ramp a PWM command from throttle and brake inputs

Selected ESP32 control fragment; input scaling and elapsed-time calculation occur earlier in the loop.

Braking takes priority over throttle tracking. Without a brake request, the command rises or falls toward the target. A deadzone then removes very small commands before the same integer duty is written to both outputs.

This is open-loop PWM command generation. It does not establish speed regulation, physical braking, driver compatibility or tested motor operation.

Read the implementation

code2.txt — throttle/brake-dependent duty ramp and two PWM outputs.

  // 4) update currentPWM with smooth accel/decel
  if (brRatio > 0.01f) {
    float decel = BASE_DECEL + brRatio * (MAX_DECEL - BASE_DECEL);
    currentPWM = max(0.0f, currentPWM - decel * dt);
  }
  else if (currentPWM < targetPWMf) {
    currentPWM = min(currentPWM + ACCEL_RATE * dt, targetPWMf);
  }
  else {
    currentPWM = max(currentPWM - BASE_DECEL * dt, targetPWMf);
  }

  // 5) deadzone
  if (currentPWM < DEADZONE) currentPWM = 0.0f;

  // 6) output to both drivers
  uint32_t duty = uint32_t(currentPWM);
  ledcWrite(MOTOR_A_PWM_PIN, duty);
  ledcWrite(MOTOR_B_PWM_PIN, duty);
ActionReduce duty using the brake-dependent rate
ActionRamp upward, capped at the target
ActionCoast downward, bounded by the target
ResultConvert to integer duty and write both outputs

Technical notes

Inputs become a target

The sketch constrains the throttle reading to configured ADC bounds and maps it to a PWM target. A second analog input is normalized to a brake ratio. These bounds are configuration values, not a demonstrated calibration.

Three command paths

A brake input above the threshold reduces the current command at a brake-dependent rate. Otherwise the code ramps upward toward the throttle target or coasts downward toward it, using elapsed time from micros().

One command, two outputs

After a small-command deadzone, the duty is converted to an integer and written to both PWM outputs. This excerpt establishes requested duty only: it contains no measured motor-speed feedback, direction output or separate stop/brake control signal, and hardware operation was not tested.

Engineering archiveArchive record

Project enquiries

Discuss your project.

Tell us what you’re developing and where you need engineering support.

Discuss your project