STM32F302R8 with Konrad's inverter boards for senior design.

Dependencies:   mbed

Fork of Blue_Board_Ticker by Brad VanderWilp

Committer:
vicyap
Date:
Fri Apr 15 22:09:41 2016 +0000
Revision:
21:2bf65c29a3c6
Parent:
20:029a58eb24ab
Child:
22:72905102b50d
refactoring: renamed functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
BVanderWilp 0:d445abf9a8e9 1 #include "mbed.h"
BVanderWilp 0:d445abf9a8e9 2
BVanderWilp 1:69c06d3676fd 3 PwmOut phaseA(PA_8); //Out1, Green
BVanderWilp 0:d445abf9a8e9 4 DigitalOut phaseAEN(PC_10);
BVanderWilp 1:69c06d3676fd 5 PwmOut phaseB(PA_9); //Out2, Blue
BVanderWilp 0:d445abf9a8e9 6 DigitalOut phaseBEN(PC_11);
BVanderWilp 1:69c06d3676fd 7 PwmOut phaseC(PA_10); //Out3, White
BVanderWilp 0:d445abf9a8e9 8 DigitalOut phaseCEN(PC_12);
BVanderWilp 0:d445abf9a8e9 9
BVanderWilp 5:6110655353ad 10 AnalogIn pot(PB_1);
BVanderWilp 5:6110655353ad 11
BVanderWilp 0:d445abf9a8e9 12 InterruptIn button(USER_BUTTON);
BVanderWilp 0:d445abf9a8e9 13
BVanderWilp 0:d445abf9a8e9 14 DigitalOut redLed(PB_2);
BVanderWilp 0:d445abf9a8e9 15 DigitalOut led(LED1);
BVanderWilp 1:69c06d3676fd 16 InterruptIn hallA(PA_15); //H1, Green
BVanderWilp 1:69c06d3676fd 17 InterruptIn hallB(PB_3); //H2, Blue
BVanderWilp 1:69c06d3676fd 18 InterruptIn hallC(PB_10); //H3, White
BVanderWilp 0:d445abf9a8e9 19
BVanderWilp 6:e401c592d2c3 20 Ticker rpmInterrupt;
vicyap 12:d34b96d7f997 21 Ticker spinTicker;
BVanderWilp 6:e401c592d2c3 22 int revCount = 0;
BVanderWilp 6:e401c592d2c3 23 int rpmPrintFlag = 0;
BVanderWilp 6:e401c592d2c3 24 int currentRPM;
BVanderWilp 0:d445abf9a8e9 25
vicyap 20:029a58eb24ab 26 int ADCCountMax = 1000; // tune for responsiveness vs. stability, higher value -> less responsive -> more stable
vicyap 20:029a58eb24ab 27 float pwmMax = 0.9; // tune for max pwmDuty. higher value -> more power available
BVanderWilp 5:6110655353ad 28 float pwmDuty;
BVanderWilp 0:d445abf9a8e9 29 int stall = 0;
BVanderWilp 7:9d90184335aa 30 int reverse = 0;
BVanderWilp 6:e401c592d2c3 31
vicyap 19:085eb0579185 32 int spinTickerCounter = 0;
vicyap 20:029a58eb24ab 33 int spinTickerPeriod_us = 50; // tune for how often hall sensors are checked
vicyap 19:085eb0579185 34 int ticksPerHall = 0;
vicyap 19:085eb0579185 35 int prevHallState = 0;
vicyap 19:085eb0579185 36
vicyap 21:2bf65c29a3c6 37 float reverseThreshold = 0.4f; // tune for minimum duty cycle to allow reverse
vicyap 21:2bf65c29a3c6 38
vicyap 20:029a58eb24ab 39 int pole_pairs = 2; // tune for proper mech rpm calculation
vicyap 19:085eb0579185 40
vicyap 21:2bf65c29a3c6 41 void init()
vicyap 21:2bf65c29a3c6 42 {
vicyap 21:2bf65c29a3c6 43 phaseA.period_us(50);
vicyap 21:2bf65c29a3c6 44 phaseB.period_us(50);
vicyap 21:2bf65c29a3c6 45 phaseC.period_us(50);
vicyap 21:2bf65c29a3c6 46
vicyap 21:2bf65c29a3c6 47 phaseA.write(0);
vicyap 21:2bf65c29a3c6 48 phaseB.write(0);
vicyap 21:2bf65c29a3c6 49 phaseC.write(0);
vicyap 21:2bf65c29a3c6 50
vicyap 21:2bf65c29a3c6 51 phaseAEN = 0;
vicyap 21:2bf65c29a3c6 52 phaseBEN = 0;
vicyap 21:2bf65c29a3c6 53 phaseCEN = 0;
vicyap 21:2bf65c29a3c6 54
vicyap 21:2bf65c29a3c6 55 // init the prevHallState
vicyap 21:2bf65c29a3c6 56 int h1 = hallA.read();
vicyap 21:2bf65c29a3c6 57 int h2 = hallB.read();
vicyap 21:2bf65c29a3c6 58 int h3 = hallC.read();
vicyap 21:2bf65c29a3c6 59 prevHallState = (h1 << 2) + (h2 << 1) + h3;
vicyap 21:2bf65c29a3c6 60 }
vicyap 21:2bf65c29a3c6 61
BVanderWilp 6:e401c592d2c3 62 void rpmCalc()
BVanderWilp 6:e401c592d2c3 63 {
vicyap 19:085eb0579185 64 currentRPM = revCount * 60; // 60 seconds in 1 minute
vicyap 19:085eb0579185 65 currentRPM /= pole_pairs; // account for elec vs mech rpm
vicyap 21:2bf65c29a3c6 66 if (reverse == 1)
vicyap 21:2bf65c29a3c6 67 {
vicyap 21:2bf65c29a3c6 68 currentRPM = -currentRPM; // indicate a reverse direction
vicyap 21:2bf65c29a3c6 69 }
BVanderWilp 6:e401c592d2c3 70 revCount = 0;
BVanderWilp 6:e401c592d2c3 71 rpmPrintFlag = 1;
BVanderWilp 6:e401c592d2c3 72 }
vicyap 21:2bf65c29a3c6 73
BVanderWilp 9:af60c737a93e 74 //original names: CBA CBA, new names: BAC BAC
vicyap 21:2bf65c29a3c6 75 void Output_ANull_BLow_CHigh() //state1, A0 B- C+
vicyap 15:dddb511c39b4 76 {
vicyap 17:5e27edd3d8e6 77 phaseA.write(0);
vicyap 17:5e27edd3d8e6 78 phaseB.write(0);
vicyap 17:5e27edd3d8e6 79 phaseC.write(pwmDuty);
BVanderWilp 0:d445abf9a8e9 80 phaseAEN = 0;
BVanderWilp 1:69c06d3676fd 81 phaseBEN = 1;
BVanderWilp 3:2bcc36fe4de5 82 phaseCEN = 1;
BVanderWilp 1:69c06d3676fd 83 }
BVanderWilp 1:69c06d3676fd 84
vicyap 21:2bf65c29a3c6 85 void Output_AHigh_BLow_CNull() //state2, A+ B- C0
BVanderWilp 1:69c06d3676fd 86 {
vicyap 17:5e27edd3d8e6 87 phaseA.write(pwmDuty);
vicyap 17:5e27edd3d8e6 88 phaseB.write(0);
BVanderWilp 1:69c06d3676fd 89 phaseC.write(0);
BVanderWilp 1:69c06d3676fd 90 phaseAEN = 1;
BVanderWilp 3:2bcc36fe4de5 91 phaseBEN = 1;
vicyap 17:5e27edd3d8e6 92 phaseCEN = 0;
BVanderWilp 1:69c06d3676fd 93 }
BVanderWilp 1:69c06d3676fd 94
vicyap 21:2bf65c29a3c6 95 void Output_AHigh_BNull_CLow() //state3, A+ B0 C-
BVanderWilp 1:69c06d3676fd 96 {
vicyap 17:5e27edd3d8e6 97 phaseA.write(pwmDuty);
vicyap 17:5e27edd3d8e6 98 phaseB.write(0);
vicyap 17:5e27edd3d8e6 99 phaseC.write(0);
vicyap 17:5e27edd3d8e6 100 phaseAEN = 1;
BVanderWilp 1:69c06d3676fd 101 phaseBEN = 0;
BVanderWilp 1:69c06d3676fd 102 phaseCEN = 1;
BVanderWilp 1:69c06d3676fd 103 }
BVanderWilp 1:69c06d3676fd 104
vicyap 21:2bf65c29a3c6 105 void Output_ANull_BHigh_CLow() //state4, A0 B+ C-
BVanderWilp 1:69c06d3676fd 106 {
BVanderWilp 0:d445abf9a8e9 107 phaseA.write(0);
BVanderWilp 0:d445abf9a8e9 108 phaseB.write(pwmDuty);
vicyap 17:5e27edd3d8e6 109 phaseC.write(0);
vicyap 17:5e27edd3d8e6 110 phaseAEN = 0;
BVanderWilp 0:d445abf9a8e9 111 phaseBEN = 1;
BVanderWilp 3:2bcc36fe4de5 112 phaseCEN = 1;
BVanderWilp 0:d445abf9a8e9 113 }
BVanderWilp 0:d445abf9a8e9 114
vicyap 21:2bf65c29a3c6 115 void Output_ALow_BHigh_CNull() //state5, A- B+ C0
BVanderWilp 0:d445abf9a8e9 116 {
vicyap 17:5e27edd3d8e6 117 phaseA.write(0);
vicyap 17:5e27edd3d8e6 118 phaseB.write(pwmDuty);
vicyap 17:5e27edd3d8e6 119 phaseC.write(0);
BVanderWilp 0:d445abf9a8e9 120 phaseAEN = 1;
vicyap 17:5e27edd3d8e6 121 phaseCEN = 0;
BVanderWilp 3:2bcc36fe4de5 122 phaseBEN = 1;
BVanderWilp 0:d445abf9a8e9 123 }
BVanderWilp 0:d445abf9a8e9 124
vicyap 21:2bf65c29a3c6 125 void Output_ALow_BNull_CHigh() //state6, A- B0 C+
BVanderWilp 0:d445abf9a8e9 126 {
vicyap 17:5e27edd3d8e6 127 phaseAEN = 1;
BVanderWilp 0:d445abf9a8e9 128 phaseBEN = 0;
vicyap 17:5e27edd3d8e6 129 phaseCEN = 1;
vicyap 17:5e27edd3d8e6 130 phaseA.write(0);
BVanderWilp 0:d445abf9a8e9 131 phaseB.write(0);
BVanderWilp 0:d445abf9a8e9 132 phaseC.write(pwmDuty);
BVanderWilp 0:d445abf9a8e9 133 }
BVanderWilp 0:d445abf9a8e9 134
vicyap 14:0f50e85bd463 135 void toggleRedLed()
vicyap 14:0f50e85bd463 136 {
vicyap 15:dddb511c39b4 137 redLed = !redLed;
vicyap 14:0f50e85bd463 138 }
BVanderWilp 0:d445abf9a8e9 139
vicyap 21:2bf65c29a3c6 140 void SixStepNext()
BVanderWilp 7:9d90184335aa 141 {
BVanderWilp 3:2bcc36fe4de5 142 int h1 = hallA.read();
BVanderWilp 3:2bcc36fe4de5 143 int h2 = hallB.read();
BVanderWilp 3:2bcc36fe4de5 144 int h3 = hallC.read();
BVanderWilp 3:2bcc36fe4de5 145 //check where we start
vicyap 19:085eb0579185 146 int currentHallState = (h1 << 2) + (h2 << 1) + h3;
vicyap 19:085eb0579185 147 if (currentHallState != prevHallState)
vicyap 19:085eb0579185 148 {
vicyap 19:085eb0579185 149 ticksPerHall = spinTickerCounter;
vicyap 19:085eb0579185 150 spinTickerCounter = 0; // reset the number of ticks per hall sensor change
vicyap 19:085eb0579185 151 if (prevHallState == 1) // arbitrarily choose state 1
vicyap 19:085eb0579185 152 {
vicyap 19:085eb0579185 153 revCount += 1;
vicyap 19:085eb0579185 154 }
vicyap 19:085eb0579185 155 }
vicyap 19:085eb0579185 156 prevHallState = currentHallState;
vicyap 19:085eb0579185 157 spinTickerCounter += 1; // count the number of times spinTicker runs per hall sensor
vicyap 16:792055c232a5 158
vicyap 16:792055c232a5 159 if (reverse == 0)
vicyap 16:792055c232a5 160 {
vicyap 16:792055c232a5 161 if(h1 == 0 && h2 == 1 && h3 == 1) { //state1
vicyap 21:2bf65c29a3c6 162 Output_AHigh_BLow_CNull();
vicyap 16:792055c232a5 163 } else if(h1 == 0 && h2 == 0 && h3 == 1) { //state2
vicyap 21:2bf65c29a3c6 164 Output_AHigh_BNull_CLow();
vicyap 16:792055c232a5 165 } else if(h1 == 1 && h2 == 0 && h3 == 1) { //state3
vicyap 21:2bf65c29a3c6 166 Output_ANull_BHigh_CLow();
vicyap 16:792055c232a5 167 } else if(h1 == 1 && h2 == 0 && h3 == 0) { //state4
vicyap 21:2bf65c29a3c6 168 Output_ALow_BHigh_CNull();
vicyap 16:792055c232a5 169 } else if(h1 == 1 && h2 == 1 && h3 == 0) { //state5
vicyap 21:2bf65c29a3c6 170 Output_ALow_BNull_CHigh();
vicyap 21:2bf65c29a3c6 171 } else if (h1 == 0 && h2 == 1 && h3 == 0) { //state6
vicyap 21:2bf65c29a3c6 172 Output_ANull_BLow_CHigh();
vicyap 16:792055c232a5 173 }
vicyap 16:792055c232a5 174 }
vicyap 18:d7033a38f20b 175 else if (reverse == 1) // to go in reverse, shift the mappings by 180 degrees
vicyap 16:792055c232a5 176 {
vicyap 16:792055c232a5 177 if(h1 == 0 && h2 == 1 && h3 == 1) { //state1
vicyap 21:2bf65c29a3c6 178 Output_ALow_BHigh_CNull();
vicyap 18:d7033a38f20b 179 } else if(h1 == 0 && h2 == 0 && h3 == 1) { //state2
vicyap 21:2bf65c29a3c6 180 Output_ALow_BNull_CHigh();
vicyap 18:d7033a38f20b 181 } else if(h1 == 1 && h2 == 0 && h3 == 1) { //state3
vicyap 21:2bf65c29a3c6 182 Output_ANull_BLow_CHigh();
vicyap 18:d7033a38f20b 183 } else if(h1 == 1 && h2 == 0 && h3 == 0) { //state4
vicyap 21:2bf65c29a3c6 184 Output_AHigh_BLow_CNull();
vicyap 18:d7033a38f20b 185 } else if(h1 == 1 && h2 == 1 && h3 == 0) { //state5
vicyap 21:2bf65c29a3c6 186 Output_AHigh_BNull_CLow();
vicyap 21:2bf65c29a3c6 187 } else if (h1 == 0 && h2 == 1 && h3 == 0) { //state6
vicyap 21:2bf65c29a3c6 188 Output_ANull_BHigh_CLow();
vicyap 16:792055c232a5 189 }
vicyap 14:0f50e85bd463 190 }
vicyap 14:0f50e85bd463 191 toggleRedLed();
BVanderWilp 7:9d90184335aa 192 }
BVanderWilp 7:9d90184335aa 193
vicyap 21:2bf65c29a3c6 194 void user_button_callback()
BVanderWilp 7:9d90184335aa 195 {
vicyap 21:2bf65c29a3c6 196 if(stall == 0)
vicyap 21:2bf65c29a3c6 197 {
BVanderWilp 7:9d90184335aa 198 stall = 1;
vicyap 21:2bf65c29a3c6 199 }
vicyap 21:2bf65c29a3c6 200 else
vicyap 21:2bf65c29a3c6 201 {
vicyap 21:2bf65c29a3c6 202 if (pwmDuty < reverseThreshold)
vicyap 16:792055c232a5 203 {
vicyap 16:792055c232a5 204 reverse = reverse ^ 1;
vicyap 16:792055c232a5 205 }
BVanderWilp 7:9d90184335aa 206 }
BVanderWilp 7:9d90184335aa 207 }
BVanderWilp 7:9d90184335aa 208
vicyap 15:dddb511c39b4 209 int main()
vicyap 15:dddb511c39b4 210 {
BVanderWilp 7:9d90184335aa 211 //wait until button push to start
BVanderWilp 7:9d90184335aa 212 rpmInterrupt.attach(&rpmCalc, 1);
vicyap 21:2bf65c29a3c6 213 button.rise(&user_button_callback);
BVanderWilp 7:9d90184335aa 214 while(stall == 0) {
BVanderWilp 7:9d90184335aa 215 led = !led;
BVanderWilp 7:9d90184335aa 216 wait(1);
BVanderWilp 7:9d90184335aa 217 }
vicyap 21:2bf65c29a3c6 218
vicyap 21:2bf65c29a3c6 219 init();
vicyap 15:dddb511c39b4 220
vicyap 21:2bf65c29a3c6 221 spinTicker.attach_us(&SixStepNext, spinTickerPeriod_us);
vicyap 16:792055c232a5 222 float ADCSum = 0;
BVanderWilp 5:6110655353ad 223 int ADCCount = 0;
BVanderWilp 0:d445abf9a8e9 224 while(1) {
BVanderWilp 0:d445abf9a8e9 225 led = !led;
vicyap 20:029a58eb24ab 226 if(ADCCount == ADCCountMax) {
vicyap 20:029a58eb24ab 227 ADCSum = ADCSum - (ADCSum / ADCCountMax);
vicyap 20:029a58eb24ab 228 ADCSum += pot.read();
vicyap 20:029a58eb24ab 229 pwmDuty = (ADCSum/ADCCountMax) * pwmMax;
vicyap 20:029a58eb24ab 230 }
vicyap 20:029a58eb24ab 231 else
vicyap 20:029a58eb24ab 232 {
vicyap 20:029a58eb24ab 233 ADCSum += pot.read();
vicyap 20:029a58eb24ab 234 ADCCount++;
BVanderWilp 5:6110655353ad 235 }
vicyap 15:dddb511c39b4 236 if(rpmPrintFlag == 1) {
vicyap 19:085eb0579185 237 printf("%d rpm; %f duty; reverse: %d; ticksPerHall = %d\r\n", currentRPM, pwmDuty, reverse, ticksPerHall);
BVanderWilp 6:e401c592d2c3 238 rpmPrintFlag = 0;
BVanderWilp 6:e401c592d2c3 239 }
BVanderWilp 0:d445abf9a8e9 240 }
BVanderWilp 0:d445abf9a8e9 241 }