This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRV8823 current limited

Other Parts Discussed in Thread: SN65HVS880, DRV8823

Dear TI Team,

I'm currently working on a redesign of a product using your DRV8823 to drive 3 DC motor actuated valves and 1 solenoid valve (old design used 2 L298 motor drivers). The new design also incorporates an SN65HVS880 input serializer on the same SPI bus which I already got working successfully. 

Using the DRV8823 has been a bit more problematic, after a couple of days trying to troubleshoot it I think I'm at the point that I need your help. I'm managing to control each of the 4 bridges (getting +24V- 0  -24V as per my test routine) , but when I connect the motors the current gets limited to about 300mA, not enough to make the valves move. During normal operation one valve draws about 1.2A and takes only 1s to get from open to close position or vice versa.

I'm feeding 2.53V to the ABREF & CDREF pins through a voltage divider which is fed from the 5V supply of the SN65GVS880. The current sense resistors are 0.33ohms.

I've tried changing the 3 current regulation bits and other configuration combinations but to no avail. The test code which I'm currently using is posted below.

Any suggestions would be greatly appreciated.

Best Regards,

Loic

//DRV8823
// the motor driver communicates using SPI, so include the library:
#include <SPI.h>

const int csSrlzrPin = 8; //SN65HVS880 serializer CS, not used in this test code
const int loadSrlzrPin = 13; //SN65HVS880 serializer load pin

const int csMotorPin = 9; //DRV8823 CS pin
const int sstbMotorPin = 3; //DRV8823 sstb pin

const int channel = 1; //choose which motor channel we want to drive


int byte1 = B00011100; //initial state of DRV8823 control byte1
int byte2 = B00000111; //initial state of DRV8823 control byte2

void setup() {
    
  // initalize the load and chip select pins:
  pinMode(csSrlzrPin, OUTPUT);
  pinMode(loadSrlzrPin, OUTPUT);
  pinMode(csMotorPin, OUTPUT);
  pinMode(sstbMotorPin, OUTPUT);
  
  digitalWrite(csSrlzrPin,HIGH); 
  digitalWrite(loadSrlzrPin,HIGH); 
  digitalWrite(csMotorPin,LOW); 
  digitalWrite(sstbMotorPin,LOW); 
 
  // start the SPI library:
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV16);		// Divide MCU clock (16MHz) by 16, SCK = 1MHz
  SPI.setBitOrder(LSBFIRST);
}

void loop() {
 
  driveMotor(channel, 1); //turn motor in direction 1
  delay(1000);

  driveMotor(channel, 0); //turn off motor
  delay(3000);

  driveMotor(channel, 2); //turn motor in direction 2
  delay(1000);

  driveMotor(channel, 0); //turn off motor
  delay(3000);
  
}



void driveMotor(int ch, int mode) {
 
  switch (ch) { //manipulate bits based on motor CH and direction commands
  case 1: //CH1
  if (mode == 0) { //Turns motor CH1 off
  bitWrite(byte1, 0, 0); 
  }
  if (mode == 1) { //Turns motor CH1 on in direction 1
  bitWrite(byte1, 0, 1);
  bitWrite(byte1, 1, 0); 
  
  
  }
  if (mode == 2) { //Turns motor CH1 on in direction 2
  bitWrite(byte1, 0, 1); 
  bitWrite(byte1, 1, 1); 
  }
  bitWrite(byte2, 4, 0); 
  break;
 
  case 2: //CH2
  if (mode == 0) {
  bitWrite(byte1, 6, 0); 
  }
  if (mode == 1) {
  bitWrite(byte1, 6, 1);
  bitWrite(byte1, 7, 0);
  }
  if (mode == 2) {
  bitWrite(byte1, 6, 1);
  bitWrite(byte1, 7, 1); 
  }
  bitWrite(byte2, 4, 0); 
    // statements
    break;
    
  case 3://CH3
  if (mode == 0) {
  bitWrite(byte1, 0, 0); 
  }
  if (mode == 1) {
  bitWrite(byte1, 0, 1);
  bitWrite(byte1, 1, 0); 
  }
  if (mode == 2) {
  bitWrite(byte1, 0, 1); 
  bitWrite(byte1, 1, 1); 
  }
  bitWrite(byte2, 4, 1); 
    // statements
    break;
    
  case 4://CH4
  if (mode == 0) {
  bitWrite(byte1, 6, 0); 
  }
  if (mode == 1) {
  bitWrite(byte1, 6, 1);
  bitWrite(byte1, 7, 0);
  }
  if (mode == 2) {
  bitWrite(byte1, 6, 1); 
  bitWrite(byte1, 7, 1); 
  }
  bitWrite(byte2, 4, 1); 
  break;
  
}
  
  
//Transfer control bits via SPI to DRV8823  
  
  
  // take the SS pin high to select the chip:
  digitalWrite(csMotorPin,HIGH);
  
  //  send in the address and control bits via SPI:
  SPI.transfer(byte1);
  SPI.transfer(byte2);
  
  // take the SS pin low to de-select the chip:
  digitalWrite(csMotorPin,LOW); 
  
  //latch data from SPI holding register to motor control
  digitalWrite(sstbMotorPin, HIGH); 
  delayMicroseconds(1);
  digitalWrite(sstbMotorPin, LOW); 
  
}

  • Hi Loic

    So you problem is the real regulated current 300mA is much smaller than the setting level which should be 2.53/5/0.33=1.53A.

    Have you checked the real xxVREF pin voltage and the xI0, xI1, xI2 bits setting? 

    Did this issue happen to one H bridge or all the four H bridges?

    Before the code checking, please make sure all the hardware settings, registers, layout are fine and correctly set.

    And could you show the schematic of DRV8823? that will be helpful.

    Thanks & Regards,

  • Hi Wilson,

    Thank you for your reply. Indeed, the problem is that the regulated current is much smaller than the setting level.

    The 2.53V is the actual voltage that I measured on the VREF pins. I tried changing the xI0-3 bits to the best of my knowledge, but maybe there is something wrong with my code which I'm not spotting.

    The issue is identical for all four bridges.

    Please find schematic of field side in attachment.

    Thank you in advance.

    Best Regards,

    Loic

    Evo1-field side TI.pdf
  • Hi Loic

    Your schematic of DRV8823 looks good.

    So I think the most possible cause is the xI0, xI1, xI2 are not correctly set. As you can see the default (0, 0, 0) stands for the 20% of the setting level (1.5A), just about 300mA. 

    Could you get a waveform of initial serial data with SCS, SCLK, SDATA in the same frame?

    Thanks & Regards,

  • Hi Wilson,

    Please see waveform below. Do you see any problem in my code?

    Do I need to write the current limitation bits at the beginning of runtime before I send general motor control commands or can the configuration bits be set at the same time when I send general motor control bits during loop?

     Best Regards,

    Loic

  • Hi Wilson,

    Could you please tell me if you have any other suggestions? I need to resolve this issue asap and I'm running out of options...

    Thank you in advance.

    Loic

  • Hi Loic

    Could you try SSTB = HIGH all the time?

    Thanks & Regards

  • Hi Wilson,

    I tried SSTB = HIGH all the time but unfortunately no luck... Still stick at 300mA...

    Regards,

    Loic

  • Hi Wilson,

    I soldered up another board just to rule out any hardware malfunctions/assembly errors but I'm getting similar results. The motor driver is switching in the correct sequence (+24V 0V -24V), but again only providing very limited or no current. When I connect my motors it doesn't source any current at all! Connecting a 24V relay works fine (driving 60mA). Is it possible that maybe when the valve motors get actuated the inrush current makes the DRV8823 go into OCP mode? I also tried feeding in Vref (0-4V) from an external source but it didn't change anything.

    I'm getting to the point that I might have to abandon this design and go back to the L298 motor drivers that worked in the past...

    Any suggestions would be appreciated. Do you happen to have any support office in Beijing where I could go to have the board checked out?

    Thank you in advance.

    Best Regards,

    Loic

  • Hi Loic I'm sorry to keep you waiting. I will be back from customer visit today. I will send my contact to you and let us figure out a way to solve it quickly. Thanks,
  • We finally figured out what the issue was: My motors have very high inrush current, this was triggering the Overcurrent Current Protection (OCP) system of the DRV8823. By adding 47uH inductors in series with both phases of the motor the inrush current is limited and the DRV8823 manages to drive the motors.

    Thank you for the fantastic help Wilson!

    Best Regards,

    Loic