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:
Thu Nov 13 10:53:10 2014 +0000
Revision:
30:91af74a299e1
Child:
34:18bcf276d3bf
Parth's edits for the week.; DC-DC completed and fixed, IMD updated, LatchMonitor and Temperature added.  Serial dashboard updated.  File structure changed Everything tested.  Compiles and runs.; Still need to write CAN in/out interface.

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 30:91af74a299e1 61 // Do nothing if error present
pspatel321 30:91af74a299e1 62 if (critError) return;
pspatel321 30:91af74a299e1 63
pspatel321 30:91af74a299e1 64 // If start requested
pspatel321 30:91af74a299e1 65 if (on) {
pspatel321 30:91af74a299e1 66 dcdcControl = ON;
pspatel321 30:91af74a299e1 67 starting = true;
pspatel321 30:91af74a299e1 68 startTimer.reset();
pspatel321 30:91af74a299e1 69 startTimer.start();
pspatel321 30:91af74a299e1 70 stopTimer.stop();
pspatel321 30:91af74a299e1 71 stopTimer.reset();
pspatel321 30:91af74a299e1 72 stopping = false;
pspatel321 30:91af74a299e1 73 // If stop requested
pspatel321 30:91af74a299e1 74 } else {
pspatel321 30:91af74a299e1 75 stopping=true;
pspatel321 30:91af74a299e1 76 fan1.directOff();
pspatel321 30:91af74a299e1 77 fan2.directOff();
pspatel321 30:91af74a299e1 78 pump1.directOff();
pspatel321 30:91af74a299e1 79 pump2.directOff();
pspatel321 30:91af74a299e1 80 dcdcControl = OFF;
pspatel321 30:91af74a299e1 81 stopTimer.reset();
pspatel321 30:91af74a299e1 82 stopTimer.start();
pspatel321 30:91af74a299e1 83 startTimer.stop();
pspatel321 30:91af74a299e1 84 startTimer.reset();
pspatel321 30:91af74a299e1 85 starting = false;
pspatel321 30:91af74a299e1 86 }
pspatel321 30:91af74a299e1 87 }
pspatel321 30:91af74a299e1 88
pspatel321 30:91af74a299e1 89 void DC_DC::sample() {
pspatel321 30:91af74a299e1 90
pspatel321 30:91af74a299e1 91 // Get next current sample
pspatel321 30:91af74a299e1 92 float curr = (dcdcCurrent - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
pspatel321 30:91af74a299e1 93 if (curr < CURRENT_SENSOR_LLIM) curr = -INFINITY; // Check if sensor out of range
pspatel321 30:91af74a299e1 94 else if (curr < 0) curr = 0; // Floor to zero
pspatel321 30:91af74a299e1 95 filterBuff[buffTracker] = curr; // Add to buffer filter
pspatel321 30:91af74a299e1 96 buffTracker++;
pspatel321 30:91af74a299e1 97 if (buffTracker >= DC_DC_FILTER_TAPS) buffTracker = 0;
pspatel321 30:91af74a299e1 98 updateCurrent(); // Compute average
pspatel321 30:91af74a299e1 99
pspatel321 30:91af74a299e1 100 // Update status
pspatel321 30:91af74a299e1 101 register char stat = status & 0xF0; // The the upper 4 bits (locking errors)
pspatel321 30:91af74a299e1 102 if (current >= DC_DC_ON_THRESHOLD) stat |= ConvOn; // The converter is actually on (positive current)
pspatel321 30:91af74a299e1 103 if (dcdcControl == ON) stat |= SetOn; // The converter is set on
pspatel321 30:91af74a299e1 104
pspatel321 30:91af74a299e1 105 // During Timed Startup Phase
pspatel321 30:91af74a299e1 106 if (starting) {
pspatel321 30:91af74a299e1 107 stat |= PowerUp; // Indicate state in status byte
pspatel321 30:91af74a299e1 108 if (startTimer.read_us() >= STARTUP_DELAY_MS*1000) { // Start time elapsed
pspatel321 30:91af74a299e1 109 if (stat & ConvOn) { // Positive current detected
pspatel321 30:91af74a299e1 110 startTimer.stop(); // Stop timer
pspatel321 30:91af74a299e1 111 startTimer.reset(); // Reset to zero
pspatel321 30:91af74a299e1 112 starting = false; // Indicate running
pspatel321 30:91af74a299e1 113 } else {
pspatel321 30:91af74a299e1 114 startTimer.stop();
pspatel321 30:91af74a299e1 115 startTimer.reset();
pspatel321 30:91af74a299e1 116 stat |= FailStart; // Failed to start
pspatel321 30:91af74a299e1 117 }
pspatel321 30:91af74a299e1 118 }
pspatel321 30:91af74a299e1 119 }
pspatel321 30:91af74a299e1 120
pspatel321 30:91af74a299e1 121 // During Timed Stopping Phase
pspatel321 30:91af74a299e1 122 if (stopping) {
pspatel321 30:91af74a299e1 123 stat |= PowerDown; // Indicate state in status byte
pspatel321 30:91af74a299e1 124 if (stopTimer.read_us() >= STOP_DELAY_MS*1000) { // Stop time elapsed
pspatel321 30:91af74a299e1 125 if (stat & ConvOn) { // Converter still on
pspatel321 30:91af74a299e1 126 stopTimer.stop();
pspatel321 30:91af74a299e1 127 stopTimer.reset();
pspatel321 30:91af74a299e1 128 stat |= FailStop; // It didn't turn off even after timer expired!
pspatel321 30:91af74a299e1 129 } else { // Its actually off
pspatel321 30:91af74a299e1 130 stopping = false;
pspatel321 30:91af74a299e1 131 stopTimer.stop();
pspatel321 30:91af74a299e1 132 stopTimer.reset();
pspatel321 30:91af74a299e1 133 }
pspatel321 30:91af74a299e1 134 }
pspatel321 30:91af74a299e1 135 }
pspatel321 30:91af74a299e1 136
pspatel321 30:91af74a299e1 137 if (current > OVER_CURRENT_THRESHOLD) stat |= OverCurrent; // Over current
pspatel321 30:91af74a299e1 138 if (current == -INFINITY) stat |= SensorFault; // Sensor out of range
pspatel321 30:91af74a299e1 139
pspatel321 30:91af74a299e1 140 // While in steady state
pspatel321 30:91af74a299e1 141 if (!stopping && !starting) {
pspatel321 30:91af74a299e1 142 if ((stat & SetOn) && !(stat & 1)) stat |= FailStart; // Should be running but its not
pspatel321 30:91af74a299e1 143 if (!(stat & SetOn) && (stat & 1)) stat |= FailStop; // Should be stopped but its not
pspatel321 30:91af74a299e1 144 }
pspatel321 30:91af74a299e1 145
pspatel321 30:91af74a299e1 146 // Process critical error conditions
pspatel321 30:91af74a299e1 147 if (stat & 0xF0) critError = true;
pspatel321 30:91af74a299e1 148 else critError = false;
pspatel321 30:91af74a299e1 149 status = stat;
pspatel321 30:91af74a299e1 150
pspatel321 30:91af74a299e1 151 // Arrest error, all channels off, DC-DC off
pspatel321 30:91af74a299e1 152 if (critError) {
pspatel321 30:91af74a299e1 153 fan1.directOff();
pspatel321 30:91af74a299e1 154 fan2.directOff();
pspatel321 30:91af74a299e1 155 pump1.directOff();
pspatel321 30:91af74a299e1 156 pump2.directOff();
pspatel321 30:91af74a299e1 157 dcdcControl = OFF;
pspatel321 30:91af74a299e1 158 startTimer.stop();
pspatel321 30:91af74a299e1 159 startTimer.reset();
pspatel321 30:91af74a299e1 160 starting = false;
pspatel321 30:91af74a299e1 161 }
pspatel321 30:91af74a299e1 162 }
pspatel321 30:91af74a299e1 163
pspatel321 30:91af74a299e1 164 void DC_DC::setPwm(enum Channel_T chan, float duty) {
pspatel321 30:91af74a299e1 165 // Do nothing if error present, starting in startup, or DC-DC not actually on, or not set on
pspatel321 30:91af74a299e1 166 if (critError || starting || stopping || !(status & 1) || dcdcControl == OFF) return;
pspatel321 30:91af74a299e1 167
pspatel321 30:91af74a299e1 168 else {
pspatel321 30:91af74a299e1 169 if (chan == FAN1) fan1.write(duty);
pspatel321 30:91af74a299e1 170 if (chan == FAN2) fan2.write(duty);
pspatel321 30:91af74a299e1 171 if (chan == PUMP1) pump1.write(duty);
pspatel321 30:91af74a299e1 172 if (chan == PUMP2) pump2.write(duty);
pspatel321 30:91af74a299e1 173 }
pspatel321 30:91af74a299e1 174 }
pspatel321 30:91af74a299e1 175 float DC_DC::readPwm(enum Channel_T chan) {
pspatel321 30:91af74a299e1 176 if (chan == FAN1) return fan1.readRaw();
pspatel321 30:91af74a299e1 177 if (chan == FAN2) return fan2.readRaw();
pspatel321 30:91af74a299e1 178 if (chan == PUMP1) return pump1.readRaw();
pspatel321 30:91af74a299e1 179 if (chan == PUMP2) return pump2.readRaw();
pspatel321 30:91af74a299e1 180 else return 0;
pspatel321 30:91af74a299e1 181 }