Cannot achieve high torque with Hoverboard motor

I’d like some help to understand why I am seeing such a low torque output with my Hoverboard motor, in theory capable of achieving 10-15 Nm.

Hardware used: ESP32, DRV8302, Hoverboard motor, AS5048A encoder.

Tested max torque with these two setups:

  1. Using DC adjustable power supply at 24V, max current limit set to 9A. Result: Current limit reached on power supply, max torque measured: 3-4 Nm

  2. Using Hoverboard battery 36V. Result: motor.voltage_limit is reached, measured torque is a bit smaller than scenario 1, around 3 Nm

Any help/ideas to try would be appreciated!!

Below is the relevant part of my code

#include <Arduino.h>
#include <SimpleFOC.h>

// DRV8302 pins connections
// don't forget to connect the common ground pin
#define   INH_A_1 14
#define   INH_B_1 12
#define   INH_C_1 13
#define   EN_GATE_1 27

#define   M_PWM 32 
#define   M_OC 25
#define   OC_ADJ 26
#define   OC_GAIN 33

#define IOUTA 36
#define IOUTB 39
#define IOUTC 34
// Define the SPI pins for VSPI
#define CS_PIN_ENCODER 5

// motor instance
BLDCMotor motor = BLDCMotor(15);
// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A_1, INH_B_1, INH_C_1, EN_GATE_1);
// DRV8302 board has 0.005Ohm shunt resistors and the gain of 12.22 V/V
LowsideCurrentSense currentSense = LowsideCurrentSense(0.005f, 12.22f, IOUTA, IOUTB, IOUTC);

// Create sensor objects
MagneticSensorSPI sensor = MagneticSensorSPI(CS_PIN_ENCODER, 14, 0x3FFF);

float target;
float step = 0.2; // angle step
const float span = 3.14/4; // allowed rotation in each direction 
float uBound, lBound;
float maxv = 0, maxi = 0; // max voltage and current Q
bool motorEnable = true;
long ts, ts2;

// commander interface
Commander command = Commander(Serial);
void doTarget(char* cmd){ command.motor(&motor, cmd); }

void setup() {
  ts = millis();
  ts2 = millis();


  // initialise magnetic sensor hardware
  Serial.println("Sensor Ready");

  // DRV8302 specific code
  // M_OC  - enable over-current protection
  // M_PWM  - enable 3pwm mode
  // OD_ADJ - set the maximum over-current limit possible
  // Better option would be to use voltage divisor to set exact value
  Serial.println("Driver config");

  // configure driver
  driver.voltage_power_supply = 36;
  driver.voltage_limit = driver.voltage_power_supply;
  driver.pwm_frequency = 15000;
  Serial.println("Driver init");

  // link current sense and the driver
  currentSense.skip_align = true;
  // link the current sense to the motor
  // driver 8302 has inverted gains on all channels
  currentSense.gain_a *=-1;
  currentSense.gain_b *=-1;
  currentSense.gain_c *=-1;

  // limiting motor movements
  motor.voltage_limit = 24;   // [V]
  motor.velocity_limit = 20;
  motor.voltage_sensor_align = 4;
  motor.velocity_index_search = 3; 

  // set control loop type to be used
  motor.controller = MotionControlType::angle;

  // velocity PI controller parameters
  motor.PID_velocity.P = 1.0;
  motor.PID_velocity.I = 15.0;
  motor.LPF_velocity.Tf = 0.02; // velocity low pass filtering time constant
  // jerk control using voltage voltage ramp
  // default value is 300 volts per sec  ~ 0.3V per millisecond
  motor.PID_velocity.output_ramp = 1000;

  // position P controller parameters
  motor.P_angle.P = 1.0;
  motor.P_angle.I = 0.0;
  motor.P_angle.D = 0.0;
  // use monitoring with serial for motor init
  // monitoring port
  // comment out if not needed

  motor.sensor_direction = Direction::CCW;
  motor.zero_electric_angle = 1.88;

  // initialize motor
  target = sensor.getAngle(); // set target
  uBound = target + span;
  lBound = target - span;
  // downsampling
  motor.motion_downsample = 10;
  motor.monitor_downsample = 10; // default 10
  // define the motor id
  char motor_id = 'M';
  command.add(motor_id, doTarget, "motor");
  // configuring the monitoring to be well parsed by the webcontroller
  //motor.monitor_start_char = motor_id; // the same latter as the motor id in the commander 
  //motor.monitor_end_char = motor_id; // the same latter as the motor id in the commander 
  //command.verbose = VerboseMode::machine_readable; // can be set using the webcontroller - optional
  Serial.println("Setup DONE");

void loop() {


Be careful hoverboard batteries can be very bad.
Voltage could be dropping as current consumption increases.


Could you please explain the theory of calculating the max torque for that motor?


Here they have a measurement of 13nm

But it’s the best variant

Without having the exact motor specifications it would be very hard to put a number.

Hoverboard motors are vastly different, number/type of magnets, poles, resistance, and wire wind count.


Yes that’s for the best motors.

Also this. Seems unlikely they would differ by this much as to get such a low torque

How much is the weight of your motors?

I probably opened more than a 30 pairs of hoverboard motors.
Unfortunately I haven’t done any measurement

According to the table specs, at 36V / 8A you will get 4 Nm @ 288W.

You get between 3 to 4 Nm when running at 24V / 9A which is 216W, or 75% of 288W, and you get between 3 and 4Nm, which is even better than the theoretical value (you should get exactly 3Nm).

I don’t see a problem here.


Would you suggest I set motor voltage limit to 36V when using the 36V hoverboard battery then?
Thanks for the help

That’s interesting, I’ll have to measure it when I get back home. Thanks for the help

Isn’t this the way it’s supposed to work? Why would you limit the motor to 24V if you battery is 36V?

Also you must have really good cooling. Hoverboard motors don’t cool at all. Please experiment safely and responsibly.


PS you may want to move this to Discord. It’s becoming a chat exchange.

My understanding was that the motor voltage limit should be a fraction of the driver voltage. I could be wrong though, I’m new to FOC

I think you are not using svpwm?

Check this also

That’s also my understanding. But it’s meant to be exactly? 50% of the battery voltage AFAIK. The reason was something about centered zero in your case +/-18V