Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Libs/CoulombCounter/CoulombCounter.cpp

Committer:
pspatel321
Date:
2014-11-13
Revision:
30:91af74a299e1
Child:
33:6bc82b6b62e5

File content as of revision 30:91af74a299e1:

#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;    
}