BTS7960 Mtor Direction Problem


I am trying to use Hoverboard motor for FFB wheel. I found cheap 2 x Bts7960 with Esp32. My encoder is AS5047P in SPI mode. When I run the code bellow, motor spins left (as expected) with no problem. But as the nature of ffb wheel, when I apply force to reverse direction, motor starts to rotate reverse direction. As you can see, I am only giving torque in one direction.

Any suggestions?

#include <SimpleFOC.h>

const uint8_t  P1_L_EN                      = 27;
const uint8_t  P2_R_EN                      = 13;
const uint8_t  P3_L_EN                     = 22;

const uint8_t  P1_L_PWM                     = 25;
const uint8_t  P2_R_PWM                     = 26;
const uint8_t  P3_L_PWM                     = 21;

// const uint8_t  P_MOSI                     = 23;
// const uint8_t  P_MISO                     = 19;
// const uint8_t  P_CLK                     = 18;
const uint8_t  P_CS                     = 5;

//  BLDCMotor( pole_pairs )
BLDCMotor motor = BLDCMotor(15);
//  BLDCDriver( pin_pwmA, pin_pwmB, pin_pwmC, enable (optional) )
BLDCDriver3PWM driver = BLDCDriver3PWM(P1_L_PWM, P2_R_PWM, P3_L_PWM, P1_L_EN, P2_R_EN, P3_L_EN);

MagneticSensorSPI encoder = MagneticSensorSPI(AS5047_SPI, P_CS);

void setup() {  

  // initialize encoder hardware
  // link the motor to the sensor
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.pwm_frequency = 5000;
  // initialise driver hardware
  // link driver
  motor.torque_controller = TorqueControlType::voltage;
  // set motion control loop to be used
  motor.controller = MotionControlType::torque;

  motor.voltage_limit = 12;
  motor.current_limit = 10;
  //motor.voltage_sensor_align = 1;

  // motor phase resistance [Ohms]
  motor.phase_resistance = 0.11; // Ohms - default not set
  // motor KV rating [rpm/V]
  motor.KV_rating = 16; // rpm/volt - default not set
  motor.velocity_limit = 20;
  // initialize motor
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0.001;
  // jerk control using voltage voltage ramp
  // default value is 300 volts per sec  ~ 0.3V per millisecond
  motor.PID_velocity.output_ramp = 1000;
  // align encoder and start FOC
void loop()


I do not understand the problem. Could you please provide more details and may be a video of the setup?


Hi Valentine,

This is the link of video.

I want to ratate motor only one direction. If I do not apply force to reverse direction, it spins to single direction, this is ok. But if I apply reverse force to motor, motor starts spining to reverse direction.

I watched the video. Where is the magnetic sensor attached? Those motors have hall sensors. Please show a picture or video of the AS5047P magnetic sensor position and mounting on the motor.


I need to think a little. How is the BTN setup looking, where did you connect the wires on the BTN? Picture please?

May be @runger could provide some comments, too.



It’s not the first time people have reported problems like this, and the causes were different, and I think in some cases it’s not fully clear yet what caused it.

Some pointers:

  1. having a correctly diametrically magnetized magnet, mounted in the right position and distance from the sensor chip is critical. Many users experience strange behavior like this when they use the wrong magnet. If you have an official AMS test board it will come with a good magnet, but if you ordered from AliExpress or similar sites, the magnet provided can be the wrong kind.

  2. I see your magnet is not actually mounted directly on the motor shaft. Having any kind of slip, play or backlash will be a problem, the motor shaft position has to be accurately determined to under 1deg.

  3. I assume the gear ratio of the two gears is exactly 1:1?

  4. Electrical spikes - stalling the motor causes currents to rise sharply, and may cause electrical interference in the sensor data lines. You can check for sudden step changes in the sensor value, or use an oscilloscope to check the lines, or add code to check the parity bit returned by the sensor (we currently don’t check it) to mitigate this problem, but the best is if you can separate and isolate the sensor lines from the motor lines so the problem doesn’t happen at all

He is using plastic herringbone gear, so slip is not the problem. Actually I really like what he’s done, that’s the first time I see anyone sensoring a hoverboard motor like that.

I 'd probably put my money on the bad magnet at that point.

Hi, thanks for your responses.

  1. Before simplefoc test, I attached encoder to arduino with spi to test angles, errors, magnetic field strenght, magnet distance . There is no error, angle readings are accurate. Magnetic field & distance is seems optimum. Magnet is fron Ali but specialy selected for diametricaly magnetized. I think if there was an error, I could see that while testing. But I will check again.

  2. magnet and encoder parts printed using very accurate 3d printer. Also herringbone gears are almost backlash free. And I used bearing in rotating shaft so very little friction. Parts are very solid and no play on x or y axis.

  3. yes, 1:1 gear ratio for z index
    4)maybe this one… I will try to write custom code to check error from encoder as you said.

1 Like

I love the idea of how you mounted the encoder.
I would encourage you to share the design files so I can use them for this :smiley:


Agree, that’s some fine work there. Even though this is out of topic, my input would be, the herringbone is designed to work in an extremely clean environment. Having such fine pitch in a dirty environment as a human house where you got hair and dust is creating a serious problem. A much better solution would be to use a rubber belt with two pulleys and use a tensioner to clear any slack. A rubber belt is a lot more debris resistant.

1 Like

Hey guys,

I think the issue here is the KV rating and the phase resistance values of the motor.
Basically the current (torque) is estimated based on the equation:

Current = (voltage_q - velocity/KV_rating)/phase_resistance 

If your KV_rating is a bit low then the voltage_bemf = velovity/KV_rating will overestimate the true back emf voltage generated by the motor and to keep the current set to 0 the torque control will need to set a higher value of voltage_q.

The rule of thumb in the docs is to use 20% to 70% higher value of the KV rating than the one provided by the manufacturer of the motor or found by the library KV rating finding example code.
for the easiest way to find the KV value, I’d suggest you to play with this value using the commander interface and find minimal KV rating for which your motor doesn’t run anyway.

Hello. I am also doing such a project. And I used two options for installing the sensor. The first is simple, the second is more complicated