forked from achamaikin/CCSModuleSW30Web
52 lines
1.7 KiB
C
Executable File
52 lines
1.7 KiB
C
Executable File
#include "meter.h"
|
||
|
||
#include "charger_control.h"
|
||
|
||
|
||
METER_t METER;
|
||
|
||
// Функция для расчета и накопления энергии c дробной частью без счетчиков
|
||
void METER_CalculateEnergy() {
|
||
// Проверяем, что индекс находится в пределах массива
|
||
|
||
METER.online = 0;
|
||
|
||
if(CONN.connState == Charging){
|
||
METER.enable = 1;
|
||
}else{
|
||
METER.enable = 0;
|
||
}
|
||
|
||
uint32_t currentTick = HAL_GetTick(); // Получаем текущее время в миллисекундах
|
||
uint32_t elapsedTimeMs = currentTick - METER.lastTick; // Вычисляем время, прошедшее с последнего вызова в секундах
|
||
METER.lastTick = currentTick; // Обновляем время последнего вызова для текущего коннектора
|
||
// uint64: Power*dt can exceed 2^32 at high power / long dt
|
||
uint64_t energyWs = ((uint64_t)CONN.Power * elapsedTimeMs) / 1000U;
|
||
|
||
//Расчет энергии теперь идет всегда, смещение берем суммарное
|
||
METER.EnergyPSU_Ws += energyWs;
|
||
|
||
// Divide in 64-bit first — casting Ws to uint32 before /3600 truncates ~1193 kWh
|
||
METER.AbsoluteEnergy = (uint32_t)(METER.EnergyPSU_Ws / 3600U);
|
||
|
||
if(METER.enable) {
|
||
//enabled state
|
||
if (METER.AbsoluteEnergy >= METER.EnergyOffset) {
|
||
CONN.Energy = METER.AbsoluteEnergy - METER.EnergyOffset;
|
||
} else {
|
||
// Guard unsigned underflow (e.g. after Absolute wrap anomaly)
|
||
CONN.Energy = 0;
|
||
METER.EnergyOffset = METER.AbsoluteEnergy;
|
||
}
|
||
|
||
}else{
|
||
// Reset statе
|
||
CONN.Energy = 0;
|
||
|
||
METER.EnergyOffset = METER.AbsoluteEnergy;
|
||
|
||
}
|
||
|
||
|
||
}
|