#include "electricity.h" #include "uart.h" #include "common.h" #include "board_cfg.h" #include "Hlw8110.h" #include "relay.h" static board_t *board = 0; static void read_ele(uint8_t channel); static void check_wanning(uint8_t in_out,uint8_t channel); static void opt_over_func(uint8_t channel); #define AC3PPDU_Lack_Voltage (30000) extern float F_AC_V; extern float F_AC_I; extern float F_AC_P; extern float F_AC_LINE_Freq; extern float F_AC_E; extern float F_AC_PF; extern float F_AC_PS; float elec[RelaySlaveChaNum] = {0.0}; void electricity_init(void) { board = get_board(); uart1_config(9600); ch448f_config(); for(int i = 0 ; i < RelaySlaveChaNum;i++) { select_channel(i); Init_HLW8110(); } board->read_ele = read_ele; board->check_wanning = check_wanning; board->opt_overfunc = opt_over_func; } static void read_ele(uint8_t channel) { if(channel < RelaySlaveChaNum) { select_channel(channel); Calculate_HLW8110_MeterData(); if(F_AC_V > 20 && F_AC_LINE_Freq < 1.0) { reinit_hlw8110(); Calculate_HLW8110_MeterData(); } if(F_AC_V < 1.0) { F_AC_V = 0.0; F_AC_I = 0.0; F_AC_P = 0.0; F_AC_PS = 0.0; F_AC_LINE_Freq = 0.0; F_AC_PF = 0.0; }else if(F_AC_PF < 0.1 || F_AC_PF > 1 || F_AC_P < 1) { F_AC_I = 0.0; F_AC_P = 0.0; F_AC_PS = 0.0; F_AC_PF = 0.0; } board->md_data.r_data.output[channel].voltage = F_AC_V * 1000; board->md_data.r_data.output[channel].current = F_AC_I * 1000; board->md_data.r_data.output[channel].power = F_AC_P * 1000; board->md_data.r_data.output[channel].freq = F_AC_LINE_Freq * 1000; board->md_data.r_data.output[channel].factor = F_AC_PF * 1000; board->md_data.r_data.output[channel].n_power = F_AC_PS * 1000; elec[channel] += F_AC_E; board->md_data.r_data.output[channel].consumer = board->ele_restore[channel] + (uint32_t)(elec[channel] * 1000); board->md_data.r_data.output[channel].s_power = (F_AC_PF > 0) ? ((F_AC_P / F_AC_PF)-F_AC_PS) *1000 : 0; } } static uint16_t count = 0; static void check_wanning(uint8_t in_out,uint8_t channel) { if(in_out == ELE_INPUT) { #if (AC_3_3 || AC_3_4) board->md_data.r_data.i_voltage[A] = board->md_data.r_data.output[A].voltage; board->md_data.r_data.i_voltage[B] = board->md_data.r_data.output[B].voltage; board->md_data.r_data.i_voltage[C] = board->md_data.r_data.output[C].voltage; board->md_data.r_data.i_current[A] = board->md_data.r_data.output[A].current; board->md_data.r_data.i_current[B] = board->md_data.r_data.output[B].current; board->md_data.r_data.i_current[C] = board->md_data.r_data.output[C].current; board->md_data.r_data.i_power[A] = board->md_data.r_data.output[A].power; board->md_data.r_data.i_power[B] = board->md_data.r_data.output[B].power; board->md_data.r_data.i_power[C] = board->md_data.r_data.output[C].power; board->md_data.r_data.i_consumer[A] = board->md_data.r_data.output[A].consumer; board->md_data.r_data.i_consumer[B] = board->md_data.r_data.output[B].consumer; board->md_data.r_data.i_consumer[C] = board->md_data.r_data.output[C].consumer; #else //voltage uint32_t _data = 0; for(int i = 0 ; i < PT_SUB_COUNT;i++) { _data = (board->md_data.r_data.output[i].voltage > _data) ? board->md_data.r_data.output[i].voltage : _data; } board->md_data.r_data.i_voltage[A] = _data; _data = 0; for(int i = PT_SUB_COUNT ; i < RelaySlaveChaNum;i++) { _data = (board->md_data.r_data.output[i].voltage > _data) ? board->md_data.r_data.output[i].voltage : _data; } board->md_data.r_data.i_voltage[B] = _data; //current _data = 0; for(int i = 0 ; i < PT_SUB_COUNT;i++) { _data += board->md_data.r_data.output[i].current; } board->md_data.r_data.i_current[A] = _data; _data = 0; for(int i = PT_SUB_COUNT ; i < RelaySlaveChaNum;i++) { _data += board->md_data.r_data.output[i].current; } board->md_data.r_data.i_current[B] = _data; //power _data = 0; for(int i = 0 ; i < PT_SUB_COUNT;i++) { _data += board->md_data.r_data.output[i].power; } board->md_data.r_data.i_power[A] = _data; _data = 0; for(int i = PT_SUB_COUNT ; i < RelaySlaveChaNum;i++) { _data += board->md_data.r_data.output[i].power; } board->md_data.r_data.i_power[B] = _data; //consumer _data = 0; for(int i = 0 ; i < PT_SUB_COUNT;i++) { _data += board->md_data.r_data.output[i].consumer; } board->md_data.r_data.i_consumer[A] = _data; _data = 0; for(int i = PT_SUB_COUNT ; i < RelaySlaveChaNum;i++) { _data += board->md_data.r_data.output[i].consumer; } board->md_data.r_data.i_consumer[B] = _data; #endif uint32_t Vmax = 0; uint32_t Vmin = 0; uint32_t sort_buff[3] = {0}; sort_buff[0] = board->md_data.r_data.i_voltage[A]; sort_buff[1] = board->md_data.r_data.i_voltage[B]; #if (AC_3_3 || AC_3_4) sort_buff[2] = board->md_data.r_data.i_voltage[C]; Vmax = (sort_buff[0] >= sort_buff[1]) ? sort_buff[0] :sort_buff[1]; Vmax = (Vmax >= sort_buff[2]) ? Vmax : sort_buff[2]; Vmin = (sort_buff[0] <= sort_buff[1]) ? sort_buff[0] :sort_buff[1]; Vmin = (Vmin <= sort_buff[2]) ? Vmin : sort_buff[2]; #else Vmax = sort_buff[0] >sort_buff[1] ? sort_buff[0] : sort_buff[1]; Vmin = sort_buff[0] >sort_buff[1] ? sort_buff[1] : sort_buff[2]; #endif if((Vmin < AC3PPDU_Lack_Voltage) && (Vmax != 0) && (Vmax > (AC3PPDU_Lack_Voltage*2))) { uint32_t v_mid = AC3PPDU_Lack_Voltage *2; count ++; if(count == 2) { if(board->md_data.r_data.i_voltage[A] < v_mid) { board->md_data.r_data.Lack_A = WANNING_SET; } if(board->md_data.r_data.i_voltage[B] < v_mid) { board->md_data.r_data.Lack_B = WANNING_SET; } #if(AC_3_3 || AC_3_4) if(board->md_data.r_data.i_voltage[C] < v_mid) { board->md_data.r_data.Lack_C = WANNING_SET; } #endif count = 0; } }else { board->md_data.r_data.Lack_A = WANNING_UNSET; board->md_data.r_data.Lack_B = WANNING_UNSET; #if(AC_3_3 || AC_3_4) board->md_data.r_data.Lack_C = WANNING_UNSET; #endif count = 0; } board->md_data.r_data.w_input.v_A_up = (board->md_data.r_data.i_voltage[A] > board->md_data.rw_data.i_V_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.v_B_up = (board->md_data.r_data.i_voltage[B] > board->md_data.rw_data.i_V_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.v_A_low = (board->md_data.r_data.i_voltage[A] < board->md_data.rw_data.i_V_min) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.v_B_low = (board->md_data.r_data.i_voltage[B] < board->md_data.rw_data.i_V_min) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.i_A_up = (board->md_data.r_data.i_current[A] > board->md_data.rw_data.i_I_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.i_B_up = (board->md_data.r_data.i_current[B] > board->md_data.rw_data.i_I_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.p_A_up = (board->md_data.r_data.i_power[A] > board->md_data.rw_data.i_P_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.p_B_up = (board->md_data.r_data.i_power[B] > board->md_data.rw_data.i_P_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.c_A_up = (board->md_data.r_data.i_consumer[A] > board->md_data.rw_data.i_C_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.c_B_up = (board->md_data.r_data.i_consumer[B] > board->md_data.rw_data.i_C_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.lack_A = board->md_data.r_data.Lack_A; board->md_data.r_data.w_input.lack_B = board->md_data.r_data.Lack_B; #if(AC_3_3 || AC_3_4) board->md_data.r_data.w_input.v_C_up = (board->md_data.r_data.i_voltage[C] > board->md_data.rw_data.i_V_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.v_C_low = (board->md_data.r_data.i_voltage[C] < board->md_data.rw_data.i_V_min) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.i_C_up = (board->md_data.r_data.i_current[C] > board->md_data.rw_data.i_I_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.p_C_up = (board->md_data.r_data.i_power[C] > board->md_data.rw_data.i_P_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.c_C_up = (board->md_data.r_data.i_consumer[C] > board->md_data.rw_data.i_C_max) ? WANNING_SET : WANNING_UNSET; board->md_data.r_data.w_input.lack_C = board->md_data.r_data.Lack_C; #endif }else { if(channel < RelaySlaveChaNum) { if(IS_VOLTAGE_MAX_EN(board->out_wanning_en[channel]) && board->md_data.r_data.output[channel].voltage > board->md_data.rw_data.o_V_max[channel]) { board->md_data.r_data.wanning[channel].v_up = WANNING_SET; if(board->md_data.rw_data.over_func[channel].v_up_func) { board->over_func[channel] = 1; } }else { board->md_data.r_data.wanning[channel].v_up = WANNING_UNSET; } if(IS_VOLTAGE_MIN_EN(board->out_wanning_en[channel]) && board->md_data.r_data.output[channel].voltage < board->md_data.rw_data.o_V_min[channel]) { board->md_data.r_data.wanning[channel].v_low = WANNING_SET; if(board->md_data.rw_data.over_func[channel].v_low_func) { board->over_func[channel] = 1; } }else { board->md_data.r_data.wanning[channel].v_low = WANNING_UNSET; } if(IS_CURRENT_MAX_EN(board->out_wanning_en[channel]) && board->md_data.r_data.output[channel].current > board->md_data.rw_data.o_I_max[channel]) { board->md_data.r_data.wanning[channel].i_up = WANNING_SET; if(board->md_data.rw_data.over_func[channel].i_up_func) { board->over_func[channel] = 1; } }else { board->md_data.r_data.wanning[channel].i_up = WANNING_UNSET; } if(IS_POWER_MAX_EN(board->out_wanning_en[channel]) && board->md_data.r_data.output[channel].power > board->md_data.rw_data.o_P_max[channel]) { board->md_data.r_data.wanning[channel].p_up = WANNING_SET; if(board->md_data.rw_data.over_func[channel].p_up_func) { board->over_func[channel] = 1; } }else { board->md_data.r_data.wanning[channel].p_up = WANNING_UNSET; } if(IS_CONSUMER_MAX_EN(board->out_wanning_en[channel]) && board->md_data.r_data.output[channel].consumer > board->md_data.rw_data.o_C_max[channel]) { board->md_data.r_data.wanning[channel].c_up = WANNING_SET; if(board->md_data.rw_data.over_func[channel].c_up_func) { board->over_func[channel] = 1; } }else { board->md_data.r_data.wanning[channel].c_up = WANNING_UNSET; } } } } static void opt_over_func(uint8_t channel) { #if (AC_3_3 || AC_3_4) for(int i = 0; i < RelaySlaveChaNum ;i+=3) { if(board->md_data.rw_data.channel_ctrl[i ] == 0 && board->md_data.rw_data.channel_ctrl[i+1] == 0 && board->md_data.rw_data.channel_ctrl[i+2] == 0) { if(board->over_func[i] || board->over_func[i+1] || board->over_func[i+2]) //3 pha { board->over_func[i ] = 1; board->over_func[i+1] = 1; board->over_func[i+2] = 1; #if SUPPORT_ZERO_CRTL board->n_over_func = 1; #endif } } } async_data da = {0}; da.method = PROMPT_CTRL; da.status = RELAY_CLOSE; da.w_eep_flag = FLAG_N_W_EEP; for(int i = 0; i < RelaySlaveChaNum ;i++) { if(board->over_func[i]) { board->over_func[i] = 0; if(board->md_data.r_data.status[i] == RELAY_OPEN) { da.channel = i; da.fire_or_zero = _FIRE; da.reg = &board->relay_staging_staus[i]; set_relay_sta_async(&da); } } } #if SUPPORT_ZERO_CRTL if(board->n_over_func) { board->n_over_func = 0; if(board->md_data.r_data.N_status == RELAY_OPEN) { da.channel = 0; da.fire_or_zero = _ZERO; da.reg = &board->relay_zero_staging_status; set_relay_sta_async(&da); } } #endif #else for(int i = 0; i < PT_SUB_COUNT ;i++) { if(board->md_data.rw_data.channel_ctrl[i ] == 0 && board->md_data.rw_data.channel_ctrl[i + PT_SUB_COUNT] == 0) { if(board->over_func[i] || board->over_func[i+PT_SUB_COUNT]) { board->over_func[i] = board->over_func[i+PT_SUB_COUNT] = 1; } } } async_data da = {0}; da.method = PROMPT_CTRL; da.status = RELAY_CLOSE; da.w_eep_flag = FLAG_N_W_EEP; for(int i = 0; i < RelaySlaveChaNum ;i++) { if(board->over_func[i]) { board->over_func[i] = 0; if(board->md_data.r_data.status[i] == RELAY_OPEN) { da.channel = i; da.fire_or_zero = _FIRE; da.reg = &board->relay_staging_staus[i]; set_relay_sta_async(&da); } } } #endif }