5

Hey everyone this is my first time reaching out to the community for help to see if someone can show me what I'm not seeing on this. Basically I am trying to make my own ESC for a BLDC and before anyone says the commercial solution is cheaper and easier, I know. I'm doing it to try learn some more in-depth programming/power electronic as well as to make a customisable version that's all my own work for if i want to use it for something else down the road, so lets get into the issue.

The problem is although I'm using a 20kHz PwM signal at a variable duty on the high side HBridge generated by direct timer control on the atmega328p (Arduino NANO), to try "chop"/control the current (also to control speed when using Zero-Cross detection) as well as keeping the lowside HBridge fully grounded on any given step, the MOSFETs (N-channel irf1405s 55V and 160A rated) are getting really really hot very fast and so is the motor like over 150 degrees Celsius hot even after only running for 30 - 120 seconds. The actual motor spins just fine however, I can even change the speed using an Arduino delay timed step change (although I do have the hardware and did have the software for BEMF step changing too I disabled it to try simplify things while attempting to solve the heating issue as its my main priority).

I've attached my code and schematic if anyone can see something on this that I can't it would be much appreciated because I'm outta ideas I've tried adding lots of different changes to the hard and software with no luck.

I built a version using P Chanels on the high side and a BJT to switch them whilst PWMing the low side, it had a similar heating problem although abit slower. I built a version using a BJT to feed the PWM coming from the Arduino OUTPUT to both HIN and LIN on the ir2101, since LIN is inverted I was hoping to connect the bridge to ground whenever it wasn't being pulsed in an attempt to give the collapsing magnetic field of the BLDC coil somewhere to flow but even though the scope showed the output was pulsing correctly when I connected the motor this didn't work either, at the end of it all I went back to the attached schematic and code but I still can't seem to stop the MOSFETs and motor from getting really hot because of what I assume is excessive current draw (possibly from an EMF building up in the coils and trying to ground through the FETS body when the HBridge goes to floating??).

If I increase the duty to 60-70%+ the MOSFETs also just straight up explode even with some long dead time coded in using delay functions. I'm using a 12V 6.5Ah lead acid battery for testing as its close to the power supply I would use the ESC with normally and an amount of power something like this should handle no problems when working properly.

So to conclude if anyone with experience in power electronics or who has any ideas on how to fix my heating issue is reading this please help. Any equations I may need to consider more carefully, or advanced things a fairly beginner engineer like me might have missed would be much appreciated since at this point I've killed more Fets than I'd like to have.

Schematic

My Code:

int StepCounter = 1; //step counter int RawDutyCycle = 0; //raw pot input storage variable int Duty = 0; //duty cycle

//setup lowside pins for standalone direct port manipulation int LowSideA = PD2; //pin D2 int LowSideB = PD5; //pin D5 int LowSideC = PD7; //pin D7

//setup highside pins to be PWM outputs at port level int HighSideA = PD3; //OC2B D3 int HighSideB = PB1; //OC1A D9 int HighSideC = PB2; //OC1B D10

//defins all the PWM pin States neatly #define HighSideASetON (1<<COM2A0) + (1<<COM2B1) + (1<<WGM20) #define HighSideASetOFF (0<<COM2A0) + (0<<COM2B1) + (1<<WGM20)

#define HighSideBSetON (1<<COM1A1) + (0<<COM1B1) #define HighSideCSetON (0<<COM1A1) + (1<<COM1B1) #define HighSideBandCSetOFF (0<<COM1A1) + (0<<COM1B1)

void setup() {

//Sets data direction of all pins DDRD = (1<<LowSideA) | (1<<LowSideB) | (1<<LowSideC) | (1<<HighSideA); DDRB = (1<<HighSideB) | (1<<HighSideC); pinMode(A0, INPUT);

//timer1 PWM pins D9 and D10 setup TCCR1A = 0; TCCR1B = 0; TCCR1A = (1<<COM1A1) + (1<<COM1B1) + (1<<WGM11); //phase correct pwm TCCR1B = (1<<WGM13) + (1<<CS11); ICR1 = 100; //set kHz OCR1A = 10; //set duty OCR1B = 10; //set duty

//timer2 PWM pin D3 setup TCCR2A = 0; TCCR2B = 0; TCCR2A = (1<<COM2A0) + (1<<COM2B1) + (1<<WGM20); //phase correct pwm TCCR2B = (1<<CS21) + (1<<WGM22); OCR2A = 100; //set kHz OCR2B = 10; //set duty

//Sets all 3 H-bridges to float TCCR1A = (0<<COM1A1) + (0<<COM1B1); TCCR2A = (0<<COM2A1) + (0<<COM2B1); PORTD = (1<<LowSideA) + (1<<LowSideB) + (1<<LowSideC);

}

void loop() {

RawDutyCycle = analogRead(A0); //read the pot int WaitTime = map(RawDutyCycle, 0, 1023, 10000, 500); Duty = 50; OCR1A = Duty; //set duty OCR1B = Duty; OCR2B = Duty;

delayMicroseconds(WaitTime);

switch(StepCounter){

case 1: //step1
TCCR1A = HighSideBandCSetOFF;
PORTD = (1&lt;&lt;LowSideA) + (0&lt;&lt;LowSideB) + (1&lt;&lt;LowSideC);
TCCR2A = HighSideASetON;
StepCounter = 2;
break;

case 2: //step2
TCCR1A = HighSideBandCSetOFF;
PORTD = (1&lt;&lt;LowSideA) + (1&lt;&lt;LowSideB) + (0&lt;&lt;LowSideC);
TCCR2A = HighSideASetON;
StepCounter = 3;
break;

case 3: //step3
TCCR2A = HighSideASetOFF;
PORTD = (1&lt;&lt;LowSideA) + (1&lt;&lt;LowSideB) + (0&lt;&lt;LowSideC);
TCCR1A = HighSideBSetON;
StepCounter = 4;
break;

case 4: //step4
TCCR1A = HighSideBandCSetOFF;
PORTD = (0&lt;&lt;LowSideA) + (1&lt;&lt;LowSideB) + (1&lt;&lt;LowSideC);
TCCR1A = HighSideBSetON;
StepCounter = 5;
break;

case 5: //step5
TCCR1A = HighSideBandCSetOFF;
PORTD = (0&lt;&lt;LowSideA) + (1&lt;&lt;LowSideB) + (1&lt;&lt;LowSideC);
TCCR1A = HighSideCSetON;
StepCounter = 6;
break;

case 6: //step6
TCCR1A = HighSideBandCSetOFF;
PORTD = (1&lt;&lt;LowSideA) + (0&lt;&lt;LowSideB) + (1&lt;&lt;LowSideC);
TCCR1A = HighSideCSetON;
StepCounter = 1;
break;

} }

Fred
  • 9,782
  • 13
  • 36
  • 48
Harry_CL
  • 51
  • 1

0 Answers0