#include "sysdata.h" #include "esr.h" #include #include #include "main.h" #include "battery_voltage_fast.h" #include "fast_current.h" #define I_MULTIPLIER ((int64_t) VREF / FAST_CURRENT_SHUNT_RESISTOR / FAST_CURRENT_I_SENSE_GAIN / FAST_CURRENT_ADC_RESOLUTION) #define U_MULTIPLIER ((int64_t) VREF * BATTERY_VOLTAGE_VOLTAGE_DIVIDER / BATTERY_VOLTAGE_FAST_ADC_RESOLUTION ) int32_t current_buffer[SAMPLE_ARRAY_SIZE]; int32_t voltage_buffer[SAMPLE_ARRAY_SIZE]; extern int32_t adc1Data[SAMPLE_ARRAY_SIZE]; extern int32_t adc2Data[SAMPLE_ARRAY_SIZE]; extern int32_t adc4Data[SAMPLE_ARRAY_SIZE]; int16_t ESR_FAST_Exec(void) { // printf("esr\r\n"); static int32_t last_refresh; int x; //Anzeige vor wieviel Sekunden zuletzt aktualisiert wurd. //Aktuell erfolgt nur die Anze der low speed Methode //sys_data.s.values.esrCalcTime = sys_data.s.values.onTime - last_refresh; //Suche Min und max werte im Array int32_t minUBatt=INT32_MAX; int32_t maxUBatt=INT32_MIN; int32_t minUOut=INT32_MAX; int32_t maxUOut=INT32_MIN; int32_t minI=INT32_MAX; int32_t maxI=INT32_MIN; int32_t minIPos = -1; int32_t maxIPos = -1; int32_t minUBattPos = -1; int32_t maxUBattPos = -1; int32_t minUOutPos = -1; int32_t maxUOutPos = -1; //Entferne Offset for (x=0; x < SAMPLE_ARRAY_SIZE -1; x++) { adc1Data[x] = adc1Data[x] - FAST_CURRENT_ADC_OFFSET; adc2Data[x] = adc2Data[x] - BATTERY_VOLTAGE_FAST_ADC_OFFSET; adc4Data[x] = adc4Data[x] - BATTERY_VOLTAGE_FAST_ADC_OFFSET; } //Suche min und max werte for (x=0; x < SAMPLE_ARRAY_SIZE -1; x++) { if (adc1Data[x] <= minI) { minI = adc1Data[x]; minIPos = x; } if (adc1Data[x] >= maxI) { maxI = adc1Data[x]; maxIPos = x; } if (adc2Data[x] <= minUBatt) { minUBatt = adc2Data[x]; minUBattPos = x; } if (adc2Data[x] >= maxUBatt) { maxUBatt = adc2Data[x]; maxUBattPos = x; } if (adc4Data[x] <= minUOut) { minUOut = adc4Data[x]; minUOutPos = x; } if (adc4Data[x] >= maxUOut) { maxUOut = adc4Data[x]; maxUOutPos = x; } } //Delta berechnen int32_t dI; int32_t dUBatt; int32_t dUOut; if (maxIPos > minIPos) { dI = maxI - minI; //Nehme nicht mehr die gesamte maximale Differenz der Spannungen, sondern nehme das delt U wo auch das Delta I gemessen wurde //Funktioniert nur bei Synchroner Messug von Strom und Spannung //int32_t dU = maxU - minU; dUBatt= adc2Data[maxIPos] - adc2Data[minIPos]; dUOut= adc4Data[maxIPos] - adc4Data[minIPos]; } else { dI = minI - maxI; dUBatt= adc2Data[minIPos] - adc2Data[maxIPos]; dUOut= adc4Data[minIPos] - adc4Data[maxIPos]; } //Umrechnung in mV / mA dI = dI * I_MULTIPLIER; dUBatt = dUBatt * U_MULTIPLIER; dUOut = dUOut * U_MULTIPLIER; //Minimale Belastung Prüfen ob es genügent Änderungen gab // 1/20 des Nennstroms // Bei 100Ah Batterie mit 0,5 Std discharge --> 50A --> /20 =2,5 A int32_t min_dI; min_dI = sys_data.s.parameter.cellCapacity / sys_data.s.parameter.cellRatedDischargeTime; //Nennlaststrom in mA min_dI = min_dI / 10 ; // int32_t min_dU = 10; if( abs(dI) < min_dI) { return -1; } int absMax = abs(maxI); int absMin = abs(minI); //Suche die Spitze //if (absMax > absMin){ // //Der größte absolut wert steht in maxI // //schauen ob die spitze nicht am Anfang oder Ende des arrays ist // if ((maxIPos < 10) || (maxIPos > 53)) // { //return -3; // } //} //else //{ // if ((minIPos < 10) || (minIPos > 53)) // { //return -3; // } //} //if (abs(dU) < min_dU) { // return -2; //} //printf("dU change!\r\n"); // int32_t dIMax=-1; // int32_t dIx=-1;; // int32_t dIMaxPos=-1; //Finde Position der flanke // for (x=0; x < (SAMPLE_ARRAY_SIZE-2); x++) // { // dIx = adc1Data[x+1] - adc1Data[x]; // if (dIx > dIMax) { dIMax = dIx; dIMaxPos = x; } // } sys_data.s.values.neg_I_peak = (minI ) * I_MULTIPLIER / 10; sys_data.s.values.pos_I_peak = (maxI ) * I_MULTIPLIER / 10 ; sys_data.s.values.neg_U_Batt_peak = (minUBatt ) * U_MULTIPLIER / 10; sys_data.s.values.pos_U_Batt_peak = (maxUBatt ) * U_MULTIPLIER / 10; sys_data.s.values.neg_U_Shunt_peak = (minUOut ) * U_MULTIPLIER / 10; sys_data.s.values.pos_U_Shunt_peak = (maxUOut ) * U_MULTIPLIER / 10; sys_data.s.values.neg_I_Buffer_pos = minIPos; sys_data.s.values.pos_I_Buffer_pos = maxIPos; //ESR berechnen! sys_data.s.values.esr_batt = ( (double)dUBatt / (double) dI) * 1000; sys_data.s.values.esr_shunt = ( (double)dUOut / (double) dI) * 1000; last_refresh = sys_data.s.values.onTime; for (x=0; x < SAMPLE_ARRAY_SIZE; x++) { sys_data.s.values.current_buffer[x] = adc1Data[x] ; sys_data.s.values.voltage_buffer_batt[x] = adc2Data[x] ; sys_data.s.values.voltage_buffer_shunt[x] = adc4Data[x] ; } //Auswertung darf nur erfolgen wenn Singulares Erreigniss nicht am Anfang oder Ende des Buffers erfolgt. //Also z.B. bei der Belastung mit elektronischer Last. Da ansonsten eventuell nicht der Beginn der Kurve mit aufgezeichnet wird //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); return 0; }