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
Libs/CoulombCounter/CoulombCounter.cpp@36:0afc0fc8f86b, 2015-01-22 (annotated)
- Committer:
- pspatel321
- Date:
- Thu Jan 22 07:58:51 2015 +0000
- Revision:
- 36:0afc0fc8f86b
- Parent:
- 34:18bcf276d3bf
- Child:
- 38:8efacce315ae
Tested in car with other systems. Most features are good to go. Except xbees need work. The DC-DC protection features were giving problems due to spurious current measurements. They have been edited to reduce glitchy errors.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pspatel321 | 30:91af74a299e1 | 1 | #include "CoulombCounter.h" |
pspatel321 | 30:91af74a299e1 | 2 | |
pspatel321 | 30:91af74a299e1 | 3 | const float MSEC_HRS = 2.77778e-7; // Multiplier to convert milliseconds to hours |
pspatel321 | 36:0afc0fc8f86b | 4 | 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 |
pspatel321 | 36:0afc0fc8f86b | 5 | 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 |
pspatel321 | 30:91af74a299e1 | 6 | const float BAT_ISENSE_LIMS = 3.0; // Over-current limit = +/- 3A |
pspatel321 | 30:91af74a299e1 | 7 | |
pspatel321 | 30:91af74a299e1 | 8 | CoulombCounter::CoulombCounter(PinName _pin, int _mSec) : BatISense(_pin) { |
pspatel321 | 30:91af74a299e1 | 9 | mSec = _mSec; |
pspatel321 | 30:91af74a299e1 | 10 | |
pspatel321 | 30:91af74a299e1 | 11 | // Default capacity if blank or corrupted |
pspatel321 | 30:91af74a299e1 | 12 | float capReg = store.read(rtcGPREG_capacity); |
pspatel321 | 30:91af74a299e1 | 13 | if (capReg < 1.0 || capReg > 5.0) { // Bad, write default |
pspatel321 | 30:91af74a299e1 | 14 | store.write(defaultAh, rtcGPREG_capacity); |
pspatel321 | 30:91af74a299e1 | 15 | } |
pspatel321 | 30:91af74a299e1 | 16 | |
pspatel321 | 30:91af74a299e1 | 17 | // Default SOC if blank or corrupted |
pspatel321 | 30:91af74a299e1 | 18 | float Ah = store.read(rtcGPREG_counter); |
pspatel321 | 33:6bc82b6b62e5 | 19 | if (Ah < 0 || Ah > defaultAh) { // Bad, write default |
pspatel321 | 33:6bc82b6b62e5 | 20 | store.write(defaultSOC*defaultAh, rtcGPREG_counter); |
pspatel321 | 30:91af74a299e1 | 21 | } |
pspatel321 | 30:91af74a299e1 | 22 | |
pspatel321 | 30:91af74a299e1 | 23 | // Take the initial readings, fill the buffer |
pspatel321 | 30:91af74a299e1 | 24 | for (int i = 0; i < CC_FILTER_TAPS; i++) { |
pspatel321 | 36:0afc0fc8f86b | 25 | buffArr[i] = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET; |
pspatel321 | 30:91af74a299e1 | 26 | } |
pspatel321 | 36:0afc0fc8f86b | 27 | updateAvg(); // Get avg and fill out overCurrent flag |
pspatel321 | 30:91af74a299e1 | 28 | tracker=0; |
pspatel321 | 30:91af74a299e1 | 29 | } |
pspatel321 | 30:91af74a299e1 | 30 | |
pspatel321 | 30:91af74a299e1 | 31 | void CoulombCounter::sample() { |
pspatel321 | 30:91af74a299e1 | 32 | // Take the reading |
pspatel321 | 36:0afc0fc8f86b | 33 | float currentSample = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET; |
pspatel321 | 30:91af74a299e1 | 34 | |
pspatel321 | 30:91af74a299e1 | 35 | // Integrate |
pspatel321 | 30:91af74a299e1 | 36 | float f = ampHours()-currentSample*mSec*MSEC_HRS; |
pspatel321 | 30:91af74a299e1 | 37 | |
pspatel321 | 30:91af74a299e1 | 38 | // Bound to valid range |
pspatel321 | 30:91af74a299e1 | 39 | float cap = capacity(); |
pspatel321 | 30:91af74a299e1 | 40 | if (f > cap) f = cap; |
pspatel321 | 30:91af74a299e1 | 41 | if (f < 0) f = 0; |
pspatel321 | 30:91af74a299e1 | 42 | |
pspatel321 | 30:91af74a299e1 | 43 | // Write |
pspatel321 | 30:91af74a299e1 | 44 | store.write(f, rtcGPREG_counter); |
pspatel321 | 30:91af74a299e1 | 45 | |
pspatel321 | 30:91af74a299e1 | 46 | // Add to filter |
pspatel321 | 30:91af74a299e1 | 47 | buffArr[tracker] = currentSample; |
pspatel321 | 30:91af74a299e1 | 48 | tracker++; |
pspatel321 | 30:91af74a299e1 | 49 | if (tracker >= CC_FILTER_TAPS) tracker = 0; |
pspatel321 | 36:0afc0fc8f86b | 50 | updateAvg(); |
pspatel321 | 30:91af74a299e1 | 51 | } |
pspatel321 | 34:18bcf276d3bf | 52 | |
pspatel321 | 36:0afc0fc8f86b | 53 | void CoulombCounter::updateAvg() { |
pspatel321 | 30:91af74a299e1 | 54 | float avg = 0; |
pspatel321 | 30:91af74a299e1 | 55 | for (int i = 0; i < CC_FILTER_TAPS; i++) { |
pspatel321 | 30:91af74a299e1 | 56 | avg += buffArr[i]; |
pspatel321 | 30:91af74a299e1 | 57 | } |
pspatel321 | 30:91af74a299e1 | 58 | avg /= CC_FILTER_TAPS; |
pspatel321 | 30:91af74a299e1 | 59 | if (abs(avg) > BAT_ISENSE_LIMS) overCurrent = true; |
pspatel321 | 36:0afc0fc8f86b | 60 | currentFiltered = avg; |
pspatel321 | 30:91af74a299e1 | 61 | } |
pspatel321 | 34:18bcf276d3bf | 62 | |
pspatel321 | 30:91af74a299e1 | 63 | bool CoulombCounter::overCurrentDetected() { |
pspatel321 | 34:18bcf276d3bf | 64 | return overCurrent; |
pspatel321 | 30:91af74a299e1 | 65 | } |