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:
Tue Jan 06 20:45:26 2015 +0000
Revision:
33:6bc82b6b62e5
Parent:
30:91af74a299e1
Child:
34:18bcf276d3bf
Updated IDs to match AMS, added a constants.h file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 30:91af74a299e1 1 #include "CoulombCounter.h"
pspatel321 30:91af74a299e1 2
pspatel321 30:91af74a299e1 3 const float MSEC_HRS = 2.77778e-7; // Multiplier to convert milliseconds to hours
pspatel321 30:91af74a299e1 4 const float BAT_ISENSE_MULTIPLIER = 6.2299; // Multiplier to convert float to amps
pspatel321 30:91af74a299e1 5 const float BAT_ISENSE_OFFSET = -0.5*BAT_ISENSE_MULTIPLIER; // Offset to convert float to amps
pspatel321 30:91af74a299e1 6 const float BAT_ISENSE_LIMS = 3.0; // Over-current limit = +/- 3A
pspatel321 30:91af74a299e1 7
pspatel321 30:91af74a299e1 8 const int rtcGPREG_counter = 0; // RTC GPREG offset for the coulomb counter
pspatel321 30:91af74a299e1 9 const int rtcGPREG_capacity = 1; // RTC GPREG offset for the capacity spec
pspatel321 30:91af74a299e1 10
pspatel321 30:91af74a299e1 11 CoulombCounter::CoulombCounter(PinName _pin, int _mSec) : BatISense(_pin) {
pspatel321 30:91af74a299e1 12 mSec = _mSec;
pspatel321 30:91af74a299e1 13
pspatel321 30:91af74a299e1 14 // Default capacity if blank or corrupted
pspatel321 30:91af74a299e1 15 float capReg = store.read(rtcGPREG_capacity);
pspatel321 30:91af74a299e1 16 if (capReg < 1.0 || capReg > 5.0) { // Bad, write default
pspatel321 30:91af74a299e1 17 store.write(defaultAh, rtcGPREG_capacity);
pspatel321 30:91af74a299e1 18 }
pspatel321 30:91af74a299e1 19
pspatel321 30:91af74a299e1 20 // Default SOC if blank or corrupted
pspatel321 30:91af74a299e1 21 float Ah = store.read(rtcGPREG_counter);
pspatel321 33:6bc82b6b62e5 22 if (Ah < 0 || Ah > defaultAh) { // Bad, write default
pspatel321 33:6bc82b6b62e5 23 store.write(defaultSOC*defaultAh, rtcGPREG_counter);
pspatel321 30:91af74a299e1 24 }
pspatel321 30:91af74a299e1 25
pspatel321 30:91af74a299e1 26 // Take the initial readings, fill the buffer
pspatel321 30:91af74a299e1 27 for (int i = 0; i < CC_FILTER_TAPS; i++) {
pspatel321 30:91af74a299e1 28 buffArr[i] = BatISense.read() * BAT_ISENSE_MULTIPLIER + BAT_ISENSE_OFFSET;
pspatel321 30:91af74a299e1 29 }
pspatel321 30:91af74a299e1 30 current(); // Get avg and fill out overCurrent flag
pspatel321 30:91af74a299e1 31 tracker=0;
pspatel321 30:91af74a299e1 32
pspatel321 30:91af74a299e1 33 // Start counting
pspatel321 30:91af74a299e1 34 // sampler.attach_us(this, &CoulombCounter::sample, mSec*1000);
pspatel321 30:91af74a299e1 35 }
pspatel321 30:91af74a299e1 36
pspatel321 30:91af74a299e1 37 void CoulombCounter::sample() {
pspatel321 30:91af74a299e1 38 // Take the reading
pspatel321 30:91af74a299e1 39 currentSample = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET;
pspatel321 30:91af74a299e1 40
pspatel321 30:91af74a299e1 41 // Integrate
pspatel321 30:91af74a299e1 42 float f = ampHours()-currentSample*mSec*MSEC_HRS;
pspatel321 30:91af74a299e1 43
pspatel321 30:91af74a299e1 44 // Bound to valid range
pspatel321 30:91af74a299e1 45 float cap = capacity();
pspatel321 30:91af74a299e1 46 if (f > cap) f = cap;
pspatel321 30:91af74a299e1 47 if (f < 0) f = 0;
pspatel321 30:91af74a299e1 48
pspatel321 30:91af74a299e1 49 // Write
pspatel321 30:91af74a299e1 50 store.write(f, rtcGPREG_counter);
pspatel321 30:91af74a299e1 51
pspatel321 30:91af74a299e1 52 // Add to filter
pspatel321 30:91af74a299e1 53 buffArr[tracker] = currentSample;
pspatel321 30:91af74a299e1 54 tracker++;
pspatel321 30:91af74a299e1 55 if (tracker >= CC_FILTER_TAPS) tracker = 0;
pspatel321 30:91af74a299e1 56 }
pspatel321 30:91af74a299e1 57 void CoulombCounter::resetToSOC(float SOC) {
pspatel321 30:91af74a299e1 58 store.write(SOC*capacity(), rtcGPREG_counter);
pspatel321 30:91af74a299e1 59 }
pspatel321 30:91af74a299e1 60 void CoulombCounter::resetToAh(float Ah) {
pspatel321 30:91af74a299e1 61 store.write(Ah, rtcGPREG_counter);
pspatel321 30:91af74a299e1 62 }
pspatel321 30:91af74a299e1 63 void CoulombCounter::changeCapacity(float capAh) {
pspatel321 30:91af74a299e1 64 store.write(capAh, rtcGPREG_capacity);
pspatel321 30:91af74a299e1 65 }
pspatel321 30:91af74a299e1 66 float CoulombCounter::current() {
pspatel321 30:91af74a299e1 67 float avg = 0;
pspatel321 30:91af74a299e1 68 for (int i = 0; i < CC_FILTER_TAPS; i++) {
pspatel321 30:91af74a299e1 69 avg += buffArr[i];
pspatel321 30:91af74a299e1 70 }
pspatel321 30:91af74a299e1 71 avg /= CC_FILTER_TAPS;
pspatel321 30:91af74a299e1 72 if (abs(avg) > BAT_ISENSE_LIMS) overCurrent = true;
pspatel321 30:91af74a299e1 73 return avg;
pspatel321 30:91af74a299e1 74 }
pspatel321 30:91af74a299e1 75 float CoulombCounter::ampHours() {
pspatel321 30:91af74a299e1 76 return store.read(rtcGPREG_counter);
pspatel321 30:91af74a299e1 77 }
pspatel321 30:91af74a299e1 78 float CoulombCounter::capacity() {
pspatel321 30:91af74a299e1 79 return store.read(rtcGPREG_capacity);
pspatel321 30:91af74a299e1 80 }
pspatel321 30:91af74a299e1 81 float CoulombCounter::SOC() {
pspatel321 30:91af74a299e1 82 return ampHours()/capacity();
pspatel321 30:91af74a299e1 83 }
pspatel321 30:91af74a299e1 84 bool CoulombCounter::overCurrentDetected() {
pspatel321 30:91af74a299e1 85 return overCurrent;
pspatel321 30:91af74a299e1 86 }