Library for driving a 3-phase brushless DC motor.

Dependents:   BLDC_mainProgram STMF302R8_MotorDrive HelloWorld_IHM07M1

BLDCmotorDriver

Introduction

This library is still being developed.

This is a Wiki page about BLDCmotorDriver library developed by TVZ Mechatronics Team. The library is part of our project of creating an e-bike which is supposed to drive/run a 3-phase brushless DC motor with Hall sensors.

We are testing our library on NXP mbed LPC1768 platform and driver DRV8301 from Texas Instruments to run our testing BLDC motor. Next step of our project is creating a standalone library for DRV8301.

Hall sensors

In our BLDC motors there are three Hall sensors located 120 degrees from one another, they are identified as InterruptIn/DigitalIn on mbed and they send zeros and ones on TeraTerm with we locate in which sector

Na našim testnim BLDC motorima postoje 3 halova senzora, koji su udaljeni za 120 stupnjeva jedan od drugoga te inicijaliziranjem svakog pojedinog kao InterruptIn/DigitalIn na pinovima mbeda preko terminala na računalu (TeraTerm) dobivamo prikaz binarnih nula i jedinica koji se slažu sa trobitnim gray-evim kodom, s time da smo kombinacije 000 i 111 definirali kao fault vrijednosti. Pošto se slučajevi kada su sva tri hallova senzora upaljena ili ugašena ne mogu dogoditi tj. ne bi se smijeli dogoditi, ukoliko je došlo do takve situacije dogodio se kvar na hallovim senzorima te bi motor trebao prijeći u mod rada bez hallovih senzora.

With that we got six combinations, which we use to determine six sectors:

  • 001 - Sector 1
  • 011 - Sector 2
  • 010 - Sector 3
  • 110 - Sector 4
  • 100 - Sector 5
  • 101 - Sector 6

Nakon toga odredili smo za sve tri faze stanja mosfeta..

/media/uploads/dfraj/3-bit_gray_code_ring.jpg

Components

/media/uploads/dfraj/kotac.jpg

Committer:
mslovic
Date:
Fri May 22 22:43:39 2015 +0000
Revision:
0:5602fba2a7f7
Child:
1:786897114846
Child:
2:7aae78b85e1d
Library for driving a 3-phase brushless DC motor.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mslovic 0:5602fba2a7f7 1 #include "BLDCmotorDriver.h"
mslovic 0:5602fba2a7f7 2
mslovic 0:5602fba2a7f7 3 BLDCmotorDriver::BLDCmotorDriver(PinName gh_a, PinName gl_a, PinName gh_b, PinName gl_b, PinName gh_c, PinName gl_c, PinName h1, PinName h2, PinName h3, PinName led1) : GH_A(gh_a), GL_A(gl_a), GH_B(gh_b), GL_B(gl_b), GH_C(gh_c), GL_C(gl_c), H1(h1), H2(h2), H3(h3), Led1(led1) {
mslovic 0:5602fba2a7f7 4 sampleTime = 1e-3;
mslovic 0:5602fba2a7f7 5 switchingPeriod = 1.0 / 20e3;
mslovic 0:5602fba2a7f7 6 dutyCycle = tempDutyCycle = 0;
mslovic 0:5602fba2a7f7 7 GH_A.period(switchingPeriod); // applies to all PwmOut instances
mslovic 0:5602fba2a7f7 8 rl.setLimits(0.1, -0.1, 0, sampleTime); // initial 10 second ramp
mslovic 0:5602fba2a7f7 9 }
mslovic 0:5602fba2a7f7 10 void BLDCmotorDriver::configure(float sampleTime, float switchingFrequency, float rampUpSlope, float rampDownSlope) {
mslovic 0:5602fba2a7f7 11 if (sampleTime < 1e-6)
mslovic 0:5602fba2a7f7 12 sampleTime = 1e-3;
mslovic 0:5602fba2a7f7 13 if (switchingFrequency < 100)
mslovic 0:5602fba2a7f7 14 switchingFrequency = 20e3;
mslovic 0:5602fba2a7f7 15 if (rampUpSlope < 0 || rampUpSlope > 1)
mslovic 0:5602fba2a7f7 16 rampUpSlope = 0.1;
mslovic 0:5602fba2a7f7 17 if (rampDownSlope > 0 || rampDownSlope < -1)
mslovic 0:5602fba2a7f7 18 rampDownSlope = -0.1;
mslovic 0:5602fba2a7f7 19 this->sampleTime = sampleTime;
mslovic 0:5602fba2a7f7 20 switchingPeriod = 1.0 / switchingFrequency;
mslovic 0:5602fba2a7f7 21 rl.setLimits(rampUpSlope, rampDownSlope, 0, sampleTime);
mslovic 0:5602fba2a7f7 22 }
mslovic 0:5602fba2a7f7 23 int BLDCmotorDriver::HallRead(){ // hall 120°
mslovic 0:5602fba2a7f7 24
mslovic 0:5602fba2a7f7 25 if(H1.read()== 1 && H2.read()== 0 && H3.read()== 0)
mslovic 0:5602fba2a7f7 26 sektor = 1;
mslovic 0:5602fba2a7f7 27 else if(H1.read()== 1 && H2.read()== 1 && H3.read()== 0)
mslovic 0:5602fba2a7f7 28 sektor = 2;
mslovic 0:5602fba2a7f7 29 else if(H1.read()== 0 && H2.read()== 1 && H3.read()== 0)
mslovic 0:5602fba2a7f7 30 sektor = 3;
mslovic 0:5602fba2a7f7 31 else if(H1.read()== 0 && H2.read()== 1 && H3.read()== 1)
mslovic 0:5602fba2a7f7 32 sektor = 4;
mslovic 0:5602fba2a7f7 33 else if(H1.read()== 0 && H2.read()== 0 && H3.read()== 1)
mslovic 0:5602fba2a7f7 34 sektor = 5;
mslovic 0:5602fba2a7f7 35 else if(H1.read()== 1 && H2.read()== 0 && H3.read()== 1)
mslovic 0:5602fba2a7f7 36 sektor = 6;
mslovic 0:5602fba2a7f7 37 else
mslovic 0:5602fba2a7f7 38 Led1 = 1;
mslovic 0:5602fba2a7f7 39
mslovic 0:5602fba2a7f7 40 return sektor;
mslovic 0:5602fba2a7f7 41 }
mslovic 0:5602fba2a7f7 42 void BLDCmotorDriver::komutacijaBLDC() {
mslovic 0:5602fba2a7f7 43 dutyCycle = rl.out(tempDutyCycle);
mslovic 0:5602fba2a7f7 44 sektor = HallRead();
mslovic 0:5602fba2a7f7 45 if (dutyCycle > 0) {
mslovic 0:5602fba2a7f7 46 if (sektor > 6) sektor = 1;
mslovic 0:5602fba2a7f7 47 sektor++;
mslovic 0:5602fba2a7f7 48 switch(sektor) {
mslovic 0:5602fba2a7f7 49 case 1: //100
mslovic 0:5602fba2a7f7 50 GH_A = dutyCycle;
mslovic 0:5602fba2a7f7 51 GL_A = 0;
mslovic 0:5602fba2a7f7 52 GH_B = 0;
mslovic 0:5602fba2a7f7 53 GL_B = 0;
mslovic 0:5602fba2a7f7 54 GH_C = 0;
mslovic 0:5602fba2a7f7 55 GL_C = 1;
mslovic 0:5602fba2a7f7 56 break;
mslovic 0:5602fba2a7f7 57 case 2: //110
mslovic 0:5602fba2a7f7 58 GH_A = dutyCycle;
mslovic 0:5602fba2a7f7 59 GL_A = 0;
mslovic 0:5602fba2a7f7 60 GH_B = 0;
mslovic 0:5602fba2a7f7 61 GL_B = 1;
mslovic 0:5602fba2a7f7 62 GH_C = 0;
mslovic 0:5602fba2a7f7 63 GL_C = 0;
mslovic 0:5602fba2a7f7 64 break;
mslovic 0:5602fba2a7f7 65 case 3: //010
mslovic 0:5602fba2a7f7 66 GH_A = 0;
mslovic 0:5602fba2a7f7 67 GL_A = 0;
mslovic 0:5602fba2a7f7 68 GH_B = 0;
mslovic 0:5602fba2a7f7 69 GL_B = 1;
mslovic 0:5602fba2a7f7 70 GH_C = dutyCycle;
mslovic 0:5602fba2a7f7 71 GL_C = 0;
mslovic 0:5602fba2a7f7 72 break;
mslovic 0:5602fba2a7f7 73 case 4: //011
mslovic 0:5602fba2a7f7 74 GH_A = 0;
mslovic 0:5602fba2a7f7 75 GL_A = 1;
mslovic 0:5602fba2a7f7 76 GH_B = 0;
mslovic 0:5602fba2a7f7 77 GL_B = 0;
mslovic 0:5602fba2a7f7 78 GH_C = dutyCycle;
mslovic 0:5602fba2a7f7 79 GL_C = 0;
mslovic 0:5602fba2a7f7 80 break;
mslovic 0:5602fba2a7f7 81 case 5: //001
mslovic 0:5602fba2a7f7 82 GH_A = 0;
mslovic 0:5602fba2a7f7 83 GL_A = 1;
mslovic 0:5602fba2a7f7 84 GH_B = dutyCycle;
mslovic 0:5602fba2a7f7 85 GL_B = 0;
mslovic 0:5602fba2a7f7 86 GH_C = 0;
mslovic 0:5602fba2a7f7 87 GL_C = 0;
mslovic 0:5602fba2a7f7 88 break;
mslovic 0:5602fba2a7f7 89 case 6: //101
mslovic 0:5602fba2a7f7 90 GH_A = 0;
mslovic 0:5602fba2a7f7 91 GL_A = 0;
mslovic 0:5602fba2a7f7 92 GH_B = dutyCycle;
mslovic 0:5602fba2a7f7 93 GL_B = 0;
mslovic 0:5602fba2a7f7 94 GH_C = 0;
mslovic 0:5602fba2a7f7 95 GL_C = 1;
mslovic 0:5602fba2a7f7 96 break;
mslovic 0:5602fba2a7f7 97 }
mslovic 0:5602fba2a7f7 98 } else if (dutyCycle < 0) { //
mslovic 0:5602fba2a7f7 99 if (sektor < 1) sektor = 6;
mslovic 0:5602fba2a7f7 100 sektor--;
mslovic 0:5602fba2a7f7 101 switch(sektor) {
mslovic 0:5602fba2a7f7 102 case 1: //100
mslovic 0:5602fba2a7f7 103 GH_A = dutyCycle;
mslovic 0:5602fba2a7f7 104 GL_A = 0;
mslovic 0:5602fba2a7f7 105 GH_B = 0;
mslovic 0:5602fba2a7f7 106 GL_B = 0;
mslovic 0:5602fba2a7f7 107 GH_C = 0;
mslovic 0:5602fba2a7f7 108 GL_C = 1;
mslovic 0:5602fba2a7f7 109 break;
mslovic 0:5602fba2a7f7 110 case 2: //110
mslovic 0:5602fba2a7f7 111 GH_A = dutyCycle;
mslovic 0:5602fba2a7f7 112 GL_A = 0;
mslovic 0:5602fba2a7f7 113 GH_B = 0;
mslovic 0:5602fba2a7f7 114 GL_B = 1;
mslovic 0:5602fba2a7f7 115 GH_C = 0;
mslovic 0:5602fba2a7f7 116 GL_C = 0;
mslovic 0:5602fba2a7f7 117 break;
mslovic 0:5602fba2a7f7 118 case 3: //010
mslovic 0:5602fba2a7f7 119 GH_A = 0;
mslovic 0:5602fba2a7f7 120 GL_A = 0;
mslovic 0:5602fba2a7f7 121 GH_B = 0;
mslovic 0:5602fba2a7f7 122 GL_B = 1;
mslovic 0:5602fba2a7f7 123 GH_C = dutyCycle;
mslovic 0:5602fba2a7f7 124 GL_C = 0;
mslovic 0:5602fba2a7f7 125 break;
mslovic 0:5602fba2a7f7 126 case 4: //011
mslovic 0:5602fba2a7f7 127 GH_A = 0;
mslovic 0:5602fba2a7f7 128 GL_A = 1;
mslovic 0:5602fba2a7f7 129 GH_B = 0;
mslovic 0:5602fba2a7f7 130 GL_B = 0;
mslovic 0:5602fba2a7f7 131 GH_C = dutyCycle;
mslovic 0:5602fba2a7f7 132 GL_C = 0;
mslovic 0:5602fba2a7f7 133 break;
mslovic 0:5602fba2a7f7 134 case 5: //001
mslovic 0:5602fba2a7f7 135 GH_A = 0;
mslovic 0:5602fba2a7f7 136 GL_A = 1;
mslovic 0:5602fba2a7f7 137 GH_B = dutyCycle;
mslovic 0:5602fba2a7f7 138 GL_B = 0;
mslovic 0:5602fba2a7f7 139 GH_C = 0;
mslovic 0:5602fba2a7f7 140 GL_C = 0;
mslovic 0:5602fba2a7f7 141 break;
mslovic 0:5602fba2a7f7 142 case 6: //101
mslovic 0:5602fba2a7f7 143 GH_A = 0;
mslovic 0:5602fba2a7f7 144 GL_A = 0;
mslovic 0:5602fba2a7f7 145 GH_B = dutyCycle;
mslovic 0:5602fba2a7f7 146 GL_B = 0;
mslovic 0:5602fba2a7f7 147 GH_C = 0;
mslovic 0:5602fba2a7f7 148 GL_C = 1;
mslovic 0:5602fba2a7f7 149 break;
mslovic 0:5602fba2a7f7 150 }
mslovic 0:5602fba2a7f7 151 }else {
mslovic 0:5602fba2a7f7 152 coast();
mslovic 0:5602fba2a7f7 153 }
mslovic 0:5602fba2a7f7 154 }
mslovic 0:5602fba2a7f7 155 void BLDCmotorDriver::setDutyCycle(float dc) {
mslovic 0:5602fba2a7f7 156 if (dc >= -1 && dc <= 1) {
mslovic 0:5602fba2a7f7 157 ticker.attach(this, &BLDCmotorDriver::komutacijaBLDC, sampleTime);
mslovic 0:5602fba2a7f7 158 tempDutyCycle = dc;
mslovic 0:5602fba2a7f7 159 } else {
mslovic 0:5602fba2a7f7 160 coast();
mslovic 0:5602fba2a7f7 161 }
mslovic 0:5602fba2a7f7 162 }
mslovic 0:5602fba2a7f7 163 void BLDCmotorDriver::coast() {
mslovic 0:5602fba2a7f7 164 GH_A = 0;
mslovic 0:5602fba2a7f7 165 GL_A = 0;
mslovic 0:5602fba2a7f7 166 GH_B = 0;
mslovic 0:5602fba2a7f7 167 GL_B = 0;
mslovic 0:5602fba2a7f7 168 GH_C = 0;
mslovic 0:5602fba2a7f7 169 GL_C = 0;
mslovic 0:5602fba2a7f7 170 dutyCycle = tempDutyCycle = 0;
mslovic 0:5602fba2a7f7 171 rl.reset();
mslovic 0:5602fba2a7f7 172 ticker.detach();
mslovic 0:5602fba2a7f7 173 }
mslovic 0:5602fba2a7f7 174 float BLDCmotorDriver::getDutyCycle() {
mslovic 0:5602fba2a7f7 175 return dutyCycle;
mslovic 0:5602fba2a7f7 176 }