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:
tbjazic
Date:
Sun May 24 06:46:25 2015 +0000
Revision:
1:786897114846
Parent:
0:5602fba2a7f7
Child:
3:a4b4a8e3f2a0
InterruptIn pins added instead of DigitalOut pins for Hall sensors, some changes in variables and function names, added adjustDutyCycle member function. Commutation function still needs to be fixed.

Who changed what in which revision?

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