Driving the motor with a current sensor

Hi!

I’m trying to run my motor using my new low side current sense code.

When I use the TorqueControlType::voltage mode the current readings seem very good. As I set the target to e.g. 1.0, and manually force the motor away from this point, the phase currents raise in a predictible manner:

  motor.torque_controller = TorqueControlType::foc_current;
  motor.controller = MotionControlType::angle;

  // contoller configuration based on the control type 
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;

    // contoller configuration based on the control type 
  motor.P_angle.P = 5;
  motor.P_angle.I = 0.1;
  motor.P_angle.D = 0.5;

  // default voltage_power_supply
  // COMMENTED !!! motor.phase_resistance = 0.14; <- not set
  motor.voltage_limit = 1;
  motor.current_limit = 0.1;

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

  // angle loop velocity limit
  motor.velocity_limit = 50;
force     ph A      ph B     ph C   timestamp        angle sensor
0          18.43   18.99   19.03   12887837          1.02
CCW:   22.46   18.99   17.98   142493226        0.60
CW:     15.84    19.20   20.21   218107287       1.45

My motor phase resistange has been measured to be 0.14 ohm with an high precision ohm meter (YR2050). More precisely, the resistance between wire pairs are 0.28028, 0.27975 and 0.28077 ohm.

Then I triy to actually use the current sensor using these settings

  motor.torque_controller = TorqueControlType::foc_current;
  motor.controller = MotionControlType::angle;

  // contoller configuration based on the control type 
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;

    // contoller configuration based on the control type 
  motor.P_angle.P = 5;
  motor.P_angle.I = 0.1;
  motor.P_angle.D = 0.5;

  // default voltage_power_supply
  motor.phase_resistance = 0.14;
  motor.voltage_limit = 1;
  motor.current_limit = 0.1;

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

  // angle loop velocity limit
  motor.velocity_limit = 50;

The initFOC() passes (yes @Antun_Skuric, I uncommented the driverAlign() code and it passes) but as soon as the loop() begins, the motor locks with a big CLANK! and my 12V/15A old ATX psu shuts down (protection). I’m using a DRV8305 BOOSTXL kit with 0.007 Ohm shunt resistors.

BLDCDriver6PWM driver(UH, UL, VH, VL, WH, WL, DRV_GATE_EN);
LowsideCurrentSense current_sense(0.007f, 10.0f, DRV_SOA, DRV_SOB, DRV_SOC);

If I look at the 6 PWM signals it is completely erratic with long dead period alternating on phases, nothing to do with the nice regular signal I get in voltage mode.

Any hnts?

Thank you!

I wouldn’t jump straight to angle control. Try torque mode with foc_current and try to tune the controller as good as possible. From your code snippet, it looks like you’re not changing the default parameters of the current PI loops. Proper tuning is going to be hard to do, but should be possible.

In this thread there’s a few recommendations on how to tune the current PI loops:

Thank you very much David!

I will read that thread and try what you suggest!

Hey! it’s (barely) alive.

I used @ngalin’s parameters along with my measure 0.14ohm phase resistance and the motor is moving (erratically, but it’s an improvement from crashing my PSU)

LowsideCurrentSense current_sense(0.007f, 10.0f, DRV_SOA, DRV_SOB, DRV_SOC);
[...]

  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
  motor.controller = MotionControlType::velocity;
  motor.torque_controller = TorqueControlType::foc_current;

  motor.phase_resistance = 0.14;
  motor.voltage_limit = 6;
  motor.current_limit = 2;
  motor.velocity_limit = 20;

  // PID_current_q:	
  motor.PID_current_q.P = 0.5;
  motor.PID_current_q.I = 0.1;
  motor.PID_current_q.D = 0;
  motor.PID_current_q.output_ramp = 50;
  motor.PID_current_q.limit = 1;
  // PID_current_d:	
  motor.PID_current_d.P =	1;
  motor.PID_current_d.I =	0.5;
  motor.PID_current_d.D =	0.01;
  motor.PID_current_d.output_ramp =	100;
  motor.PID_current_d.limit =	2;
  // PID_velocity:	
  motor.PID_velocity.P = 1;
  motor.PID_velocity.I = 0.2;
  motor.PID_velocity.D = 0.05;
  motor.PID_velocity.output_ramp = 1000;
  motor.PID_velocity.limit = 500;
  motor.LPF_current_q = 0.1;
  motor.LPF_current_d = 0;
  motor.LPF_velocity = 1;

I suggest you do MotionControlType::torque before trying velocity or angle control. A trick that worked for me is only using two currents in the CurrentSense constructor, instead of the three.

This is how it should behave in torque mode: when setting a target of 0 the motor should feel easy to spin, even easier than with the motor disconnected, and when you set a target of 1 or 2 Amps to the q axis it should spin very fast, but with barely any torque (very easy to stop with your fingers).

Thanks,

I’m getting nowhere in velocity mode. It’s not easy to make sense of the motor behavior.

Would you be so kind to share a good starting point for the motor/PID/LPF settings?

Hey @malem,

Tuning PIDs is not easy, especially when you need to start from the current control loop.
Here is a set of parameters that works in my case (this was generated by the SimpleFOCStudio):

  // velocity loop PID
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 5.0;
  motor.PID_velocity.D = 0.0;
  motor.PID_velocity.output_ramp = 0.0;
  motor.PID_velocity.limit = 12.0;
  // Low pass filtering time constant 
  motor.LPF_velocity.Tf = 0.02;
  // angle loop PID
  motor.P_angle.P = 20.0;
  motor.P_angle.I = 0.0;
  motor.P_angle.D = 0.0;
  motor.P_angle.output_ramp = 0.0;
  motor.P_angle.limit = 50.0;
  // Low pass filtering time constant 
  motor.LPF_angle.Tf = 0.0;
  // current q loop PID 
  motor.PID_current_q.P = 3.0;
  motor.PID_current_q.I = 100.0;
  motor.PID_current_q.D = 0.0;
  motor.PID_current_q.output_ramp = 0.0;
  motor.PID_current_q.limit = 12.0;
  // Low pass filtering time constant 
  motor.LPF_current_q.Tf = 0.02;
  // current d loop PID
  motor.PID_current_d.P = 3.0;
  motor.PID_current_d.I = 100.0;
  motor.PID_current_d.D = 0.0;
  motor.PID_current_d.output_ramp = 0.0;
  motor.PID_current_d.limit = 12.0;
  // Low pass filtering time constant 
  motor.LPF_current_d.Tf = 0.02;

If you have a stable values for the current control, the velocity loop will work ok.
The rule of thumb is to divide the values that work well for the voltage mode by ~10 or so, for example.

What is exactly the behavior you see, the motor locks in place or starts spinning out of control?

Hi Antun,

Thanks for the hints.

The motor spun out of control and now nFault is always on on my DRV8305, maybe a wire got disconnected. My test setup is getting crowded!

I will investigate this through DRV’s SPI and then try your PID settings. I’ll also invest som time on my binary scope/logger, I’d like to make it DMA-based too so it doesn’t affect the main loop’s performance.

Thanks.

Had a lot of “fun” today investigating that nFault error. unplugged everything from the BOOSTXL, made sure I could clear nfault using E-Gate. then plugged SPI only, I could now clear nFault by reading registers. Then I connect back the pwm signals and try again and it goes back to nFault, SPI tells me that:

Report for register: 3
AVDD_UVLO (AVDD undervoltage fault):                            True (0b1)

darn!
@David_Gonzalez @Gouldpa any clue what I could have damaged on my BOOSTXL?

I see no signs of physical harm on the chip, but while strying to tune the current pid loop I crashed my desktop AXT PSU 4-5 times.

It’s not easy to damage those chips. Have you tested to see if you can still run voltage mode? Just to make sure everything is working properly

oh yes I did. In fact, when I’m lucky enough to be able to clear the nFault, just running initFOC will trigger the AVDD_UVLO fault.

I just unplugged everything again (12V, no motor) and this time I’m not able to clear the nFault by pulling up EGate anymore.

The little LMR16006XDDC still gives me some 3.68V.

I’m totally puzzled.

this sucks, I don’t have a backup 8305.

I’ll have to switch to my 8316 EVM I just received. I wonder how I’ll be careful enought not to break it.

Have you tried using a different PSU? I’m wondering why you have an under-voltage condition.

Yes, switched to my 50C 5Ah 12v battery, same same :frowning: