Hoverboard motor vibrates but doesn't rotate

#include <SimpleFOC.h>
// software interrupt library
#include <PciManager.h>
#include <PciListenerImp.h>
// DRV8302 pins connections
#define INH_A 9
#define INH_B 10
#define INH_C 11
#define EN_GATE 8
#define M_PWM 6
#define M_OC 5
#define OC_ADJ 7

// set up pins on arduino board
#define HallA 2 // yellow
#define HallB 3 // blue
#define HallC 4// green

// polar pairs
int pp = 15; // motor has 30 outer magnets
// motor instance
BLDCMotor motor = BLDCMotor(pp);

// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);

// hall sensor instance
HallSensor sensor = HallSensor(HallA, HallB, HallC, pp);
// Interrupt routine intialisation
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
// If no available hadware interrupt pins use the software interrupt
PciListenerImp listenC(sensor.pinC, doC);

// velocity set point variable
float target_velocity = 0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }

void setup() {
// initialize Hall sensor hardware
//sensor.pullup = Pullup::USE_EXTERN;
//sensor.velocity_max = 30;
// initialize sensor sensor hardware
sensor.init();
sensor.enableInterrupts(doA, doB); //, doC);
// software interrupts
PciManager.registerListener(&listenC);

// link the motor to the sensor
motor.linkSensor(&sensor);

// DRV8302 specific code
// M_OC - enable over-current protection
pinMode(M_OC,OUTPUT);
digitalWrite(M_OC,LOW);
// M_PWM - enable 3pwm mode
pinMode(M_PWM,OUTPUT);
digitalWrite(M_PWM,HIGH);
// OD_ADJ - set the maximum over-current limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
//driver.pwm_frequency = 32000;

// configure driver
driver.voltage_power_supply = 36;
driver.init();
motor.linkDriver(&driver);

//motor.velocity_limit = 1; // [rad/s] cca 50rpm

// aligning voltage [V]
motor.voltage_sensor_align = 3;

// choose FOC modulation
//motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

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

// controller configuration based on the control type
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 0;
// default voltage_power_supply
motor.voltage_limit = 12;

// jerk control using voltage voltage ramp
// default value is 300 volts per sec ~ 0.3V per millisecond
motor.PID_velocity.output_ramp = 1000;

// velocity low pass filtering time constant
motor.LPF_velocity.Tf = 0.01f;
// angle loop velocity limit
// angle loop controller
//motor.P_angle.P = 20;

//motor.velocity_limit = 50;
// use monitoring with serial
// default voltage_power_supply
//motor.voltage_limit = 36;
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);
//motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE;
// downsampling
//motor.monitor_downsample = 10; // default 10
// initialize motor
motor.init();
// align encoder and start FOC
motor.initFOC();

// set the initial target value
//motor.target = 2;

// define the motor id
command.add(‘T’, doTarget, “target velocity”);
Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target velocity using serial terminal:”));
_delay(1000);
}

void loop() {
// iterative setting FOC phase voltage
//sensor.min_elapsed_time = 0.0001; // 0.0001 by default
// update the sensor values
// sensor.update();
motor.loopFOC();

// iterative function setting the outer loop target
// velocity, position or voltage
// if target not set in parameter uses motor.target variable
motor.move(target_velocity);
// user communication
command.run();
}

Hi,
During sensor.init it should move back and forth a few degrees. If it doesn’t move the sensor.init fails.
Did you try to use the /utils/sensor-test.ino first?
Also test the motor with openloop_velocity.ino before you combine both.
It might not want to spin with only 3V target on a 12V system.

Thank you, I have checked and the sensor alignment process is quite ok but when I set the speed the motor only vibrates but it does not rotate.

Try to reduce the PID values alot, especially “I” is much too high for low resistance hoverboard motors.
These are my values for a splitboard hoverboard controller. Use it as ballpark numbers, it depends on your MCU-performance, driver voltage a.s.o.

 // velocity low pass filtering time constant
  motor.PID_velocity.P  = 0.3f;
  motor.PID_velocity.I  = 0.3f;
  motor.LPF_velocity.Tf = 0.04f; 
1 Like

I tried it but the motor just vibrates and doesn’t rotate. I also changed the PID with small P and I, D = 0 but the result is the same

Does open loop work at all?

Yes, but when I put the hall sensor in, the wheel does not rotate, the motor only vibrates when I set the speed taget but the wheel does not rotate.

You have to match the hall sensor pins with the right motor pins.
Usually the phase colors and hall-sensor colors match ( yellow, blue, green)

I plugged hall into arduino mega2560, hallsensor A, B, pin 21,20. hallsensorB is plugged into pin 4 and I use an interrupt

Is the sensor working normally without closed-loop mode?

i.e. could you try with the HallSensor, but leaving the motor disabled (motor.disable()) and rotate the motor by hand while printing the angles in the main loop.
We have a sensor test ino in our examples that you can use.

If you do this, do you get ±6.28 radians from the sensor per full revolution of the motor?

I have tried it and the result is like that

When I send the speed the motor vibrates very loudly but the wheel does not rotate. Is it because the PID parameters are not correct?

It’s possible that PID parameters are the cause, but usually, unless they are way off, you get some movement.

Non-movement and loud noise is sometimes caused by setting the number of pole-pairs incorrectly, or due to bad commutation signals. But if open loop is working well then it’s probably not the commutation.

Can you try to use open-loop mode, maybe in open-loop position mode, and command the motor to turn itself?
In the main loop, call sensor.update() and print the angle from the sensor (but only 1-2 times per second or you will overload the serial port). This is to see if the sensor agrees with the open loop position.

yes, I see it rotates once and the angle is about 6rad. quite okay

Can you rephrase the title of the thread lol

Sorry, I just want to make the content clearer

Honestly, if all these things are working, and it also works in torque-voltage mode, then it might well be the PID that needs tuning…

Does torque voltage mode work?

You enable only 2 interrupts?

They one have 2 spare pins left for interrupt, so they used one with software int.

I tried changing the PID parameters many times without success. Or maybe it’s not right?