Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Libs/DC_DC/DC_DC.cpp@38:8efacce315ae, 2015-02-07 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |
