Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: Libs/CoulombCounter/CoulombCounter.cpp
- 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