Custom DRV8301 board help - motor makes noise, doesn't spin

I made some custom PCBs using the DRV8301 chips from TI. I’m trying to use them to spin a bldc with 7 pole pairs. I’m using the AS5600 sensor and 6 PWM control. My code is just a slightly modified velocity control example:

 * Velocity motion control example
 * Steps:
 * 1) Configure the motor and magnetic sensor 
 * 2) Run the code
 * 3) Set the target velocity (in radians per second) from serial terminal
 * By using the serial terminal set the velocity value you want to motor to obtain
#include <SimpleFOC.h>

// magnetic sensor instance - SPI
//MagneticSensorSPI sensor = MagneticSensorSPI(AS5147_SPI, 10);
// magnetic sensor instance - MagneticSensorI2C
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
// magnetic sensor instance - analog output
// MagneticSensorAnalog sensor = MagneticSensorAnalog(A1, 14, 1020);

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(10, 9, 6, 5, 11, 3);
// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6,  8);

void setup() {
  // initialise magnetic sensor hardware
  // link the motor to the sensor

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // link the motor and the driver

  // set motion control loop to be used
  motor.controller = ControlType::velocity;

  // contoller configuration 
  // default parameters in defaults.h

  // velocity PI controller parameters
  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
  // default 5ms - try different values to see what is the best. 
  // the lower the less filtered
  motor.LPF_velocity.Tf = 0.01;

  // use monitoring with serial 
  // comment out if not needed

  // initialize motor
  // align sensor and start FOC

  Serial.println("Motor ready.");
  Serial.println("Set the target velocity using serial terminal:");

// velocity set point variable
float target_velocity = 0;

void loop() {
  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz 

  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the in the code

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  // motor.monitor();
  // user communication

// utility function enabling serial communication with the user to set the target values
// this function can be implemented in serialEvent function as well
void serialReceiveUserCommand() {
  // a string to hold incoming data
  static String received_chars;
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char);
    // add it to the string buffer:
    received_chars += inChar;
    // end of user input
    if (inChar == '\n') {
      // change the motor target
      target_velocity = received_chars.toFloat();
      Serial.print("Target velocity: ");
      // reset the command buffer 
      received_chars = "";

When I power the board and driver on, it makes noises, jiggles around a bit, then stops and makes weird noises again. The serial monitor shows me the following:

MOT: Monitor enabled!
MOT: Initialise variables.
MOT: Enable driver.
MOT: Align sensor.
MOT: natural_direction==CCW
MOT: Absolute zero align.
MOT: Success!
MOT: Motor ready.
Motor ready.

Set the target velocity using serial terminal:
Target velocity: 1.00

Since this is a custom board, I would expect this to be a hardware issue, however when I looked at the inputs and outputs with my scope, it seems to be fine (e. g. when INH_A is high, output A is HIGH, when INL_A is high, A is low). Any help would be greatly appreciated :slight_smile:

Hi @slasowy,
is it your motor moves, have you tried 10 rd/s, or 100 rd/s, otherwise try this:

motor.PID_velocity.P = 0.02;
motor.PID_velocity.I = 0.02;
motor.PID_velocity.D = 0;

Then increase a little bit “velocity.I” up to 0.2 in a first time, and tell me.

Hey, some ideas you could look at:

What is the resistance of the motor you’re using? A drop in voltage from 12 to 7.5V could indicate a large current draw - perhaps it isn’t the under-voltage but rather the over-current protection that is activating? If your motor’s winding resistance is low, you need to set a voltage_limit to prevent too much current being drawn.

Can you see the output of the nFault pin of the DRV8301? This should be low if the protections kick in…

Otherwise, if you leave the motor off, and just read the sensor values (print them to Serial for example), is it working correctly? Do the sensor values change as you turn the motor with your hand?

Hey @slasowy,

In your code I dont see any DRV8301 configuration?
It should have an spi interface to configure it. Are you setting it in some manner or am I missing somthing?

If you use a new version of the library (v2.1) it would give us a bit more info in the monitor so we could be able to tell you a bit more what is going on from the code perspective.

Did you check that your sensor work?
Did you check that the driver works in open-loop mode?

Hiya - yeah, be careful! I’m going to guess this motor’s winding resistance is less than 1Ω. You can check it with the resistance mode of your multimeter.

nFault is active-low… so if it gets pulled to GND it is indicating a fault state. If you’re getting GND asserted lots of the time then this could certainly be the source of your strange motor behaviour. nOCTW is also active low. The behaviour you describe could be one of the protections kicking in, and timing out or being reset?

Other motors of this type I can find that list their winding resistance list it at around 0.1Ω- which means at 2V the current would quickly rise to about 20A - can your FETs handle that?

But the DRV8301 is a fairly complex driver, and depending on how you set the different options like OC_MODE the behaviour can be different.
I would try setting the voltage limit to 0.2 or 0.1V and see if this helps.

Which MCU are you using? Which modes are set on the DRV8301, or is everything on default?

Hi @slasowy,

Because your motor works in open loop but not in closed loop mode: Check your magnet of the AS5600!

Lots of the AliExpress variants are delivered with the wrong one… I also had issues once with working open loop code and that it would not move with weird shakes in closed loop mode thanks to the wrong magnet…

Maybe it is something that you already checked, but I did not saw someone mentioning it in this chat.

Good luck with your problem!

The code looks ok to me… maybe someone else can see a mistake I’ve missed?

The magnet is also something I would have suggested, many people describing your behaviour turns out its the wrong magnet.

Other times its been incorrect number of pole-pairs - you’re sure your motor has 7?

PWM frequency can be an issue - which microcontroller are you using? Although this problem would also manifest in open-loop mode.

Do you have a higher-ohm motor you could use for testing? This would not get so hot so quickly…
Do you have access to an oscilloscope and/or logic analyser? Might be necessary in this case to get deeper into the problem.

If open-loop is working well, but closed loop is not, then that is indicative of sensor problems…

Your PID - the I value is kind of low - perhaps set them to the defaults until things are working?

Personally, I like to use closed loop velocity mode before trying position mode. I find that position mode generally works once (closed loop) velocity mode is working, and I set my target-value to some reasonable speed, say 2rad/s, as the initial value. That way, the moment the main loop starts, the motor starts to spin (or it doesn’t). That saves me a lot of time setting speeds when testing. I also don’t bother with the monitoring or serialReceiveUserCommand until things are working - its just another source of error.

Wow, that sounds very frustrating! I feel for you, we’ve all been there… sometimes a night’s sleep really helps too :expressionless:

If you were planning to open source your design or don’t mind sharing, then you could post the schematics (or link to) and the people here could take a look and see if we can spot any circuit level problems… several members of the forum have designed motor shields/ESC boards so maybe they can see something…
Intermittent failures and strange behaviour like that sounds like it could be electrical too, brownouts or similar…

If it was working in open loop before, and now isn’t, this probably means:

  • the board or setup has somehow physically changed - something became disconnected, something got damaged on the PCB, you changed the wiring and forgot to change it back, battery is empty whereas before it was full, more devices are connected, etc…
  • the software is not exactly the same as in the previous test - something got changed and didn’t get completely reversed, or there is some compilation issue or library issue, etc…

I really think to debug a PCB for motor control you almost need to have an oscilloscope to see what’s going on. Modern ones often double up as logic analysers, but if you think the problem is on the digital side, and don’t already have one, this will be the best EUR10 you invest in a long time:
Don’t be put off by their cheapness - they work fine, and together with the Open Source software “Pulseview” you can debug things like SPI, I2C, and track the state of nFAULT and nOCTP.

The reason I ask about your MCU is because looking at your code you’re using a bunch of pins and default SPI/I2C configurations. Depending on the microcontroller and board wiring there could be a conflict? If the conflict were between I2C and the commutation, for example, this would explain why it works/worked in open-loop but not in closed…

Hi @slasowy,

Very frustrating that it also stopped working open loop… I do not have suggestions for solving that…

For the closed loop part, I do have another suggestion: Did you connect the DIR port of the AS5600 to ground or VCC? Theoretically it is not necessary for SimpleFOC but from the datasheets, it is recommended to connect it. One day, my DIR cable became loose and my motor behaved the same way as yours. Also my self-balancing cart could not balance anymore this week because I did not connect the DIR port which resulted in I2C errors……

If you can share your schematic maybe someone can check if everything seems to be properly connected.

Is this on an Uno (or anything else with 8bit PWM).

0.2V voltage limit - whilst needed due to low motor widing resistance might be causing some quantization issues if your power supply is 12V. 12V/256=0.047V so your sine wave being fed to your motor only has 5 steps. The sine wave would be a bit smoother with a 8V supply, still not great though.

So you’ve tried it openloop and this works and the sensor test works too. I would try in torque/voltage mode next but be very careful how much you ask to move e.g. motor.move(0.2).

The torque/voltage mode combines motor and sensor but does not require PIDs to be tuned. I certainly wouldn’t try angle mode until velocity mode is stable as you want to tune velocity PID before moving to angle tuning. Don’t forget to tune Velocity Tf - it will need to be a little larger than the default (e.g. 0.02 or 0.2) for a noisy sensor like the AS5600. I no longer use the AS5600 - the 14bit magnetic sensors e.g. AS5047/5147/5048 and ma730 are so much better (but cost 3 times more)

Yeah, I’d recommend testing first with a gimbal motor - the lower amps make everything easy to start out with.

I would guess so. Maybe something burnt/shorted?

There is now a more powerful Arduino Nano 33 IoT which is supported, and has a small form-factor. There’s also the ESP32 (like this one) which is cheap and very powerful. The Nano itself will work, but isn’t the most powerful MCU for motor control.

I got the same problem a few days ago and it turns out the problem is the magnet is wrong. I am also using AS5600. You need use diametrically magnetized magnet, not axially magnetized ones. (For some reason axially magnetized magnet would show roughly correct sensor angle reading as well, I don’t know why).

There might be an issue in the shaft axis or the windings due to which the motor makes noise. You should also calibrate the sensors and get the drives repaired. You can also contact servo drives repair for details.

Maybe your ( and many others ) problem is just the board design.
I see in your schematic everything connected to “GND”. All “GND” points are supposed to carry the same voltage.
Unfortunately, they do not.
Every trace on the board has resistance, capacity, inductance and acts like an antenna.
In a position sensor you try to measure microvolts, while a few milimeters away high currents are switched on and off at nanosecond speeds.
Sometimes you are lucky, but often you are not.
Without equipment costing thousands, you may never know what hit you.

A common mistake is called “groud loop” where the traces or wires that are connected to ground will induce a current when there is an alternating magnetic field nearby. Since there is near zero resistance in the circuit, this current can become very large.
Another problem can be noise on a power-rail. It is the problem that makes you hear a click on your stereo everytime the refrigerator in the kitchen switches on. That is the reason half the components in your smartphone are either decoupling capacitors or filter-inductors.