Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

Committer:
pspatel321
Date:
Wed Feb 11 23:09:57 2015 +0000
Revision:
39:ddf38df9699e
Parent:
38:8efacce315ae
Updated CAN IDs for datalogging.  Changed profile encoding.

Who changed what in which revision?

UserRevisionLine numberNew 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 38:8efacce315ae 4 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
pspatel321 38:8efacce315ae 5 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
pspatel321 30:91af74a299e1 6
pspatel321 38:8efacce315ae 7 CoulombCounter::CoulombCounter(PinName _pin, int _mSec, unsigned int size) : BatISense(_pin)
pspatel321 38:8efacce315ae 8 {
pspatel321 30:91af74a299e1 9 mSec = _mSec;
pspatel321 38:8efacce315ae 10 _size = 0;
pspatel321 38:8efacce315ae 11 errorPacket = 0;
pspatel321 38:8efacce315ae 12 overChargeCurrent = 0;
pspatel321 38:8efacce315ae 13 overDischargeCurrent = 0;
pspatel321 30:91af74a299e1 14
pspatel321 30:91af74a299e1 15 // Default capacity if blank or corrupted
pspatel321 38:8efacce315ae 16 float capReg = store.read(GPREG_AH_CAPACITY);
pspatel321 38:8efacce315ae 17 if (capReg < MIN_CAPACITY_SETTING || capReg > MAX_CAPACITY_SETTING) { // Bad, write default
pspatel321 38:8efacce315ae 18 store.write(DEFAULT_AH, GPREG_AH_CAPACITY);
pspatel321 38:8efacce315ae 19 errorPacket |= CAP_INIT;
pspatel321 30:91af74a299e1 20 }
pspatel321 38:8efacce315ae 21
pspatel321 30:91af74a299e1 22 // Default SOC if blank or corrupted
pspatel321 38:8efacce315ae 23 float Ah = store.read(GPREG_AH_COUNTER);
pspatel321 38:8efacce315ae 24 if (Ah < 0 || Ah > MAX_CAPACITY_SETTING) { // Bad, write default
pspatel321 38:8efacce315ae 25 store.write(DEFAULT_SOC*DEFAULT_AH, GPREG_AH_COUNTER);
pspatel321 38:8efacce315ae 26 errorPacket |= SOC_INIT;
pspatel321 30:91af74a299e1 27 }
pspatel321 38:8efacce315ae 28
pspatel321 38:8efacce315ae 29 // Allocate the buffer
pspatel321 38:8efacce315ae 30 buffArr = new float [size];
pspatel321 38:8efacce315ae 31 if (buffArr == 0) {
pspatel321 38:8efacce315ae 32 error("Coulomb Counter failed to allocate memory");
pspatel321 38:8efacce315ae 33 }
pspatel321 38:8efacce315ae 34 _size = size;
pspatel321 38:8efacce315ae 35 tracker = 0;
pspatel321 38:8efacce315ae 36
pspatel321 30:91af74a299e1 37 // Take the initial readings, fill the buffer
pspatel321 38:8efacce315ae 38 for (int i = 0; i < _size; i++) {
pspatel321 36:0afc0fc8f86b 39 buffArr[i] = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET;
pspatel321 30:91af74a299e1 40 }
pspatel321 36:0afc0fc8f86b 41 updateAvg(); // Get avg and fill out overCurrent flag
pspatel321 38:8efacce315ae 42 }
pspatel321 38:8efacce315ae 43 void CoulombCounter::setup(float *charge, float *discharge) {
pspatel321 38:8efacce315ae 44 overChargeCurrent = charge;
pspatel321 38:8efacce315ae 45 overDischargeCurrent = discharge;
pspatel321 30:91af74a299e1 46 }
pspatel321 38:8efacce315ae 47 bool CoulombCounter::size(unsigned int size)
pspatel321 38:8efacce315ae 48 {
pspatel321 38:8efacce315ae 49 if (_size == size) return false;
pspatel321 30:91af74a299e1 50
pspatel321 38:8efacce315ae 51 // Get a current sample, this will be used to fill the new buffer
pspatel321 38:8efacce315ae 52 updateAvg();
pspatel321 38:8efacce315ae 53 float avg = current();
pspatel321 38:8efacce315ae 54
pspatel321 38:8efacce315ae 55 float* newArr = new float [size];
pspatel321 38:8efacce315ae 56 if (newArr == 0) return false;
pspatel321 38:8efacce315ae 57 else {
pspatel321 38:8efacce315ae 58 delete[] buffArr; // Free old
pspatel321 38:8efacce315ae 59 __disable_irq();
pspatel321 38:8efacce315ae 60
pspatel321 38:8efacce315ae 61 buffArr = newArr; // Transfer
pspatel321 38:8efacce315ae 62 _size = size; // Set new size
pspatel321 38:8efacce315ae 63 for (int i = 0; i < _size; i++) buffArr[i] = avg; // Fill with old avg
pspatel321 38:8efacce315ae 64
pspatel321 38:8efacce315ae 65 __enable_irq();
pspatel321 38:8efacce315ae 66 return true;
pspatel321 38:8efacce315ae 67 }
pspatel321 38:8efacce315ae 68 }
pspatel321 38:8efacce315ae 69 void CoulombCounter::sample()
pspatel321 38:8efacce315ae 70 {
pspatel321 30:91af74a299e1 71 // Take the reading
pspatel321 36:0afc0fc8f86b 72 float currentSample = BatISense.read()*BAT_ISENSE_MULTIPLIER+BAT_ISENSE_OFFSET;
pspatel321 38:8efacce315ae 73
pspatel321 30:91af74a299e1 74 // Integrate
pspatel321 30:91af74a299e1 75 float f = ampHours()-currentSample*mSec*MSEC_HRS;
pspatel321 38:8efacce315ae 76
pspatel321 30:91af74a299e1 77 // Bound to valid range
pspatel321 30:91af74a299e1 78 float cap = capacity();
pspatel321 30:91af74a299e1 79 if (f > cap) f = cap;
pspatel321 30:91af74a299e1 80 if (f < 0) f = 0;
pspatel321 38:8efacce315ae 81
pspatel321 30:91af74a299e1 82 // Write
pspatel321 38:8efacce315ae 83 store.write(f, GPREG_AH_COUNTER);
pspatel321 38:8efacce315ae 84
pspatel321 38:8efacce315ae 85 // Add to filter
pspatel321 38:8efacce315ae 86 buffArr[tracker++] = currentSample;
pspatel321 38:8efacce315ae 87 tracker %= _size;
pspatel321 30:91af74a299e1 88
pspatel321 38:8efacce315ae 89 // Update the avg, check for over-current
pspatel321 36:0afc0fc8f86b 90 updateAvg();
pspatel321 30:91af74a299e1 91 }
pspatel321 34:18bcf276d3bf 92
pspatel321 38:8efacce315ae 93 void CoulombCounter::updateAvg()
pspatel321 38:8efacce315ae 94 {
pspatel321 30:91af74a299e1 95 float avg = 0;
pspatel321 38:8efacce315ae 96 for (int i = 0; i < _size; i++) {
pspatel321 38:8efacce315ae 97 avg += buffArr[i];
pspatel321 30:91af74a299e1 98 }
pspatel321 38:8efacce315ae 99 avg /= _size;
pspatel321 36:0afc0fc8f86b 100 currentFiltered = avg;
pspatel321 38:8efacce315ae 101
pspatel321 38:8efacce315ae 102 errorPacket = 0;
pspatel321 38:8efacce315ae 103 if (overChargeCurrent == 0) return; // setup() not run yet
pspatel321 34:18bcf276d3bf 104
pspatel321 38:8efacce315ae 105 if (avg > *overDischargeCurrent) errorPacket |= OVER_DISCHARGE_I;
pspatel321 38:8efacce315ae 106 else errorPacket &= ~OVER_DISCHARGE_I;
pspatel321 38:8efacce315ae 107 if (avg < *overChargeCurrent) errorPacket |= OVER_CHARGE_I;
pspatel321 38:8efacce315ae 108 else errorPacket &= ~OVER_CHARGE_I;
pspatel321 30:91af74a299e1 109 }