| [20] | 1 |
|
|---|
| 2 |
|
|---|
| 3 | #include "sysdata.h"
|
|---|
| 4 | #include "esr.h"
|
|---|
| 5 | #include <stdlib.h>
|
|---|
| [73] | 6 | #include <stdio.h>
|
|---|
| [25] | 7 | #include "main.h"
|
|---|
| [73] | 8 | #include "battery_voltage_fast.h"
|
|---|
| [25] | 9 | #include "fast_current.h"
|
|---|
| [20] | 10 |
|
|---|
| [73] | 11 | #define I_MULTIPLIER ((int64_t) VREF / FAST_CURRENT_SHUNT_RESISTOR / FAST_CURRENT_I_SENSE_GAIN / FAST_CURRENT_ADC_RESOLUTION)
|
|---|
| 12 | #define U_MULTIPLIER ((int64_t) VREF * BATTERY_VOLTAGE_VOLTAGE_DIVIDER / BATTERY_VOLTAGE_FAST_ADC_RESOLUTION )
|
|---|
| [20] | 13 |
|
|---|
| 14 | int32_t current_buffer[SAMPLE_ARRAY_SIZE];
|
|---|
| 15 | int32_t voltage_buffer[SAMPLE_ARRAY_SIZE];
|
|---|
| 16 |
|
|---|
| [38] | 17 |
|
|---|
| [73] | 18 | extern int32_t adc1Data[SAMPLE_ARRAY_SIZE];
|
|---|
| 19 | extern int32_t adc2Data[SAMPLE_ARRAY_SIZE];
|
|---|
| 20 | extern int32_t adc4Data[SAMPLE_ARRAY_SIZE];
|
|---|
| [20] | 21 |
|
|---|
| [25] | 22 |
|
|---|
| [20] | 23 |
|
|---|
| 24 | int16_t ESR_FAST_Exec(void)
|
|---|
| 25 | {
|
|---|
| 26 |
|
|---|
| [73] | 27 | // printf("esr\r\n");
|
|---|
| [20] | 28 | static int32_t last_refresh;
|
|---|
| 29 | int x;
|
|---|
| 30 |
|
|---|
| 31 | //Anzeige vor wieviel Sekunden zuletzt aktualisiert wurd.
|
|---|
| [26] | 32 | //Aktuell erfolgt nur die Anze der low speed Methode
|
|---|
| 33 | //sys_data.s.values.esrCalcTime = sys_data.s.values.onTime - last_refresh;
|
|---|
| [20] | 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 | //Suche Min und max werte im Array
|
|---|
| [55] | 38 | int32_t minUBatt=INT32_MAX;
|
|---|
| [73] | 39 | int32_t maxUBatt=INT32_MIN;
|
|---|
| [55] | 40 | int32_t minUOut=INT32_MAX;
|
|---|
| [73] | 41 | int32_t maxUOut=INT32_MIN;
|
|---|
| [20] | 42 | int32_t minI=INT32_MAX;
|
|---|
| [73] | 43 | int32_t maxI=INT32_MIN;
|
|---|
| [20] | 44 | int32_t minIPos = -1;
|
|---|
| [73] | 45 | int32_t maxIPos = -1;
|
|---|
| [55] | 46 | int32_t minUBattPos = -1;
|
|---|
| 47 | int32_t maxUBattPos = -1;
|
|---|
| 48 | int32_t minUOutPos = -1;
|
|---|
| 49 | int32_t maxUOutPos = -1;
|
|---|
| [20] | 50 |
|
|---|
| [73] | 51 |
|
|---|
| 52 | //Entferne Offset
|
|---|
| 53 | for (x=0; x < SAMPLE_ARRAY_SIZE -1; x++)
|
|---|
| 54 | {
|
|---|
| 55 | adc1Data[x] = adc1Data[x] - FAST_CURRENT_ADC_OFFSET;
|
|---|
| 56 | adc2Data[x] = adc2Data[x] - BATTERY_VOLTAGE_FAST_ADC_OFFSET;
|
|---|
| 57 | adc4Data[x] = adc4Data[x] - BATTERY_VOLTAGE_FAST_ADC_OFFSET;
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| [20] | 62 | //Suche min und max werte
|
|---|
| [71] | 63 | for (x=0; x < SAMPLE_ARRAY_SIZE -1; x++)
|
|---|
| [20] | 64 | {
|
|---|
| [73] | 65 | if (adc1Data[x] <= minI) { minI = adc1Data[x]; minIPos = x; }
|
|---|
| 66 | if (adc1Data[x] >= maxI) { maxI = adc1Data[x]; maxIPos = x; }
|
|---|
| 67 | if (adc2Data[x] <= minUBatt) { minUBatt = adc2Data[x]; minUBattPos = x; }
|
|---|
| 68 | if (adc2Data[x] >= maxUBatt) { maxUBatt = adc2Data[x]; maxUBattPos = x; }
|
|---|
| 69 | if (adc4Data[x] <= minUOut) { minUOut = adc4Data[x]; minUOutPos = x; }
|
|---|
| 70 | if (adc4Data[x] >= maxUOut) { maxUOut = adc4Data[x]; maxUOutPos = x; }
|
|---|
| [20] | 71 | }
|
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 | //Delta berechnen
|
|---|
| [73] | 75 | int32_t dI;
|
|---|
| 76 | int32_t dUBatt;
|
|---|
| 77 | int32_t dUOut;
|
|---|
| [20] | 78 |
|
|---|
| [73] | 79 | if (maxIPos > minIPos)
|
|---|
| 80 | {
|
|---|
| 81 | dI = maxI - minI;
|
|---|
| 82 | //Nehme nicht mehr die gesamte maximale Differenz der Spannungen, sondern nehme das delt U wo auch das Delta I gemessen wurde
|
|---|
| 83 | //Funktioniert nur bei Synchroner Messug von Strom und Spannung
|
|---|
| 84 | //int32_t dU = maxU - minU;
|
|---|
| 85 | dUBatt= adc2Data[maxIPos] - adc2Data[minIPos];
|
|---|
| 86 | dUOut= adc4Data[maxIPos] - adc4Data[minIPos];
|
|---|
| 87 | }
|
|---|
| 88 | else
|
|---|
| 89 | {
|
|---|
| 90 | dI = minI - maxI;
|
|---|
| 91 | dUBatt= adc2Data[minIPos] - adc2Data[maxIPos];
|
|---|
| 92 | dUOut= adc4Data[minIPos] - adc4Data[maxIPos];
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 |
|
|---|
| [25] | 96 | //Umrechnung in mV / mA
|
|---|
| [73] | 97 | dI = dI * I_MULTIPLIER;
|
|---|
| 98 | dUBatt = dUBatt * U_MULTIPLIER;
|
|---|
| 99 | dUOut = dUOut * U_MULTIPLIER;
|
|---|
| [25] | 100 |
|
|---|
| [20] | 101 | //Minimale Belastung Prüfen ob es genügent Änderungen gab
|
|---|
| 102 | // 1/20 des Nennstroms
|
|---|
| 103 | // Bei 100Ah Batterie mit 0,5 Std discharge --> 50A --> /20 =2,5 A
|
|---|
| 104 | int32_t min_dI;
|
|---|
| 105 | min_dI = sys_data.s.parameter.cellCapacity / sys_data.s.parameter.cellRatedDischargeTime; //Nennlaststrom in mA
|
|---|
| [73] | 106 | min_dI = min_dI / 10 ;
|
|---|
| [25] | 107 |
|
|---|
| [20] | 108 |
|
|---|
| [71] | 109 | // int32_t min_dU = 10;
|
|---|
| [20] | 110 |
|
|---|
| [25] | 111 | if( abs(dI) < min_dI)
|
|---|
| [20] | 112 | {
|
|---|
| 113 |
|
|---|
| 114 | return -1;
|
|---|
| 115 | }
|
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| [73] | 118 |
|
|---|
| 119 |
|
|---|
| 120 | int absMax = abs(maxI);
|
|---|
| 121 | int absMin = abs(minI);
|
|---|
| 122 |
|
|---|
| 123 | //Suche die Spitze
|
|---|
| 124 | //if (absMax > absMin){
|
|---|
| 125 | // //Der größte absolut wert steht in maxI
|
|---|
| 126 | // //schauen ob die spitze nicht am Anfang oder Ende des arrays ist
|
|---|
| 127 | // if ((maxIPos < 10) || (maxIPos > 53))
|
|---|
| 128 | // {
|
|---|
| 129 | //return -3;
|
|---|
| 130 | // }
|
|---|
| 131 |
|
|---|
| 132 | //}
|
|---|
| 133 | //else
|
|---|
| 134 | //{
|
|---|
| 135 |
|
|---|
| 136 | // if ((minIPos < 10) || (minIPos > 53))
|
|---|
| 137 | // {
|
|---|
| 138 | //return -3;
|
|---|
| 139 | // }
|
|---|
| 140 | //}
|
|---|
| [55] | 141 | //if (abs(dU) < min_dU) {
|
|---|
| 142 | // return -2;
|
|---|
| 143 | //}
|
|---|
| [20] | 144 |
|
|---|
| 145 | //printf("dU change!\r\n");
|
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| [73] | 148 | // int32_t dIMax=-1;
|
|---|
| 149 | // int32_t dIx=-1;;
|
|---|
| 150 | // int32_t dIMaxPos=-1;
|
|---|
| [20] | 151 |
|
|---|
| [25] | 152 |
|
|---|
| 153 |
|
|---|
| 154 | //Finde Position der flanke
|
|---|
| [73] | 155 | // for (x=0; x < (SAMPLE_ARRAY_SIZE-2); x++)
|
|---|
| 156 | // {
|
|---|
| 157 | // dIx = adc1Data[x+1] - adc1Data[x];
|
|---|
| 158 | // if (dIx > dIMax) { dIMax = dIx; dIMaxPos = x; }
|
|---|
| 159 | // }
|
|---|
| [20] | 160 |
|
|---|
| [73] | 161 | sys_data.s.values.neg_I_peak = (minI ) * I_MULTIPLIER / 10;
|
|---|
| 162 | sys_data.s.values.pos_I_peak = (maxI ) * I_MULTIPLIER / 10 ;
|
|---|
| [20] | 163 |
|
|---|
| [73] | 164 | sys_data.s.values.neg_U_Batt_peak = (minUBatt ) * U_MULTIPLIER / 10;
|
|---|
| 165 | sys_data.s.values.pos_U_Batt_peak = (maxUBatt ) * U_MULTIPLIER / 10;
|
|---|
| 166 | sys_data.s.values.neg_U_Shunt_peak = (minUOut ) * U_MULTIPLIER / 10;
|
|---|
| 167 | sys_data.s.values.pos_U_Shunt_peak = (maxUOut ) * U_MULTIPLIER / 10;
|
|---|
| [20] | 168 |
|
|---|
| [73] | 169 | sys_data.s.values.neg_I_Buffer_pos = minIPos;
|
|---|
| 170 | sys_data.s.values.pos_I_Buffer_pos = maxIPos;
|
|---|
| 171 |
|
|---|
| 172 |
|
|---|
| 173 |
|
|---|
| [25] | 174 | //ESR berechnen!
|
|---|
| [73] | 175 | sys_data.s.values.esr_batt = ( (double)dUBatt / (double) dI) * 1000;
|
|---|
| 176 | sys_data.s.values.esr_shunt = ( (double)dUOut / (double) dI) * 1000;
|
|---|
| [25] | 177 | last_refresh = sys_data.s.values.onTime;
|
|---|
| 178 |
|
|---|
| 179 |
|
|---|
| 180 | for (x=0; x < SAMPLE_ARRAY_SIZE; x++)
|
|---|
| [20] | 181 | {
|
|---|
| [73] | 182 | sys_data.s.values.current_buffer[x] = adc1Data[x] ;
|
|---|
| 183 | sys_data.s.values.voltage_buffer_batt[x] = adc2Data[x] ;
|
|---|
| 184 | sys_data.s.values.voltage_buffer_shunt[x] = adc4Data[x] ;
|
|---|
| [25] | 185 | }
|
|---|
| [20] | 186 |
|
|---|
| 187 |
|
|---|
| [73] | 188 | //Auswertung darf nur erfolgen wenn Singulares Erreigniss nicht am Anfang oder Ende des Buffers erfolgt.
|
|---|
| 189 | //Also z.B. bei der Belastung mit elektronischer Last. Da ansonsten eventuell nicht der Beginn der Kurve mit aufgezeichnet wird
|
|---|
| 190 | //printf("delta I: %d, deltaUBatt=%d, deltaUOut=%d,posMax=%d; posMin=%d, esr1=%d, esr2=%d \r\n",dI,dUBatt,dUOut,maxIPos, minIPos,sys_data.s.values.esr_batt,sys_data.s.values.esr_shunt);
|
|---|
| [20] | 191 |
|
|---|
| 192 |
|
|---|
| [25] | 193 |
|
|---|
| [20] | 194 | return 0;
|
|---|
| 195 | }
|
|---|