#include "sysdata.h" #include "self_discharge.h" #define HOLD_TIME ( 3 * 3600 ) // 3 stunde #define SD_FILTER 64 int16_t SELF_DISCHARGE_Exec(void) { const double batt_float_voltage_tol = 0.03; const double batt_voltage_holding_tol = 10; int32_t max_u = sys_data.s.parameter.uBatFull * ( 1 + batt_float_voltage_tol); int32_t min_u = sys_data.s.parameter.uBatFull * ( 1 - batt_float_voltage_tol); static uint32_t holding_counter = 0; static int32_t u_hold = 0; sys_data.s.values.selfDischargeTime = holding_counter; int32_t u = sys_data.s.values.batteryVoltage; if (u > max_u) { u_hold = 0; holding_counter = 0; return -1; } if (u < min_u) { u_hold = 0; holding_counter = 0; return -1; } //Bin im richtigen Spannungsbereich, zu haltende Spannung speichern if (u_hold == 0) { u_hold = u; } int32_t u_hold_max = u_hold + batt_voltage_holding_tol; int32_t u_hold_min = u_hold - batt_voltage_holding_tol; if (u > u_hold_max) { u_hold = 0; holding_counter = 0; return -2; } if (u < u_hold_min) { u_hold = 0; holding_counter = 0; return -2; } holding_counter++; if (holding_counter > HOLD_TIME) { sys_data.s.values.selfDischarge = sys_data.s.values.batteryCurrent; } // --- Mittelwert --- static uint32_t last_days; static unsigned long avgsum = 0; // Converting seconds into days uint32_t days = sys_data.s.values.onTime / (24U * 3600U); // Alle 24 Stunden ein Wert zur Mittelwertberechnung hinzufügen if (days != last_days) { last_days = days; uint32_t avgval; // Filterlängen in 2er-Potenzen --> Compiler optimiert avgsum -= avgsum/SD_FILTER; avgsum += sys_data.s.values.selfDischarge; avgval = avgsum / SD_FILTER; sys_data.s.values.selfDischargeAvg = avgval; } return 0; }