Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Revision:
38:8efacce315ae
Parent:
36:0afc0fc8f86b
--- a/Libs/CoulombCounter/CoulombCounter.cpp	Thu Jan 22 07:59:48 2015 +0000
+++ b/Libs/CoulombCounter/CoulombCounter.cpp	Sat Feb 07 08:54:51 2015 +0000
@@ -1,65 +1,109 @@
 #include "CoulombCounter.h"
 
 const float MSEC_HRS = 2.77778e-7;                          // Multiplier to convert milliseconds to hours
-const float BAT_ISENSE_MULTIPLIER = /*6.2299*/6.640114;     // Multiplier to convert float to amps, calibrated using 3 points with Fluke 87V meter and code on 1/9/15
-const float BAT_ISENSE_OFFSET = /*-0.5*BAT_ISENSE_MULTIPLIER*/-3.344968; // Offset to convert float to amps, calibrated using 3 points with Fluke 87V meter and code on 1/9/15
-const float BAT_ISENSE_LIMS = 3.0;                          // Over-current limit = +/- 3A
+const float BAT_ISENSE_MULTIPLIER = 6.640114;               // Multiplier to convert float to amps, calibrated using 3 points with Fluke 87V meter and code on 1/9/15
+const float BAT_ISENSE_OFFSET = -3.344968;                  // Offset to convert float to amps, calibrated using 3 points with Fluke 87V meter and code on 1/9/15
 
-CoulombCounter::CoulombCounter(PinName _pin, int _mSec) : BatISense(_pin) {
+CoulombCounter::CoulombCounter(PinName _pin, int _mSec, unsigned int size) : BatISense(_pin)
+{
     mSec = _mSec;
+    _size = 0;
+    errorPacket = 0;
+    overChargeCurrent = 0;
+    overDischargeCurrent = 0;
     
     // 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);
+    float capReg = store.read(GPREG_AH_CAPACITY);
+    if (capReg < MIN_CAPACITY_SETTING || capReg > MAX_CAPACITY_SETTING) {   // Bad, write default
+        store.write(DEFAULT_AH, GPREG_AH_CAPACITY);
+        errorPacket |= CAP_INIT;
     }
-    
+
     // Default SOC if blank or corrupted
-    float Ah = store.read(rtcGPREG_counter);
-    if (Ah < 0 || Ah > defaultAh) {                    // Bad, write default
-        store.write(defaultSOC*defaultAh, rtcGPREG_counter);
+    float Ah = store.read(GPREG_AH_COUNTER);
+    if (Ah < 0 || Ah > MAX_CAPACITY_SETTING) {                              // Bad, write default
+        store.write(DEFAULT_SOC*DEFAULT_AH, GPREG_AH_COUNTER);
+        errorPacket |= SOC_INIT;
     }
-    
+
+    // Allocate the buffer
+    buffArr = new float [size];
+    if (buffArr == 0) {
+        error("Coulomb Counter failed to allocate memory");
+    }
+    _size = size;
+    tracker = 0;
+
     // Take the initial readings, fill the buffer
-    for (int i = 0; i < CC_FILTER_TAPS; i++) {
+    for (int i = 0; i < _size; i++) {
         buffArr[i] = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET;
     }
     updateAvg();      // Get avg and fill out overCurrent flag
-    tracker=0;
+}
+void CoulombCounter::setup(float *charge, float *discharge) {
+    overChargeCurrent = charge;
+    overDischargeCurrent = discharge;
 }
+bool CoulombCounter::size(unsigned int size)
+{
+    if (_size == size) return false;
 
-void CoulombCounter::sample() {
+    // Get a current sample, this will be used to fill the new buffer
+    updateAvg();
+    float avg = current();
+
+    float* newArr = new float [size];
+    if (newArr == 0) return false;
+    else {
+        delete[] buffArr;   // Free old
+        __disable_irq();
+
+        buffArr = newArr;   // Transfer
+        _size = size;       // Set new size
+        for (int i = 0; i < _size; i++) buffArr[i] = avg;   // Fill with old avg
+
+        __enable_irq();
+        return true;
+    }
+}
+void CoulombCounter::sample()
+{
     // Take the reading
     float 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);
+    store.write(f, GPREG_AH_COUNTER);
+
+    // Add to filter
+    buffArr[tracker++] = currentSample;
+    tracker %= _size;
     
-    // Add to filter
-    buffArr[tracker] = currentSample;
-    tracker++;
-    if (tracker >= CC_FILTER_TAPS) tracker = 0;
+    // Update the avg, check for over-current
     updateAvg();
 }
 
-void CoulombCounter::updateAvg() {
+void CoulombCounter::updateAvg()
+{
     float avg = 0;
-    for (int i = 0; i < CC_FILTER_TAPS; i++) {
-        avg += buffArr[i];   
+    for (int i = 0; i < _size; i++) {
+        avg += buffArr[i];
     }
-    avg /= CC_FILTER_TAPS;
-    if (abs(avg) > BAT_ISENSE_LIMS) overCurrent = true;
+    avg /= _size;
     currentFiltered = avg;
-}
+    
+    errorPacket = 0;
+    if (overChargeCurrent == 0) return;     // setup() not run yet
 
-bool CoulombCounter::overCurrentDetected() {
-    return overCurrent;
+    if (avg > *overDischargeCurrent)    errorPacket |= OVER_DISCHARGE_I;
+    else                                errorPacket &= ~OVER_DISCHARGE_I;
+    if (avg < *overChargeCurrent)       errorPacket |= OVER_CHARGE_I;
+    else                                errorPacket &= ~OVER_CHARGE_I;
 }
\ No newline at end of file