SimpleFOCMini's Problem with High-Speed 24V BLDC Motor

Hello,

We are trying to run full_control_serial example from SimpleFOC 2.2.3 on our set-up (more down below).

When voltage_power_supply is 12V, the code runs without any errors and the motor speed gets max around 32 rad/s.

However, when we increase the voltage to 24V and set motor.target to 45, “No current sense” raises, and the motor spins then stops. If the motor.target is 5, “No current sense” still shows up, but the motor still spins.

Also, in all the cases, the motor is not operating smoothly but it keeps turning on and off. We also tried some different library version and get similar error.

Please help us find out what is happening here and how can we increase the motor speed. Thank you!

Devices:

  • MCU: Arduino UNO R3
  • Motor Driver: SimpleFOCMini v1.0 Fabrication ordered from JLCPCB
  • BLDC Motor: BL17E19-01
  • Encoder: E5 US Digital
1 Like

“it keeps turning on and off” sounds like a current problem. The best way to check this is if the voltage collapses. Then the power supply is not powerful enough…
(Maybe also share photos)

Regards,
Laurenz

1 Like

@Tri_Nguyen

Welcome to the forum.

The short answer: you cannot. You are triggering the driver overcurrent / overvoltage / overtemperature protection. Lower the voltage, and lower the RPMs to where you do not trigger the errors, and the motor still spins. Also, please read very carefully TI’s DRV8313 documentation to understand how the driver works and read the error pin.

This is a very small low power driver. You probably need a much bigger driver.

Cheers,
Valentine

1 Like

But this motor runs on the same voltage as the examples on the SimpleFOC website. So why does that motor work and not this one? The max RPM of the specified motor is 5000 RPM but it is only running at ~300 RPM.

This is the exact example we’re trying to replicate with the motor specified in the original post. The only difference is the motor+encoder combination. We tested the encoder and it works. The motor makes a humming noise periodically. Like it vibrates too much then smooth, then vibrates then again smooth.

@Laurenz_Kaml there is no power supply problem. I am using the same power supply in many other BLDC motor control applications and it works fine. Used it with nucleo f401re/g431rb+ihm07m1/ihm16m1, and arduino+esc - all work perfectly.

Like I said, even the basic examples don’t work well.
I have used a 12V Infineon shield before for a 24V motor, but it still ran at approximately half speed.

I checked the DRV8313 spec sheet: https://www.ti.com/lit/ds/symlink/drv8313.pdf?ts=1650461862269&ref_url=https%3A%2F%2Fwww.google.com%2F

However, there isn’t anything here that says our motor is incompatible. In fact, the example design specs mentioned for BLDC applications are quite similar to the specs of our motor. Also, it mentions that it fully supports 24V motors.

Any comments would be really helpful. This is my first time working with SimpleFOC mini and the library itself so I would really appreciate some guidance.

Our BLDC motor is only a 30W motor with 1.6A nominal current at 24V. Max speed: 5000RPM.

Thank you
Anirudh

You are clearly triggering the internal driver protection. Why is that? This is something to do with the combination of motor and the way you are driving it.

The best way to handle this, what are the values on the nFTL pin? This will tell you if the driver enters into protection mode. Protection mode is triggered also by overtemperature, so it may be overheating.

You need to monitor the nFLT in real time to understand what’s going on. Once you confirm it’s the driver protection you need to slowly eliminate all causes one by one.

What is the motor KV rating and resistance? Can you measure the current from the driver into the phases and from the power supply into the driver?

Cheers,
Valentine

P.S.

I just checked the motor. The rated peak current is 3.34A and the resistance is 1.34 O so you are clearly tripping the driver. Also the UNO doesn’t have enough processing power.

Lower the voltage and the current and you will be OK. Also put a heat-sink on the driver. This motor requires a driver that can deliver at least 3A continuous and 5A peak current. If I were you I’d probably double it and go for 6A continuous and 10A peak. DRV8313 is way too small for this motor.

Also, you need a lot faster MCU to drive it at high speed. The UNO is way too small.

Next time you do this, please consider the motor peak rated current and get a driver that can deliver 2x peak current as continuous current. For example, your BL17E19-01 motor peak current is 3.34A, then x 2 = 6.68A, so you need a driver that can deliver between 6A and 7A continuous current. Driver peak current is different from motor peak current for time purposes. Driver peak current is measured in milli to microseconds. Motor peak current is measured in seconds. That’s between 1000 and 1000000 times more and enough to burn the driver.

Last but not the least, solder a very large bulk capacitance to the driver immediately next to the input leads. Beware of polarity don’t blow up the capacitor.

Hello @Valentine

Thank you so much for your comments.

I will check the nFTL pin for protection mode. I believe the reason could be overheating so applying a heat sink might be a good idea. I will also try using nucleo (stm32duino library) with the SimpleFOC mini to see if that helps.

However, I don’t understand where you get the rated current of 3.34A. As per the datasheet, the rated current is 1.67A. I have used the same motor with Nucleo F401RE+IHM16M1 and Arduino+Cheap ESC, and never have I seen a current draw more than 1A even at a top speed of 5000RPM.

Is there something I am missing?

Regards
Anirudh

P.S. Here are the motor specs.

Also, the KV rating from my understanding is 5000 RPM / 24V = ~208

Edit: I also have a power distribution board which I am using. It has 35V 470uF capacitor across the driver terminals. Also, there is a 100V 470uF capacitor across the power source.

The max current, not the rated current. Rated current is the motor just spinning with some light load. Max current is when the motor is fully loaded.

That’s interesting, but the input current draw is different from the phase current which also includes BEMF so unless you measure directly inline phase current you are stuck.

Definitely get a heatsink, and check the fault pin and see what’s going on. Easiest way, attach in series a 5k resistor and a small 3V LED from nFLT to GND, if the LED starts blinking, your driver is playing possum.

Also attach a large bulk capacitor, I mean, very large, right next to the input.

And definitely switch to Nucleo.

Cheers,
Valentine

@Valentine

Great! Thank you. I am going to try out your suggestions and get back to you soon. Will let you know.

Thanks
Anirudh

1 Like

Hello @Valentine

Thank you so much for your suggestion. I was able to make it work.

I don’t understand it yet, but we swapped Arduino for Nucleo and apparently the SimpleFOC mini is not hot (infact it is quite cool). And also we can reach up to ~220 rad/s. If you could explain this, that would be really helpful for me to understand how it works.

Now the only issue is that we’re operating at 12V now. When we try 24V, the speed still goes only up to 220 rad/s. I think this might be a setting inside the SimpleFOC library because the driver isn’t that hot. I checked the temperature using a probe and it only goes up to 60-70 C which is much lower than the specified limits in the datasheet. Also, I put up heatsinks on both sides with a small fan to take care of unexpected temp spikes. If you do have any suggestions, that would be appreciated.

Again, thank you so much for your guidance and help. This speed is enough for my project but I still do want to exploit the full capabilities of the driver.

P.S: I was using Nucleo G431RB. Also, I will check the phase currents once. I will attach a photo soon of my setup. Also, I am operating in Closed Loop Velocity control mode.

There is one other issue. While using Nucleo using stm32duino repo, I am unable to send commands to SimpleFOC using the serial window. The library uses the Commander function for that but it never responds to any commands I write in the serial monitor. Am I missing something here?

Regards
Anirudh

The arduino has very low loop frequency so you may have been running up against some serious performance issues.

I’m not sure why do you expect the speed to increase when you increase the voltage? The speed is determined by the control loop, not the voltage. Higher voltage will help you deliver more power but not more speed. If you want more speed, as they say, get a bigger horse (I mean go for a much higher end MCU such as one of the H7 Nucleos). Also increase the PWM to may be 30000? You can even try 50000. The DRV8313 can go up to 250000. Anything higher than 50000 however you need to deal with skin effects and it gets very hairy.

Any time. Glad it worked out.

Please attach cool pictures and videos, we are always eager to learn from other’s setups.

Depends on which pins you are using for serial. It should be a very straightforward affair to talk to Nucleo. If you post your code here we may be able to give you some hints. Which development environment are you using?

Cheers,
Valenitne

I believe this could be the issue. I think the mistimed loops were causing current spikes when there was a lack of control. I also read that Arduino isn’t good with high CPR encoders. So that might be affecting the closed-loop control response leading to a heated board.

Actually, I had an Infineon shield some time ago that responded like that. But I think it could be because of low current limit. I didn’t think much then and let it go. Now it makes sense what you’re saying since I have spent more than a month working on BLDC motor control. Thank you for the information.

I was actually thinking of this and will try it tomorrow. Will let you know if that works.

Will do. Please allow me some time.

I have the Nucleo connected to my PC using a USB cable. G431RB comes with a micro-USB connector. I am coding within Arduino IDE. Thought about moving to PlatformIO but didn’t do that yet.

Here is the code:


#include <SimpleFOC.h>

// init BLDC motor
BLDCMotor motor = BLDCMotor( 3 );
// init driver
BLDCDriver3PWM driver = BLDCDriver3PWM(13, 12, 11, 10);
//  init encoder
Encoder encoder = Encoder(2, 3, 1000);

// Interrupt routine intialisation
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
void doIndex(){encoder.handleIndex();}

// velocity set point variable
float target_velocity = 200;

void setup() {

  // initialize encoder sensor hardware
  encoder.init();
  encoder.enableInterrupts(doA, doB, doIndex);

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

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 24;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // aligning voltage [V]
  motor.voltage_sensor_align = 3;
  // index search velocity [rad/s]
  motor.velocity_index_search = 3;

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

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

  // velocity PI controller parameters
  motor.PID_velocity.P = 0.2f;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0.1;
  // default voltage_power_supply
  motor.voltage_limit = 24;
  // jerk control using voltage voltage ramp
  motor.PID_velocity.output_ramp = 100;

  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.05f;

  // use monitoring with serial
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);

  // initialize motor
  motor.init();
  // align sensor and start FOC
  motor.initFOC();

  // add target command T
  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() {
  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz
  motor.loopFOC();

  // 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 motor.target in the code
  
  motor.move(target_velocity);

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

  // user communication
  command.run();
}

Source: Example “Simple FOC > motion_control > velocity_motion_control > encoder > velocity_control”
SimpleFOC library version: 2.2.3

Hi guys,

I’m happy to see that you’ve found your solution @anirudhchhabra96 :smiley:
At least partially.
Arduino loop time is greatly impacted by the interrupt routine needed to handle the encoder. The rule of thumb that I’ve found so far is not to exceed 20000 interrupts per second, which in your case would be around 20000/1000x4= 50rad/s.
After 20000 Arduino loop drops the performance a lot and it draws much more current as it takes too much time to compute.

So powerful nucleo board will be able to solve this issue as it will have loop times that are lower and having better interrupt handling. What you can try as well is using the hardware interrupt based stm32 encoder class from the driver’s library. That one is not based on interrupts but the internal counters of the stm32 chips and it should reduce the loop times even more.

Now in terms of 24V vs 12V power supply for your motor. Having the higher power supply and voltage limit should result in higher velocity reached. Not maybe twice as much, but certainly more.

As the velocity of the motor is directy determined by the voltage applied, the phase resistance of the motor and the back-emf constant

velocity  = (voltage_applied - motor_current*phase_resistance)/bemf_constant 

Are you reaching exactly the same velocity for 12 and 24V?
It might be the issue of interrupts as well, even though I doubt it, but if so you should be able to avoid this problem by using the hardware based encoder from the drivers repo.

Valentine has also pointed out one problem that can be causing it, it’s the pwm frequency maybe its too low, wo you can try raising it.

I’m really not sure what is the issue here, but in my opinion you should have considerably higher velocities with 24V than with 12V, if not there is something limiting the performance.

1 Like

The problem is the wrong encoder installation. More precisely, its axis does not coincide with the axis of the motor. Therefore, its rotation varies depending on the position of the rotor. Try to run in open loop

On this point, have you tried using Serial2 ? IIRC the USB serial on the nucleo boards is routed to Serial2 on the MCU via the onboard ST-Link…

1 Like

Oh, I didn’t know about this. Let me try that. I will look into the documentation for this. Thank you so much! :slight_smile:

@Antun_Skuric
I am taking your comments into consideration. I couldn’t work much today due to other work, but I will try them out soon and let you know what happens. Thank you for the information.

By the way, I would like to thank everyone for their comments and suggestions. You all have helped us a lot with our project. :slight_smile:

I am working on making some figures and organizing photos. I will post soon to share our complete setup.

Although I think the motor+driver combination isn’t perfect, it works well enough for our application. Thank you again to everyone who interacted with this post!

1 Like