Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Revision:
30:91af74a299e1
Child:
33:6bc82b6b62e5
diff -r f58a3c0071c3 -r 91af74a299e1 Libs/CoulombCounter/CoulombCounter.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/CoulombCounter/CoulombCounter.cpp	Thu Nov 13 10:53:10 2014 +0000
@@ -0,0 +1,87 @@
+#include "CoulombCounter.h"
+
+const float MSEC_HRS = 2.77778e-7;                          // Multiplier to convert milliseconds to hours
+const float BAT_ISENSE_MULTIPLIER = 6.2299;                 // Multiplier to convert float to amps
+const float BAT_ISENSE_OFFSET = -0.5*BAT_ISENSE_MULTIPLIER; // Offset to convert float to amps
+const float BAT_ISENSE_LIMS = 3.0;                          // Over-current limit = +/- 3A
+
+const int rtcGPREG_counter = 0;     // RTC GPREG offset for the coulomb counter
+const int rtcGPREG_capacity = 1;    // RTC GPREG offset for the capacity spec
+
+CoulombCounter::CoulombCounter(PinName _pin, int _mSec) : BatISense(_pin) {
+    mSec = _mSec;
+    
+    // Default capacity if blank or corrupted
+    float capReg = store.read(rtcGPREG_capacity);
+    if (capReg < 1.0 || capReg > 5.0) {             // Bad, write default
+        store.write(defaultAh, rtcGPREG_capacity);
+    }
+    capReg = store.read(rtcGPREG_capacity);
+    
+    // Default SOC if blank or corrupted
+    float Ah = store.read(rtcGPREG_counter);
+    if (Ah < 0 || Ah > capReg) {                    // Bad, write default
+        store.write(defaultSOC*capReg, rtcGPREG_counter);
+    }
+    
+    // Take the initial readings, fill the buffer
+    for (int i = 0; i < CC_FILTER_TAPS; i++) {
+        buffArr[i] = BatISense.read() * BAT_ISENSE_MULTIPLIER + BAT_ISENSE_OFFSET;
+    }
+    current();      // Get avg and fill out overCurrent flag
+    tracker=0;
+    
+    // Start counting
+    // sampler.attach_us(this, &CoulombCounter::sample, mSec*1000);
+}
+
+void CoulombCounter::sample() {
+    // Take the reading
+    currentSample = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET;
+        
+    // Integrate
+    float f = ampHours()-currentSample*mSec*MSEC_HRS;
+    
+    // Bound to valid range
+    float cap = capacity();
+    if (f > cap) f = cap;
+    if (f < 0) f = 0;
+    
+    // Write
+    store.write(f, rtcGPREG_counter);
+    
+    // Add to filter
+    buffArr[tracker] = currentSample;
+    tracker++;
+    if (tracker >= CC_FILTER_TAPS) tracker = 0;
+}
+void CoulombCounter::resetToSOC(float SOC) { 
+    store.write(SOC*capacity(), rtcGPREG_counter);
+}
+void CoulombCounter::resetToAh(float Ah) {
+    store.write(Ah, rtcGPREG_counter);
+}
+void CoulombCounter::changeCapacity(float capAh) {
+    store.write(capAh, rtcGPREG_capacity);
+}
+float CoulombCounter::current() { 
+    float avg = 0;
+    for (int i = 0; i < CC_FILTER_TAPS; i++) {
+        avg += buffArr[i];   
+    }
+    avg /= CC_FILTER_TAPS;
+    if (abs(avg) > BAT_ISENSE_LIMS) overCurrent = true;
+    return avg;
+}
+float CoulombCounter::ampHours() {
+    return store.read(rtcGPREG_counter);
+}
+float CoulombCounter::capacity() {
+    return store.read(rtcGPREG_capacity);
+}
+float CoulombCounter::SOC() {
+    return ampHours()/capacity();
+}
+bool CoulombCounter::overCurrentDetected() {
+    return overCurrent;    
+}
\ No newline at end of file