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:
Wed Jan 07 03:25:50 2015 +0000
Revision:
34:18bcf276d3bf
Parent:
30:91af74a299e1
Child:
36:0afc0fc8f86b
Added serial input.  Updated glvBat coulomb counter to match AMS, brought in changes to outDiag and inCommands from AMS.

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 30:91af74a299e1 4 #define OFF 1
pspatel321 30:91af74a299e1 5 #define ON 0
pspatel321 30:91af74a299e1 6
pspatel321 30:91af74a299e1 7 const float CURRENT_MULTIPLIER_DEFAULT = 41.35338345864663; // Full scale amps
pspatel321 30:91af74a299e1 8 const float CURRENT_OFFSET_DEFAULT = 0.0909090909090909; // Float adc reading for 0 amps
pspatel321 30:91af74a299e1 9
pspatel321 30:91af74a299e1 10 const float DC_DC_ON_THRESHOLD = 0.5; // Current draw required in order to declare it as ON
pspatel321 30:91af74a299e1 11 const int STARTUP_DELAY_MS = 500; // DC-DC converter startup time in milliseconds
pspatel321 30:91af74a299e1 12 const float OVER_CURRENT_THRESHOLD = 25; // Overcurrent threshold
pspatel321 30:91af74a299e1 13 const float CURRENT_SENSOR_LLIM = -0.5; // Lowest allowable reading before declaring sensor broken
pspatel321 30:91af74a299e1 14 const int ZEROING_SAMPLES = 50; // Number of samples to average for zeroing
pspatel321 30:91af74a299e1 15 const int STOP_DELAY_MS = 500; // Amount of time given to turn-off before flagging error
pspatel321 30:91af74a299e1 16
pspatel321 30:91af74a299e1 17 DC_DC::DC_DC(PinName _dcdcPin, PinName _dcdcCurrent, PinName _fan1, PinName _fan2, PinName _pump1, PinName _pump2, float period, float slew) :
pspatel321 30:91af74a299e1 18 dcdcControl(_dcdcPin, OFF), dcdcCurrent(_dcdcCurrent), fan1(_fan1, period, slew), fan2(_fan2, period, slew), pump1(_pump1, period, slew), pump2(_pump2, period, slew) {
pspatel321 30:91af74a299e1 19
pspatel321 30:91af74a299e1 20 currentOffset = CURRENT_OFFSET_DEFAULT;
pspatel321 30:91af74a299e1 21 starting = false;
pspatel321 30:91af74a299e1 22 stopping = false;
pspatel321 30:91af74a299e1 23 buffTracker = 0;
pspatel321 30:91af74a299e1 24 wait_ms(10); // Make sure Hall effect IC is ready
pspatel321 30:91af74a299e1 25 startTimer.reset();
pspatel321 30:91af74a299e1 26 stopTimer.reset();
pspatel321 30:91af74a299e1 27 status=0;
pspatel321 30:91af74a299e1 28
pspatel321 30:91af74a299e1 29 // Fill up the buffer
pspatel321 30:91af74a299e1 30 for (int i = 0; i < DC_DC_FILTER_TAPS; i++) {
pspatel321 30:91af74a299e1 31 filterBuff[i] = (dcdcCurrent - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
pspatel321 30:91af74a299e1 32 }
pspatel321 30:91af74a299e1 33 updateCurrent();
pspatel321 30:91af74a299e1 34 sample();
pspatel321 30:91af74a299e1 35 if (!critError) zeroCurrent();
pspatel321 30:91af74a299e1 36 }
pspatel321 30:91af74a299e1 37
pspatel321 30:91af74a299e1 38 void DC_DC::zeroCurrent() {
pspatel321 30:91af74a299e1 39 float avg=0;
pspatel321 30:91af74a299e1 40 for (int i = 0; i < ZEROING_SAMPLES; i++) {
pspatel321 30:91af74a299e1 41 avg+=dcdcCurrent;
pspatel321 30:91af74a299e1 42 wait_ms(1);
pspatel321 30:91af74a299e1 43 }
pspatel321 30:91af74a299e1 44 avg /= ZEROING_SAMPLES;
pspatel321 30:91af74a299e1 45 currentOffset = avg;
pspatel321 30:91af74a299e1 46 }
pspatel321 30:91af74a299e1 47
pspatel321 30:91af74a299e1 48 void DC_DC::updateCurrent() {
pspatel321 30:91af74a299e1 49 float avg=0;
pspatel321 30:91af74a299e1 50 for (int i = 0; i < DC_DC_FILTER_TAPS; i++) {
pspatel321 30:91af74a299e1 51 avg += filterBuff[i];
pspatel321 30:91af74a299e1 52 }
pspatel321 30:91af74a299e1 53 avg /= DC_DC_FILTER_TAPS;
pspatel321 30:91af74a299e1 54 current = avg;
pspatel321 30:91af74a299e1 55 }
pspatel321 30:91af74a299e1 56
pspatel321 30:91af74a299e1 57 void DC_DC::set(bool on) {
pspatel321 30:91af74a299e1 58 // Do nothing if already on
pspatel321 30:91af74a299e1 59 if (on && dcdcControl == ON) return;
pspatel321 30:91af74a299e1 60
pspatel321 34:18bcf276d3bf 61 // If start requested and no error
pspatel321 34:18bcf276d3bf 62 if (on && !critError) {
pspatel321 30:91af74a299e1 63 dcdcControl = ON;
pspatel321 30:91af74a299e1 64 starting = true;
pspatel321 30:91af74a299e1 65 startTimer.reset();
pspatel321 30:91af74a299e1 66 startTimer.start();
pspatel321 30:91af74a299e1 67 stopTimer.stop();
pspatel321 30:91af74a299e1 68 stopTimer.reset();
pspatel321 30:91af74a299e1 69 stopping = false;
pspatel321 34:18bcf276d3bf 70
pspatel321 30:91af74a299e1 71 // If stop requested
pspatel321 30:91af74a299e1 72 } else {
pspatel321 30:91af74a299e1 73 stopping=true;
pspatel321 30:91af74a299e1 74 fan1.directOff();
pspatel321 30:91af74a299e1 75 fan2.directOff();
pspatel321 30:91af74a299e1 76 pump1.directOff();
pspatel321 30:91af74a299e1 77 pump2.directOff();
pspatel321 30:91af74a299e1 78 dcdcControl = OFF;
pspatel321 30:91af74a299e1 79 stopTimer.reset();
pspatel321 30:91af74a299e1 80 stopTimer.start();
pspatel321 30:91af74a299e1 81 startTimer.stop();
pspatel321 30:91af74a299e1 82 startTimer.reset();
pspatel321 30:91af74a299e1 83 starting = false;
pspatel321 30:91af74a299e1 84 }
pspatel321 30:91af74a299e1 85 }
pspatel321 30:91af74a299e1 86
pspatel321 30:91af74a299e1 87 void DC_DC::sample() {
pspatel321 30:91af74a299e1 88
pspatel321 30:91af74a299e1 89 // Get next current sample
pspatel321 30:91af74a299e1 90 float curr = (dcdcCurrent - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
pspatel321 30:91af74a299e1 91 if (curr < CURRENT_SENSOR_LLIM) curr = -INFINITY; // Check if sensor out of range
pspatel321 30:91af74a299e1 92 else if (curr < 0) curr = 0; // Floor to zero
pspatel321 30:91af74a299e1 93 filterBuff[buffTracker] = curr; // Add to buffer filter
pspatel321 30:91af74a299e1 94 buffTracker++;
pspatel321 30:91af74a299e1 95 if (buffTracker >= DC_DC_FILTER_TAPS) buffTracker = 0;
pspatel321 30:91af74a299e1 96 updateCurrent(); // Compute average
pspatel321 30:91af74a299e1 97
pspatel321 30:91af74a299e1 98 // Update status
pspatel321 30:91af74a299e1 99 register char stat = status & 0xF0; // The the upper 4 bits (locking errors)
pspatel321 30:91af74a299e1 100 if (current >= DC_DC_ON_THRESHOLD) stat |= ConvOn; // The converter is actually on (positive current)
pspatel321 30:91af74a299e1 101 if (dcdcControl == ON) stat |= SetOn; // The converter is set on
pspatel321 30:91af74a299e1 102
pspatel321 30:91af74a299e1 103 // During Timed Startup Phase
pspatel321 30:91af74a299e1 104 if (starting) {
pspatel321 30:91af74a299e1 105 stat |= PowerUp; // Indicate state in status byte
pspatel321 30:91af74a299e1 106 if (startTimer.read_us() >= STARTUP_DELAY_MS*1000) { // Start time elapsed
pspatel321 30:91af74a299e1 107 if (stat & ConvOn) { // Positive current detected
pspatel321 30:91af74a299e1 108 startTimer.stop(); // Stop timer
pspatel321 30:91af74a299e1 109 startTimer.reset(); // Reset to zero
pspatel321 30:91af74a299e1 110 starting = false; // Indicate running
pspatel321 30:91af74a299e1 111 } else {
pspatel321 30:91af74a299e1 112 startTimer.stop();
pspatel321 30:91af74a299e1 113 startTimer.reset();
pspatel321 30:91af74a299e1 114 stat |= FailStart; // Failed to start
pspatel321 30:91af74a299e1 115 }
pspatel321 30:91af74a299e1 116 }
pspatel321 30:91af74a299e1 117 }
pspatel321 30:91af74a299e1 118
pspatel321 30:91af74a299e1 119 // During Timed Stopping Phase
pspatel321 30:91af74a299e1 120 if (stopping) {
pspatel321 30:91af74a299e1 121 stat |= PowerDown; // Indicate state in status byte
pspatel321 30:91af74a299e1 122 if (stopTimer.read_us() >= STOP_DELAY_MS*1000) { // Stop time elapsed
pspatel321 30:91af74a299e1 123 if (stat & ConvOn) { // Converter still on
pspatel321 30:91af74a299e1 124 stopTimer.stop();
pspatel321 30:91af74a299e1 125 stopTimer.reset();
pspatel321 30:91af74a299e1 126 stat |= FailStop; // It didn't turn off even after timer expired!
pspatel321 30:91af74a299e1 127 } else { // Its actually off
pspatel321 30:91af74a299e1 128 stopping = false;
pspatel321 30:91af74a299e1 129 stopTimer.stop();
pspatel321 30:91af74a299e1 130 stopTimer.reset();
pspatel321 30:91af74a299e1 131 }
pspatel321 30:91af74a299e1 132 }
pspatel321 30:91af74a299e1 133 }
pspatel321 30:91af74a299e1 134
pspatel321 30:91af74a299e1 135 if (current > OVER_CURRENT_THRESHOLD) stat |= OverCurrent; // Over current
pspatel321 30:91af74a299e1 136 if (current == -INFINITY) stat |= SensorFault; // Sensor out of range
pspatel321 30:91af74a299e1 137
pspatel321 30:91af74a299e1 138 // While in steady state
pspatel321 30:91af74a299e1 139 if (!stopping && !starting) {
pspatel321 30:91af74a299e1 140 if ((stat & SetOn) && !(stat & 1)) stat |= FailStart; // Should be running but its not
pspatel321 30:91af74a299e1 141 if (!(stat & SetOn) && (stat & 1)) stat |= FailStop; // Should be stopped but its not
pspatel321 30:91af74a299e1 142 }
pspatel321 30:91af74a299e1 143
pspatel321 30:91af74a299e1 144 // Process critical error conditions
pspatel321 30:91af74a299e1 145 if (stat & 0xF0) critError = true;
pspatel321 30:91af74a299e1 146 else critError = false;
pspatel321 30:91af74a299e1 147 status = stat;
pspatel321 30:91af74a299e1 148
pspatel321 30:91af74a299e1 149 // Arrest error, all channels off, DC-DC off
pspatel321 30:91af74a299e1 150 if (critError) {
pspatel321 30:91af74a299e1 151 fan1.directOff();
pspatel321 30:91af74a299e1 152 fan2.directOff();
pspatel321 30:91af74a299e1 153 pump1.directOff();
pspatel321 30:91af74a299e1 154 pump2.directOff();
pspatel321 30:91af74a299e1 155 dcdcControl = OFF;
pspatel321 30:91af74a299e1 156 startTimer.stop();
pspatel321 30:91af74a299e1 157 startTimer.reset();
pspatel321 30:91af74a299e1 158 starting = false;
pspatel321 30:91af74a299e1 159 }
pspatel321 30:91af74a299e1 160 }
pspatel321 30:91af74a299e1 161
pspatel321 30:91af74a299e1 162 void DC_DC::setPwm(enum Channel_T chan, float duty) {
pspatel321 30:91af74a299e1 163 // Do nothing if error present, starting in startup, or DC-DC not actually on, or not set on
pspatel321 30:91af74a299e1 164 if (critError || starting || stopping || !(status & 1) || dcdcControl == OFF) return;
pspatel321 30:91af74a299e1 165
pspatel321 30:91af74a299e1 166 else {
pspatel321 34:18bcf276d3bf 167 if (chan == FAN1) fan1.write(duty);
pspatel321 34:18bcf276d3bf 168 if (chan == FAN2) fan2.write(duty);
pspatel321 30:91af74a299e1 169 if (chan == PUMP1) pump1.write(duty);
pspatel321 30:91af74a299e1 170 if (chan == PUMP2) pump2.write(duty);
pspatel321 30:91af74a299e1 171 }
pspatel321 30:91af74a299e1 172 }
pspatel321 30:91af74a299e1 173 float DC_DC::readPwm(enum Channel_T chan) {
pspatel321 30:91af74a299e1 174 if (chan == FAN1) return fan1.readRaw();
pspatel321 30:91af74a299e1 175 if (chan == FAN2) return fan2.readRaw();
pspatel321 30:91af74a299e1 176 if (chan == PUMP1) return pump1.readRaw();
pspatel321 30:91af74a299e1 177 if (chan == PUMP2) return pump2.readRaw();
pspatel321 30:91af74a299e1 178 else return 0;
pspatel321 30:91af74a299e1 179 }