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
diff -r 2207b58b9a7f -r 8efacce315ae Libs/CoulombCounter/CoulombCounter.cpp
--- 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
