BLDC motor battery current spikes

hi..
This is sivaram from india. I developed a code file which is supposed to run in motoring mode and braking if needed. I probed the DC input current of the inverter its showing as figure attached. one of the inverter leg is getting heated. The switch numbering is describe in the code file. I don't know the reason why it is happening. If additional info is need I can give the details.
hope it makes sense, what i am asking for......

// This is code is for BLDC motor is operated in PWM mode for motoring and braking operation.
// The LOW side swithces are intended to operated in PWM with TIMER3 output pins and HIGH side switches are just turn on and off.
// The high side switches T1 connected to pin 10
//                        T3              pin 9
//                        T5              pin 8

// The low side switches  T4 connected to pin 5
//                        T6              pin 3
//                        T2              pin 2

// The pin 50 is used as the switch for the transition.


// Polling variable.
volatile uint8_t ZZ = 0, XX = 0;
 
void setup() 
{ 
  // enable the global interrupts
  sei();

  // setting pin 50 for the transition between motoring and braking.
  pinMode(50,INPUT_PULLUP);

  // setting PORTC as input port. mainly to read pin 33 34 and 35 on the board.
  DDRC = 0x00;
  // turning on the internal pull-up resistors of the MCU.
  PORTC = 0xFF;
  
  // High side switching signals
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  
  // setting PIN 13 as high for the MOSFET driver AND gate input.
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);  
  
  // starting the timer3 for PWM generation of LOW side switches.
  TCNT3  = 0x0000;
  OCR3B  = 35;
  OCR3A  = 35;
  OCR3C  = 35;
  ICR3L  = 50; 
  TCCR3A = 0b10101010;
  TCCR3B = 0b00011011;

  // starting timer4 for event management. (polling of hall signal is done for every 15 us)
  TCNT4  = 0x0000;
  OCR4B  = 0x0F;
  OCR4A  = 0x00EF;
  TIMSK4 = 0b00000010; 
  TCCR4A = 0b00100011;
  TCCR4B = 0b00011001;
}

void loop()
{
  // Do nothing.
}

ISR(TIMER4_COMPA_vect)
{
  XX = PINB;
  if((XX & (1 << 3)))
  {
    // motoring
      ZZ = PINC;
  switch (ZZ)
  {
    case 0b11100111:
      /* turning on T6 and T5 for 001 output */
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      digitalWrite(8,HIGH);
      pinMode(2,INPUT);
      pinMode(5,INPUT);
      pinMode(3,OUTPUT);
      break;

    case 0b11101011:
      /* turning on T4 and T3 for 010 output */
      digitalWrite(8,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,HIGH);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,OUTPUT);
      break;

    case 0b11101111:
      /* turning on T4 and T5 for 011 output */
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      digitalWrite(8,HIGH);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,OUTPUT);
      break;

    case 0b11110011:
      /* turning on T1 and T2 for 100 output */
      digitalWrite(10,HIGH);
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      pinMode(2,OUTPUT);
      break;

    case 0b11110111:
      /* turning on T1 and T6 for 101 output */
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      digitalWrite(10,HIGH);
      pinMode(2,INPUT);
      pinMode(5,INPUT);
      pinMode(3,OUTPUT);
      break;

    case 0b11111011:
      /* turning on T2 and T3 for 110 output */
      digitalWrite(8,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,HIGH);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      pinMode(2,OUTPUT);
      break;

    default:
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      break;
  } 
  }
  else
  {
    // braking
      ZZ = PINC;
  switch (ZZ)
  {
    case 0b11100111:
      /* PWM applied at T6, for 001 output */
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      digitalWrite(8,LOW);
      pinMode(2,INPUT);
      pinMode(5,INPUT);
      pinMode(3,OUTPUT);
      break;

    case 0b11101011:
      /* PWM applied at T4, for 010 output */
      digitalWrite(8,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,LOW);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,OUTPUT);
      break;

    case 0b11101111:
      /* PWM applied at T4, for 011 output */
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      digitalWrite(8,LOW);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,OUTPUT);
      break;

    case 0b11110011:
      /* PWM applied at T2, for 100 output */
      digitalWrite(10,LOW);
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      pinMode(2,OUTPUT);
      break;

    case 0b11110111:
      /* PWM applied at T6, for 101 output */
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      pinMode(2,INPUT);
      pinMode(5,INPUT);
      pinMode(3,OUTPUT);
      break;

    case 0b11111011:
      /* PWM applied at T2, for 110 output */
      digitalWrite(8,LOW);
      digitalWrite(10,LOW);
      digitalWrite(9,LOW);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      pinMode(2,OUTPUT);
      break;

    default:
      digitalWrite(8,LOW);
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);
      pinMode(2,INPUT);
      pinMode(3,INPUT);
      pinMode(5,INPUT);
      break;
  } 
  }
}

// The code is under test

F0004TEK.JPG

There is something very odd in your code - the low side switch pins are being toggled between INPUT and OUTUT rather than HIGH and LOW.

Why is this? It seems unlikely to me.

Can you provide the circuit schematic, that's vital to understanding whats going on.

Also I note you don't always switch off before switching on - so you are bound to have lots of shoot-through

Hey Mark

I have attached the ckt and the commutation table for the motor.

hiiii

I have tried the following code file it is working fine without any shoot through.

// This is code is for BLDC motor is operated in openloop.
// In this code example the timer 4 is used for the event management for the Electronic commutation.

// The connections for the gate driver circuit is described below.
// T1 ---- pin 12
// T2 ---- pin 5
// T3 ---- pin 9
// T4 ---- pin 11
// T5 ---- pin 6
// T6 ---- pin 8


// Polling variable.
volatile uint8_t ZZ = 0;

void setup() 
{ 
  // enable the global interrupts
  sei();

  // setting PORTC as input port. mainly to read pin 33 34 and 35 on the board.
  DDRC = 0x00;
  // turning on the internal pull-up resistors of the MCU.
  PORTC = 0xFF;

  /* pin 11 and 12 of Arduino board are set as output for T4 and T1 switch driving*/
  DDRB |= (1<<PINB5)|(1<<PINB6);
  /* pin 8 and 9 of Arduino board are set as output for T6 and T3 switch driving*/
  DDRH |= (1<<PINH5)|(1<<PINH6);
  /* pin 6 and 5 of Arduino board are set as output for T5 and T2 switch driving*/
  DDRH |= (1<<PINH3);
  DDRE |= (1<<PINE3);
    
  // setting PIN 13 as high for the MOSFET driver AND gate input.
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);  
  

  // starting timer4 for event management. (polling of hall signal is done for every 15 us)
  TCNT4  = 0x0000;
  OCR4B  = 0x0F;
  OCR4A  = 0x00EF;
  TIMSK4 = 0b00000010; 
  TCCR4A = 0b00100011;
  TCCR4B = 0b00011001;
}

void loop()
{
  // Do nothing.
}

ISR(TIMER4_COMPA_vect)
{
  ZZ = PINC;
    switch (ZZ)
    {
      case 0b11100111:
      /* turning on T6 and T5 for 001 output */
      PORTH = 0b00101000;
      PORTE = 0x00;
      PORTB = 0x00;
      break;
      
      case 0b11101011:
      /* turning on T4 and T3 for 010 output */
      PORTB = 0b00100000;
      PORTH = 0b01000000;
      PORTE = 0x00;
      break;
      
      case 0b11101111:
      /* turning on T4 and T5 for 011 output */
      PORTB = 0b00100000;
      PORTH = 0b00001000;
      PORTE = 0x00;
      break;
      
      case 0b11110011:
      /* turning on T1 and T2 for 100 output */
      PORTB = 0b01000000;
      PORTH = 0x00;
      PORTE = 0b00001000;
      break;
      
      case 0b11110111:
      /* turning on T1 and T6 for 101 output */
      PORTB = 0b01000000;
      PORTH = 0b00100000;
      PORTE = 0x00;
      break;
      
      case 0b11111011:
      /* turning on T2 and T3 for 110 output */
      PORTB = 0x00;
      PORTH = 0b01000000;
      PORTE = 0b00001000;
      break;
      
      default:
      PORTB = 0x00;
      PORTH = 0x00;
      PORTE = 0x00;
      break; 
    }
}

// The code is working.
// In this code example the LOW side PMW cannot be applied.

But for the first code first code file which I posted their is a shoot through problem occuring when ever their is a transition regarding the W-phase of the motor terminals.
The problem with the second code file is I cannot apply the PWM for the low side switches. My professor is asking for the solution for PWM to LOW side switches.

The following code is modified version of the staring one but without PWM.

Hey if someone Knows BLDC motor controlling please helpme.

// This is code is for BLDC motor is operated in openloop.
// The LOW side swithces are intended to operated in PWM with TIMER3 output pins and HIGH side switches are just turn on and off.
// The high side switches T1 connected to pin 10
//                        T3              pin 9
//                        T5              pin 8

// The low side switches  T4 connected to pin 5
//                        T6              pin 3
//                        T2              pin 2



// Polling variable.
volatile uint8_t ZZ = 0;

// macros for the switching signals
#define T1    10
#define T2    2
#define T3    9
#define T4    5
#define T5    8
#define T6    3
  
void setup() 
{ 
  // enable the global interrupts
  sei();

  // setting PORTC as input port. mainly to read pin 33 34 and 35 on the board.
  DDRC = 0x00;
  // turning on the internal pull-up resistors of the MCU.
  PORTC = 0xFF;

  // Low side signals
  pinMode(5,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(6,OUTPUT);
  
  // High side switching signals
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  
  // setting PIN 13 as high for the MOSFET driver AND gate input.
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);  
  
  // starting the timer3 for PWM generation of LOW side switches.
//  TCNT3  = 0x0000;
//  OCR3B  = 35;
//  OCR3A  = 35;
//  OCR3C  = 35;
//  ICR3L  = 50; 
//  TCCR3A = 0b10101010;
//  TCCR3B = 0b00011011;

  // starting timer4 for event management. (polling of hall signal is done for every 15 us)
  TCNT4  = 0x0000;
  OCR4B  = 0x0F;
  OCR4A  = 0x00EF;
  TIMSK4 = 0b00000010; 
  TCCR4A = 0b00100011;
  TCCR4B = 0b00011001;
}

void loop()
{
  // Do nothing.
}

ISR(TIMER4_COMPA_vect)
{
  // For motoring operation.
  ZZ = PINC;
  switch (ZZ)
  {
    case 0b11100111:
      /* turning on T6 and T5 for 001 output */
      digitalWrite(T1,LOW);
      digitalWrite(T2,LOW);
      digitalWrite(T3,LOW);
      digitalWrite(T4,LOW);
      digitalWrite(T5,HIGH);
      digitalWrite(T6,HIGH);
      break;

    case 0b11101011:
      /* turning on T4 and T3 for 010 output */
      digitalWrite(T1,LOW);
      digitalWrite(T2,LOW);
      digitalWrite(T5,LOW);
      digitalWrite(T6,LOW);
      digitalWrite(T4,HIGH);
      digitalWrite(T3,HIGH);
      break;

    case 0b11101111:
      /* turning on T4 and T5 for 011 output */
      digitalWrite(T1,LOW);
      digitalWrite(T2,LOW);
      digitalWrite(T3,LOW);
      digitalWrite(T6,LOW);
      digitalWrite(T4,HIGH);
      digitalWrite(T5,HIGH);
      break;

    case 0b11110011:
      /* turning on T1 and T2 for 100 output */
      digitalWrite(T5,LOW);
      digitalWrite(T6,LOW);
      digitalWrite(T3,LOW);
      digitalWrite(T4,LOW);
      digitalWrite(T1,HIGH);
      digitalWrite(T2,HIGH);
      break;

    case 0b11110111:
      /* turning on T1 and T6 for 101 output */
      digitalWrite(T5,LOW);
      digitalWrite(T2,LOW);
      digitalWrite(T3,LOW);
      digitalWrite(T4,LOW);
      digitalWrite(T1,HIGH);
      digitalWrite(T6,HIGH);
      break;

    case 0b11111011:
      /* turning on T2 and T3 for 110 output */
      digitalWrite(T1,LOW);
      digitalWrite(T6,LOW);
      digitalWrite(T5,LOW);
      digitalWrite(T4,LOW);
      digitalWrite(T2,HIGH);
      digitalWrite(T3,HIGH);
      break;

    default:

      break;
  }
}

// The code is working.

You have an interesting project, it is not an easy one to solve. Try this link for starters: Texas Instruments DRV10964 Sensorless BLDC Motor Driver, there are many more, you can look for them. Several do all the filtering in the chip for you. Consider simply generating preferably a sinusoidal a 3 phase signal to drive the motor, open loop, it works best. A square wave will work but you will get more noise and heating. Then simply change the frequency, the output will be the relationship between the number of poles - the slip. Commutation is a problem and if not properly done you will get shoot through. Dynamic breaking is accomplished by shorting the windings ie. turn them all on or off but there will be recirculation currents to be careful of. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

Hey gill
Thanks for the reply.

yeahhhhhh I am trying to get the solution.

Hi friends..

Actually their is a faulty MOSFET driver for the W-phase in my hardware. That's the reason for the shoot through in inverter. anyways thanks to every one who replied.

Hey mark you mentioned why switching the pin from input to output. The answer for that question is....

Timer-3 is acessed for PWM operation of the LOW side switches whenever I want to turn off the switch out of PWM signal, the corresponding pin is made INPUT (which disconnect the pin from the timer module).
Hope this answer makes some sense. :slight_smile: