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
- Committer:
- pspatel321
- Date:
- 2015-02-11
- Revision:
- 39:ddf38df9699e
- Parent:
- 38:8efacce315ae
File content as of revision 39:ddf38df9699e:
#include "CoulombCounter.h" const float MSEC_HRS = 2.77778e-7; // Multiplier to convert milliseconds to hours 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, 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(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(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 < _size; i++) { buffArr[i] = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET; } updateAvg(); // Get avg and fill out overCurrent flag } void CoulombCounter::setup(float *charge, float *discharge) { overChargeCurrent = charge; overDischargeCurrent = discharge; } bool CoulombCounter::size(unsigned int size) { if (_size == size) return false; // 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, GPREG_AH_COUNTER); // Add to filter buffArr[tracker++] = currentSample; tracker %= _size; // Update the avg, check for over-current updateAvg(); } void CoulombCounter::updateAvg() { float avg = 0; for (int i = 0; i < _size; i++) { avg += buffArr[i]; } avg /= _size; currentFiltered = avg; errorPacket = 0; if (overChargeCurrent == 0) return; // setup() not run yet if (avg > *overDischargeCurrent) errorPacket |= OVER_DISCHARGE_I; else errorPacket &= ~OVER_DISCHARGE_I; if (avg < *overChargeCurrent) errorPacket |= OVER_CHARGE_I; else errorPacket &= ~OVER_CHARGE_I; }