V1.5: 电能日志每分钟附带电压/电流/功率显示;电压系数按49.9R修正为2.004

This commit is contained in:
helei 2026-08-14 23:55:50 +08:00
parent e8ee21b41f
commit 0b4724f96a
7 changed files with 45 additions and 8 deletions

View File

@ -39,6 +39,9 @@ static uint8_t s_idx = 0; /* ֡ͬ
static uint64_t s_total_pulses = 0; /* 累计脉冲(含 EEPROM 恢复的历史值) */ static uint64_t s_total_pulses = 0; /* 累计脉冲(含 EEPROM 恢复的历史值) */
static uint64_t s_saved_pulses = 0; /* 上次已写入 EEPROM 的值 */ static uint64_t s_saved_pulses = 0; /* 上次已写入 EEPROM 的值 */
static uint32_t s_power_par = 0; /* 功率参数寄存器(芯片常数,收到帧后才有) */ 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 uint32_t s_k = 0; /* 本次上电以来 bit7 翻转PF 溢出)次数 */ static uint32_t s_k = 0; /* 本次上电以来 bit7 翻转PF 溢出)次数 */
static uint8_t s_last_bit7 = 0; static uint8_t s_last_bit7 = 0;
@ -57,6 +60,13 @@ static void hlw8032_parse(const uint8_t *f)
if (power_par == 0) return; /* 参数寄存器异常,帧不可用 */ if (power_par == 0) return; /* 参数寄存器异常,帧不可用 */
s_power_par = power_par; s_power_par = power_par;
/* 电压/电流/功率原始寄存器(调试用,每分钟日志显示) */
s_u_par = ((uint32_t)f[2] << 16) | ((uint32_t)f[3] << 8) | f[4];
s_u_reg = ((uint32_t)f[5] << 16) | ((uint32_t)f[6] << 8) | f[7];
s_i_par = ((uint32_t)f[8] << 16) | ((uint32_t)f[9] << 8) | f[10];
s_i_reg = ((uint32_t)f[11] << 16) | ((uint32_t)f[12] << 8) | f[13];
s_p_reg = ((uint32_t)f[17] << 16) | ((uint32_t)f[18] << 8) | f[19];
uint8_t bit7 = f[20] & 0x80; uint8_t bit7 = f[20] & 0x80;
uint16_t pf = ((uint16_t)f[21] << 8) | f[22]; uint16_t pf = ((uint16_t)f[21] << 8) | f[22];
@ -141,6 +151,25 @@ float hlw8032_get_energy_kwh(void)
(double)HLW_U_COEF * (double)HLW_I_COEF / 3.6e12); (double)HLW_U_COEF * (double)HLW_I_COEF / 3.6e12);
} }
/*==== 电压/电流/功率(手册:有效值 = 参数寄存器/寄存器 × 系数)====*/
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);
}
float hlw8032_get_current_a(void)
{
if (!s_i_reg) return 0.0f;
return (float)((double)s_i_par / (double)s_i_reg * HLW_I_COEF);
}
float hlw8032_get_power_w(void)
{
if (!s_p_reg) return 0.0f;
return (float)((double)s_power_par / (double)s_p_reg * HLW_U_COEF * HLW_I_COEF);
}
/*==== 在线判断1s 内收到过有效帧 ====*/ /*==== 在线判断1s 内收到过有效帧 ====*/
uint8_t hlw8032_online(void) uint8_t hlw8032_online(void)
{ {

View File

@ -14,6 +14,9 @@ void hlw8032_rx_byte(uint8_t b); /* UART5
void hlw8032_tick(void); /* 1s 周期:到阈值就把累计脉冲写 EEPROM */ void hlw8032_tick(void); /* 1s 周期:到阈值就把累计脉冲写 EEPROM */
void hlw8032_save(void); /* 立即写 EEPROM断电预警/计划复位前调用) */ void hlw8032_save(void); /* 立即写 EEPROM断电预警/计划复位前调用) */
float hlw8032_get_energy_kwh(void); /* 累计电量 kWh未收到帧前为 0 */ float hlw8032_get_energy_kwh(void); /* 累计电量 kWh未收到帧前为 0 */
float hlw8032_get_voltage_v(void); /* 电压有效值 V调试显示用 */
float hlw8032_get_current_a(void); /* 电流有效值 A */
float hlw8032_get_power_w(void); /* 有功功率 W */
uint8_t hlw8032_online(void); /* 最近 1s 内收到过有效帧 */ uint8_t hlw8032_online(void); /* 最近 1s 内收到过有效帧 */
#endif /* __HLW8032_H */ #endif /* __HLW8032_H */

View File

@ -3,4 +3,4 @@
/* 本文件为 UTF-8 编码ARMCC 原样输出字符串字面量的字节, /* 本文件为 UTF-8 编码ARMCC 原样输出字符串字面量的字节,
* UTF-8 UTF-8 */ * UTF-8 UTF-8 */
const char FMT_UPTIME[] = "> 运行时间: %u天--%02u小时--%02u分钟"; const char FMT_UPTIME[] = "> 运行时间: %u天--%02u小时--%02u分钟";
const char FMT_UPTIME_EN[] = "> 运行时间: %u天--%02u小时--%02u分钟 电能: %.2fkWh"; const char FMT_UPTIME_EN[] = "> 运行时间: %u天--%02u小时--%02u分钟 电能: %.2fkWh 电压: %.1fV 电流: %.2fA 功率: %.1fW";

View File

@ -236,7 +236,10 @@ static void sys_task(void *arg)
log_info(FMT_UPTIME_EN, log_info(FMT_UPTIME_EN,
(unsigned)(mins / 1440), (unsigned)(mins / 1440),
(unsigned)((mins % 1440) / 60), (unsigned)((mins % 1440) / 60),
(unsigned)(mins % 60), (double)kwh); (unsigned)(mins % 60), (double)kwh,
(double)hlw8032_get_voltage_v(),
(double)hlw8032_get_current_a(),
(double)hlw8032_get_power_w());
} else { } else {
log_info(FMT_UPTIME, log_info(FMT_UPTIME,
(unsigned)(mins / 1440), (unsigned)(mins / 1440),

View File

@ -62,12 +62,12 @@ extern UART_HandleTypeDef huart3;
#define BLE_NAME "Bt1" #define BLE_NAME "Bt1"
/*===== HLW8032 电量计量系数UART5 PD2 接收,只上报累计电量) ===== /*===== HLW8032 电量计量系数UART5 PD2 接收,只上报累计电量) =====
* : ZMPT107-1(2mA:2mA) 220V 100K 50R * : ZMPT107-1(2mA:2mA) 220V 100K 49.9R
* -> = (100K/50)/1000 = 2.0 * -> = (100K/49.9)/1000 = 2.004
* : CT 100A/100mA(1000:1) 2R -> 0.002R * : CT 100A/100mA(1000:1) 2R -> 0.002R
* -> = 1/(0.002*1000) = 0.5 * -> = 1/(0.002*1000) = 0.5
* / HLW8032 */ * / HLW8032 */
#define HLW_U_COEF 2.0f #define HLW_U_COEF 2.004f
#define HLW_I_COEF 0.5f #define HLW_I_COEF 0.5f
/*===== 蓝牙 GATT UUID 配置(透传服务)===== /*===== 蓝牙 GATT UUID 配置(透传服务)=====

View File

@ -109,12 +109,13 @@
只计量**累计消耗电量**,上报平台标识符 `energy`(单位 kWh两位小数 只计量**累计消耗电量**,上报平台标识符 `energy`(单位 kWh两位小数
- **硬件**HLW80325V 供电)经 B0505S 隔离电源 + 光耦隔离,芯片 TXD 接 PD2UART5_RX电压采样 ZMPT107-12mA:2mA初级 220V 串 100K次级并 50Ω),电流采样 CT 100A/100mA1000:1输出并 2Ω三个模拟脚各对地 33nF - **硬件**HLW80325V 供电)经 B0505S 隔离电源 + 光耦隔离,芯片 TXD 接 PD2UART5_RX电压采样 ZMPT107-12mA:2mA初级 220V 串 100K次级并 49.9Ω),电流采样 CT 100A/100mA1000:1输出并 2Ω三个模拟脚各对地 33nF
- **通信**4800bps 8E1F1 上按 9 位帧长 + 偶校验配置),芯片每 50ms 主动上报 24 字节帧,只收不发;帧同步 = 首字节 0x55/0xAA/0xFx + 第二字节 0x5A + 校验和([2]~[22] 相加低 8 位) - **通信**4800bps 8E1F1 上按 9 位帧长 + 偶校验配置),芯片每 50ms 主动上报 24 字节帧,只收不发;帧同步 = 首字节 0x55/0xAA/0xFx + 第二字节 0x5A + 校验和([2]~[22] 相加低 8 位)
- **电量算法**(手册公式):`kWh = 总脉冲 × 功率参数寄存器 × 电压系数 × 电流系数 / (10^9×3600)`PF 寄存器 16 位溢出由数据更新寄存器 bit7 翻转计数(`总脉冲 = k×65536 + PF`50ms 一帧不可能漏翻转;芯片断电重启(计数值倒退)自动重新基准 - **电量算法**(手册公式):`kWh = 总脉冲 × 功率参数寄存器 × 电压系数 × 电流系数 / (10^9×3600)`PF 寄存器 16 位溢出由数据更新寄存器 bit7 翻转计数(`总脉冲 = k×65536 + PF`50ms 一帧不可能漏翻转;芯片断电重启(计数值倒退)自动重新基准
- **系数宏**`main.h` 的 `HLW_U_COEF`=100K/50/1000=2.0)、`HLW_I_COEF`=1/(0.002×1000)=0.5)——改电阻/互感器只动这两个宏 - **系数宏**`main.h` 的 `HLW_U_COEF`=100K/49.9/1000=2.004)、`HLW_I_COEF`=1/(0.002×1000)=0.5)——改电阻/互感器只动这两个宏
- **持久化**累计脉冲数uint64存 EEPROM 偏移 164~171每攒约 0.1kWh 写一次(限制擦写),断电预警(法拉电容续航内)立即写一次,掉电损失 <0.1kWh - **持久化**累计脉冲数uint64存 EEPROM 偏移 164~171每攒约 0.1kWh 写一次(限制擦写),断电预警(法拉电容续航内)立即写一次,掉电损失 <0.1kWh
- **上报**MQTT 就绪且芯片在线1s 内有有效帧)时,每分钟随运行心跳上报一次 `{"energy":%.2f}`;未联网/芯片不在线不上报 - **上报**MQTT 就绪且芯片在线1s 内有有效帧)时,每分钟随运行心跳上报一次 `{"energy":%.2f}`;未联网/芯片不在线不上报
- **调试日志**:芯片在线时每分钟日志同时打印电压/电流/功率(`运行时间: ... 电能: x.xxkWh 电压: xxx.xV 电流: x.xxA 功率: xxxx.xW`
## 双通道网络4G 优先WiFi 兜底) ## 双通道网络4G 优先WiFi 兜底)

View File

@ -100,7 +100,8 @@
帧同步(0x55/0xAA/0xFx + 0x5A)+校验和验证;只取 PF 脉冲累计换算累计电量 帧同步(0x55/0xAA/0xFx + 0x5A)+校验和验证;只取 PF 脉冲累计换算累计电量
- 电量按手册公式换算kWh = 总脉冲×功率参数×电压系数×电流系数/(10^9×3600) - 电量按手册公式换算kWh = 总脉冲×功率参数×电压系数×电流系数/(10^9×3600)
PF 16 位溢出靠数据更新寄存器 bit7 翻转计数50ms 一帧不会漏);芯片断电重启自动重新基准 PF 16 位溢出靠数据更新寄存器 bit7 翻转计数50ms 一帧不会漏);芯片断电重启自动重新基准
- 系数宏 `HLW_U_COEF`(2.0)/`HLW_I_COEF`(0.5) 在 main.h对应 ZMPT107-1(100K/50R)+CT 1000:1(2R) - 系数宏 `HLW_U_COEF`(2.004)/`HLW_I_COEF`(0.5) 在 main.h对应 ZMPT107-1(100K/49.9R)+CT 1000:1(2R)
- 芯片在线时每分钟日志打印电压/电流/功率/电能(调试校准用)
- 累计脉冲(uint64)持久化 EEPROM 偏移 164每攒约 0.1kWh 写一次 + 断电预警时立即写(法拉电容续航内) - 累计脉冲(uint64)持久化 EEPROM 偏移 164每攒约 0.1kWh 写一次 + 断电预警时立即写(法拉电容续航内)
- 平台上报标识符 `energy`kWh 两位小数MQTT 就绪且芯片在线时每分钟一次4G/WiFi 双通道 - 平台上报标识符 `energy`kWh 两位小数MQTT 就绪且芯片在线时每分钟一次4G/WiFi 双通道
- UART5 带 ORE 自愈硬件B0505S 隔离电源 + 光耦,芯片 TXD 接 PD2 - UART5 带 ORE 自愈硬件B0505S 隔离电源 + 光耦,芯片 TXD 接 PD2