Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Committer:
pspatel321
Date:
Sat Feb 07 08:54:51 2015 +0000
Revision:
38:8efacce315ae
Parent:
36:0afc0fc8f86b
Updated with profiles, operating info, etc. Just like the other programs.  Awaiting test in car.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 30:91af74a299e1 1 #include "DC_DC.h"
pspatel321 30:91af74a299e1 2 #include <math.h>
pspatel321 30:91af74a299e1 3
pspatel321 36:0afc0fc8f86b 4 #define TURN_OFF dcdcControl = 1; isControlPinOn = false;
pspatel321 36:0afc0fc8f86b 5 #define TURN_ON dcdcControl = 0; isControlPinOn = true;
pspatel321 30:91af74a299e1 6
pspatel321 38:8efacce315ae 7 const float CURRENT_MULTIPLIER_DEFAULT = 41.35338345864663; // Full scale amps
pspatel321 38:8efacce315ae 8 const float CURRENT_OFFSET_DEFAULT = 0.0909090909090909; // Float adc reading for 0 amps
pspatel321 30:91af74a299e1 9
pspatel321 38:8efacce315ae 10 const float CURRENT_SENSOR_LLIM = -1.0; // Lowest allowable reading before declaring sensor broken
pspatel321 38:8efacce315ae 11 const float CURRENT_SENSOR_ULIM = 33; // Sensor is at 5V rail, broken
pspatel321 30:91af74a299e1 12
pspatel321 38:8efacce315ae 13 DC_DC::DC_DC(PinName _dcdcPin, PinName _dcdcCurrent, PinName _fan1, PinName _fan2, PinName _pump1, PinName _pump2, float period, float slew, unsigned int size) :
pspatel321 36:0afc0fc8f86b 14 dcdcControl(_dcdcPin, 1), dcdcCurrent(_dcdcCurrent), fan1(_fan1, period, slew), fan2(_fan2, period, slew), pump1(_pump1, period, slew), pump2(_pump2, period, slew)
pspatel321 36:0afc0fc8f86b 15 {
pspatel321 36:0afc0fc8f86b 16 TURN_OFF
pspatel321 30:91af74a299e1 17 currentOffset = CURRENT_OFFSET_DEFAULT;
pspatel321 30:91af74a299e1 18 buffTracker = 0;
pspatel321 30:91af74a299e1 19 wait_ms(10); // Make sure Hall effect IC is ready
pspatel321 30:91af74a299e1 20 startTimer.reset();
pspatel321 30:91af74a299e1 21 stopTimer.reset();
pspatel321 30:91af74a299e1 22 status=0;
pspatel321 38:8efacce315ae 23 _size = 0;
pspatel321 38:8efacce315ae 24 onThreshold = 0;
pspatel321 38:8efacce315ae 25 startDelay = 0;
pspatel321 38:8efacce315ae 26 stopDelay = 0;
pspatel321 38:8efacce315ae 27 overCurrent = 0;
pspatel321 38:8efacce315ae 28
pspatel321 38:8efacce315ae 29 filterBuff = new float[size];
pspatel321 38:8efacce315ae 30 if (filterBuff == 0) {
pspatel321 38:8efacce315ae 31 error("DC-DC failed to allocate memory");
pspatel321 38:8efacce315ae 32 }
pspatel321 38:8efacce315ae 33 _size = size;
pspatel321 30:91af74a299e1 34
pspatel321 30:91af74a299e1 35 // Fill up the buffer
pspatel321 38:8efacce315ae 36 for (int i = 0; i < _size; i++) {
pspatel321 30:91af74a299e1 37 filterBuff[i] = (dcdcCurrent - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
pspatel321 36:0afc0fc8f86b 38 wait_ms(10);
pspatel321 30:91af74a299e1 39 }
pspatel321 36:0afc0fc8f86b 40
pspatel321 38:8efacce315ae 41 // Compute the zero
pspatel321 38:8efacce315ae 42 currentOffset = (current / CURRENT_MULTIPLIER_DEFAULT) + CURRENT_OFFSET_DEFAULT;
pspatel321 36:0afc0fc8f86b 43
pspatel321 36:0afc0fc8f86b 44 // Correct the buffer for the new zero
pspatel321 38:8efacce315ae 45 for (int i = 0; i < _size; i++) {
pspatel321 36:0afc0fc8f86b 46 filterBuff[i] = ((CURRENT_OFFSET_DEFAULT - currentOffset) * CURRENT_MULTIPLIER_DEFAULT) + filterBuff[i];
pspatel321 36:0afc0fc8f86b 47 }
pspatel321 30:91af74a299e1 48 }
pspatel321 30:91af74a299e1 49
pspatel321 38:8efacce315ae 50 void DC_DC::setup(float* _onThreshold, float* _overCurrent, float* _startDelay, float* _stopDelay) {
pspatel321 38:8efacce315ae 51 onThreshold = _onThreshold;
pspatel321 38:8efacce315ae 52 overCurrent = _overCurrent;
pspatel321 38:8efacce315ae 53 startDelay = _startDelay;
pspatel321 38:8efacce315ae 54 startDelay = _startDelay;
pspatel321 38:8efacce315ae 55 }
pspatel321 38:8efacce315ae 56
pspatel321 38:8efacce315ae 57 bool DC_DC::size(unsigned int size) {
pspatel321 38:8efacce315ae 58 if (_size == size) return false;
pspatel321 38:8efacce315ae 59
pspatel321 38:8efacce315ae 60 // Get recent
pspatel321 38:8efacce315ae 61 updateCurrent();
pspatel321 38:8efacce315ae 62 float avg = getCurrent();
pspatel321 38:8efacce315ae 63
pspatel321 38:8efacce315ae 64 // Allocate new
pspatel321 38:8efacce315ae 65 float* newBuff = new float[size];
pspatel321 38:8efacce315ae 66 if (newBuff == 0) return false; // Not found, nothing has been changed
pspatel321 38:8efacce315ae 67 else {
pspatel321 38:8efacce315ae 68 delete[] filterBuff; // Free old
pspatel321 38:8efacce315ae 69 __disable_irq();
pspatel321 38:8efacce315ae 70
pspatel321 38:8efacce315ae 71 _size = size; // Set size
pspatel321 38:8efacce315ae 72 filterBuff = newBuff; // Transfer to new
pspatel321 38:8efacce315ae 73 for (int i = 0; i < size; i++) filterBuff[i] = avg; // Pre-fill with old average
pspatel321 38:8efacce315ae 74
pspatel321 38:8efacce315ae 75 __enable_irq();
pspatel321 38:8efacce315ae 76 return true;
pspatel321 38:8efacce315ae 77 }
pspatel321 38:8efacce315ae 78 }
pspatel321 36:0afc0fc8f86b 79 void DC_DC::updateCurrent()
pspatel321 36:0afc0fc8f86b 80 {
pspatel321 30:91af74a299e1 81 float avg=0;
pspatel321 38:8efacce315ae 82 for (int i = 0; i < _size; i++) {
pspatel321 30:91af74a299e1 83 avg += filterBuff[i];
pspatel321 30:91af74a299e1 84 }
pspatel321 38:8efacce315ae 85 avg /= _size;
pspatel321 30:91af74a299e1 86 current = avg;
pspatel321 30:91af74a299e1 87 }
pspatel321 30:91af74a299e1 88
pspatel321 36:0afc0fc8f86b 89 void DC_DC::set(bool on)
pspatel321 36:0afc0fc8f86b 90 {
pspatel321 38:8efacce315ae 91 if (onThreshold == 0) return; // Not setup yet
pspatel321 38:8efacce315ae 92
pspatel321 30:91af74a299e1 93 // Do nothing if already on
pspatel321 36:0afc0fc8f86b 94 if (on && isControlPinOn) return;
pspatel321 30:91af74a299e1 95
pspatel321 38:8efacce315ae 96 // Double check if already off
pspatel321 38:8efacce315ae 97 if (!on && !isControlPinOn) {
pspatel321 38:8efacce315ae 98 fan1.directOff();
pspatel321 38:8efacce315ae 99 fan2.directOff();
pspatel321 38:8efacce315ae 100 pump1.directOff();
pspatel321 38:8efacce315ae 101 pump2.directOff();
pspatel321 38:8efacce315ae 102 TURN_OFF
pspatel321 38:8efacce315ae 103 }
pspatel321 36:0afc0fc8f86b 104
pspatel321 34:18bcf276d3bf 105 // If start requested and no error
pspatel321 38:8efacce315ae 106 if (on && !critError && !(status & POWER_DOWN)) {
pspatel321 38:8efacce315ae 107 status |= POWER_UP;
pspatel321 38:8efacce315ae 108 status &= ~POWER_DOWN;
pspatel321 36:0afc0fc8f86b 109 TURN_ON
pspatel321 30:91af74a299e1 110 startTimer.reset();
pspatel321 30:91af74a299e1 111 startTimer.start();
pspatel321 30:91af74a299e1 112 stopTimer.stop();
pspatel321 30:91af74a299e1 113 stopTimer.reset();
pspatel321 36:0afc0fc8f86b 114
pspatel321 38:8efacce315ae 115 // If stop requested
pspatel321 30:91af74a299e1 116 } else {
pspatel321 38:8efacce315ae 117 status &= ~POWER_UP;
pspatel321 38:8efacce315ae 118 status |= POWER_DOWN;
pspatel321 30:91af74a299e1 119 fan1.directOff();
pspatel321 30:91af74a299e1 120 fan2.directOff();
pspatel321 30:91af74a299e1 121 pump1.directOff();
pspatel321 30:91af74a299e1 122 pump2.directOff();
pspatel321 36:0afc0fc8f86b 123 TURN_OFF
pspatel321 30:91af74a299e1 124 stopTimer.reset();
pspatel321 30:91af74a299e1 125 stopTimer.start();
pspatel321 30:91af74a299e1 126 startTimer.stop();
pspatel321 30:91af74a299e1 127 startTimer.reset();
pspatel321 30:91af74a299e1 128 }
pspatel321 30:91af74a299e1 129 }
pspatel321 30:91af74a299e1 130
pspatel321 36:0afc0fc8f86b 131 void DC_DC::sample()
pspatel321 36:0afc0fc8f86b 132 {
pspatel321 30:91af74a299e1 133 // Get next current sample
pspatel321 36:0afc0fc8f86b 134 float curr = (dcdcCurrent.read() - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
pspatel321 36:0afc0fc8f86b 135
pspatel321 38:8efacce315ae 136 filterBuff[buffTracker++] = curr; // Add to buffer filter
pspatel321 38:8efacce315ae 137 buffTracker %= _size;
pspatel321 36:0afc0fc8f86b 138 updateCurrent(); // Compute average
pspatel321 30:91af74a299e1 139
pspatel321 38:8efacce315ae 140 if (onThreshold == 0) return; // Not setup yet
pspatel321 38:8efacce315ae 141
pspatel321 30:91af74a299e1 142 // Update status
pspatel321 38:8efacce315ae 143 char stat = 0;
pspatel321 38:8efacce315ae 144 if (current >= *onThreshold) stat |= CONV_ON; // The converter is actually on (positive current)
pspatel321 38:8efacce315ae 145 if (isControlPinOn) stat |= SET_ON; // The converter is set on
pspatel321 36:0afc0fc8f86b 146
pspatel321 30:91af74a299e1 147 // During Timed Startup Phase
pspatel321 38:8efacce315ae 148 if (stat & POWER_UP) {
pspatel321 38:8efacce315ae 149 if (startTimer.read() >= *startDelay) { // Start time elapsed
pspatel321 38:8efacce315ae 150 if (stat & CONV_ON) { // Positive current detected
pspatel321 38:8efacce315ae 151 startTimer.stop(); // Stop timer
pspatel321 30:91af74a299e1 152 startTimer.reset();
pspatel321 38:8efacce315ae 153 stat &= ~POWER_UP; // Done power-up
pspatel321 30:91af74a299e1 154 }
pspatel321 30:91af74a299e1 155 }
pspatel321 38:8efacce315ae 156 }
pspatel321 36:0afc0fc8f86b 157
pspatel321 30:91af74a299e1 158 // During Timed Stopping Phase
pspatel321 38:8efacce315ae 159 if (stat & POWER_DOWN) {
pspatel321 38:8efacce315ae 160 if (stopTimer.read() >= *stopDelay) { // Stop time elapsed
pspatel321 38:8efacce315ae 161 if (!(stat & CONV_ON)) { // Current dropped, its off
pspatel321 38:8efacce315ae 162 stopTimer.stop(); // Stop timer
pspatel321 30:91af74a299e1 163 stopTimer.reset();
pspatel321 38:8efacce315ae 164 stat &= ~POWER_DOWN; // Done power-down
pspatel321 30:91af74a299e1 165 }
pspatel321 30:91af74a299e1 166 }
pspatel321 30:91af74a299e1 167 }
pspatel321 30:91af74a299e1 168
pspatel321 38:8efacce315ae 169 if (current < CURRENT_SENSOR_LLIM || current > CURRENT_SENSOR_ULIM) stat |= SENSOR_FAULT; // Sensor out of range
pspatel321 38:8efacce315ae 170 else if (current > *overCurrent) stat |= OVER_CURRENT; // Over current
pspatel321 36:0afc0fc8f86b 171
pspatel321 30:91af74a299e1 172 // Process critical error conditions
pspatel321 38:8efacce315ae 173 if (stat & (SENSOR_FAULT | OVER_CURRENT)) critError = true;
pspatel321 30:91af74a299e1 174 else critError = false;
pspatel321 30:91af74a299e1 175 status = stat;
pspatel321 30:91af74a299e1 176
pspatel321 30:91af74a299e1 177 // Arrest error, all channels off, DC-DC off
pspatel321 30:91af74a299e1 178 if (critError) {
pspatel321 30:91af74a299e1 179 fan1.directOff();
pspatel321 30:91af74a299e1 180 fan2.directOff();
pspatel321 30:91af74a299e1 181 pump1.directOff();
pspatel321 30:91af74a299e1 182 pump2.directOff();
pspatel321 36:0afc0fc8f86b 183 TURN_OFF
pspatel321 30:91af74a299e1 184 startTimer.stop();
pspatel321 30:91af74a299e1 185 startTimer.reset();
pspatel321 38:8efacce315ae 186 }
pspatel321 38:8efacce315ae 187
pspatel321 38:8efacce315ae 188 // Don't allow to run if still powering on or off
pspatel321 38:8efacce315ae 189 if (stat & (POWER_UP | POWER_DOWN)) {
pspatel321 38:8efacce315ae 190 fan1.directOff();
pspatel321 38:8efacce315ae 191 fan2.directOff();
pspatel321 38:8efacce315ae 192 pump1.directOff();
pspatel321 38:8efacce315ae 193 pump2.directOff();
pspatel321 30:91af74a299e1 194 }
pspatel321 30:91af74a299e1 195 }
pspatel321 30:91af74a299e1 196
pspatel321 36:0afc0fc8f86b 197 void DC_DC::setPwm(enum Channel_T chan, float duty)
pspatel321 36:0afc0fc8f86b 198 {
pspatel321 38:8efacce315ae 199 // Off if error present, starting in startup, or DC-DC not actually on, or not set on
pspatel321 38:8efacce315ae 200 if (!onThreshold || critError || !(status & CONV_ON) || !isControlPinOn || (status & (POWER_UP | POWER_DOWN))) {
pspatel321 38:8efacce315ae 201 fan1.directOff();
pspatel321 38:8efacce315ae 202 fan2.directOff();
pspatel321 38:8efacce315ae 203 pump1.directOff();
pspatel321 38:8efacce315ae 204 pump2.directOff();
pspatel321 38:8efacce315ae 205 } else {
pspatel321 34:18bcf276d3bf 206 if (chan == FAN1) fan1.write(duty);
pspatel321 34:18bcf276d3bf 207 if (chan == FAN2) fan2.write(duty);
pspatel321 30:91af74a299e1 208 if (chan == PUMP1) pump1.write(duty);
pspatel321 36:0afc0fc8f86b 209 if (chan == PUMP2) pump2.write(duty);
pspatel321 30:91af74a299e1 210 }
pspatel321 30:91af74a299e1 211 }
pspatel321 36:0afc0fc8f86b 212 float DC_DC::readPwm(enum Channel_T chan)
pspatel321 36:0afc0fc8f86b 213 {
pspatel321 38:8efacce315ae 214 if (chan == FAN1) return fan1.readRaw();
pspatel321 38:8efacce315ae 215 if (chan == FAN2) return fan2.readRaw();
pspatel321 38:8efacce315ae 216 if (chan == PUMP1) return pump1.readRaw();
pspatel321 38:8efacce315ae 217 if (chan == PUMP2) return pump2.readRaw();
pspatel321 30:91af74a299e1 218 else return 0;
pspatel321 30:91af74a299e1 219 }