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:
- 30:91af74a299e1
- Child:
- 33:6bc82b6b62e5
--- /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