DRV8301/8302 Current Sense Setup


Has anyone had any success setting up the current sense with the DRVs? I have some custom hardware based on the Odrive schematics and was working well with Odrive firmware. I now have SimpleFOC running on these ( runs better than Odrive firmware ) I have them running perfectly in voltage/velocity/angle modes and have now been trying to set up current control.

I’m using 0.0005-ohm shunt resistors and the default DVR gain settings which are 10. In the Odrive firmware, a gain value of 22 worked. I have tried 10,22,50 and so on with not much luck. I’m getting very unstable readings, the current readings will jump all over the place anywhere from -1 to 2 - 3 when the motor is actually drawing around 150ma. The Q, D reading were also all over the place around -1400 etc

The Shunt resistors are connected to the ground. I don’t know if this has anything to do with it ( I have tried inverting in software and not much change, still unstable ) Do the gain settings in the DRV need to be altered via SPI rather than in SimpleFOC.

I have been through the DRV datasheet to try and get the best understanding I can, but I’m a bit lost and don’t know what to try from here, here you can see the specific current sense stuff from the datasheet. Pages 9 and 16

Hello Matt,

The current sense code is far from ready in the main branch. Proper (low-side) current sense requires you to sample the ADC at a precise moment and it can prove to be challenging.

I’m working on a SAMD21-based solution, which you can find here, and I’ve just returned to it right now. @Antun_Skuric and @runger are not comfortable to pull in so much implementation-specific code (and I think they are right, yet I think what I’m trying to do expose some limitations with the current (pun!) implementation.

Right now I have an angle loop “working” (can’t seem to be able to tune that pid right, but at least it’s vivrating around setpoint and fight to get back when I force it out with my hand).


    motor.phase_resistance = 0.14; //motor is a cheap 5010-360kv with very low phase resistance
    motor.current_limit = 8;
    motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
    motor.controller = MotionControlType::angle;
    // motor.controller = MotionControlType::velocity;
    motor.torque_controller = TorqueControlType::foc_current;

    // motor.phase_resistance = 0.14;
    // motor.voltage_limit = 2;
    // motor.current_limit = 1;
    motor.velocity_limit = 20;

    // PID_current_q:	
    motor.PID_current_q.P = 0.21; //from Instaspin
    motor.PID_current_q.I = 0.057; //from Instapin
    motor.PID_current_q.D = 0;
    motor.PID_current_q.output_ramp = 0;
    motor.LPF_current_q.Tf = 0.0005;

    // PID_current_d:	
    motor.PID_current_d.P =	motor.PID_current_q.P;
    motor.PID_current_d.I =	motor.PID_current_q.I;
    motor.PID_current_d.D =	motor.PID_current_q.D;
    motor.PID_current_d.output_ramp =	motor.PID_current_q.output_ramp;
    motor.LPF_current_d.Tf = motor.LPF_current_q.Tf;

    // PID_angle:	
    motor.P_angle.P = 90;
    motor.P_angle.I = 20;
    motor.P_angle.D = 0; 
    motor.LPF_angle.Tf = 0.001;

I’m completely tired of tuning my pid by hand so I’m looking at the theory behind all this, hoping to come out if a more automatic solution (i.e. moving towards replicating TI’s InstaSpin)