V1.5: 电压/电流/功率加EMA滑动平均滤波(1/8系数约0.4s响应),压空载功率跳变

This commit is contained in:
helei 2026-08-15 08:04:13 +08:00
parent 7500acb041
commit 6c89a0d049
1 changed files with 20 additions and 10 deletions

View File

@ -42,6 +42,7 @@ static uint32_t s_power_par = 0; /*
static uint32_t s_u_par = 0, s_u_reg = 0; /* 电压参数/电压寄存器(显示电压用) */
static uint32_t s_i_par = 0, s_i_reg = 0; /* 电流参数/电流寄存器 */
static uint32_t s_p_reg = 0; /* 功率寄存器 */
static float s_u_f = 0, s_i_f = 0, s_p_f = 0; /* 电压/电流/功率 EMA 滤波值 */
static uint32_t s_k = 0; /* 本次上电以来 bit7 翻转PF 溢出)次数 */
static uint8_t s_last_bit7 = 0;
@ -97,6 +98,17 @@ static void hlw8032_parse(const uint8_t *f)
if (s_streak < 3) return; /* 未确认同步:帧内容一律不采用 */
}
/* EMA 滑动平均(系数 1/8约 0.4s 响应):压空载噪声跳变,
* <0.5s使 */
{
float u = s_u_reg ? (float)((double)s_u_par / (double)s_u_reg * HLW_U_COEF) : 0.0f;
float a = s_i_reg ? (float)((double)s_i_par / (double)s_i_reg * HLW_I_COEF) : 0.0f;
float w = s_p_reg ? (float)((double)s_power_par / (double)s_p_reg * HLW_U_COEF * HLW_I_COEF) : 0.0f;
s_u_f += (u - s_u_f) * 0.125f;
s_i_f += (a - s_i_f) * 0.125f;
s_p_f += (w - s_p_f) * 0.125f;
}
uint32_t chip_total = s_k * HLW_OVERFLOW_PULSES + pf;
if (s_synced) {
/* 正常单调递增;变小说明芯片断电重启过(寄存器清零),从当前值重新累计 */
@ -185,24 +197,22 @@ float hlw8032_get_energy_kwh(void)
/*==== 电压/电流/功率(手册:有效值 = 参数寄存器/寄存器 × 系数)====*/
float hlw8032_get_voltage_v(void)
{
if (!s_u_reg) return 0.0f;
return (float)((double)s_u_par / (double)s_u_reg * HLW_U_COEF);
if (!s_synced) return 0.0f;
return s_u_f;
}
float hlw8032_get_current_a(void)
{
if (!s_i_reg) return 0.0f;
float a = (float)((double)s_i_par / (double)s_i_reg * HLW_I_COEF);
a -= HLW_I_ZERO_A; /* 减零点偏移 */
return a > 0.0f ? a : 0.0f; /* 钳位到 0 */
if (!s_synced) return 0.0f;
float a = s_i_f - HLW_I_ZERO_A; /* 减零点偏移 */
return a > 0.0f ? a : 0.0f; /* 钳位到 0 */
}
float hlw8032_get_power_w(void)
{
if (!s_p_reg) return 0.0f;
float w = (float)((double)s_power_par / (double)s_p_reg * HLW_U_COEF * HLW_I_COEF);
if (w < HLW_P_DEAD_W) return 0.0f; /* 死区:空载噪声底显示 0 */
return w - HLW_P_ZERO_W;
if (!s_synced) return 0.0f;
if (s_p_f < HLW_P_DEAD_W) return 0.0f; /* 死区:空载噪声底显示 0 */
return s_p_f - HLW_P_ZERO_W;
}
/*==== 在线判断1s 内收到过有效帧 ====*/