#include "board.h" #include "base_types.h" #include "check.h" #include "param.h" #include "lcd_disp.h" #include "tdc_tof.h" #include "prj_com.h" #include "stat.h" #include "app_nb.h" #include "alarm.h" #include "bill.h" float RefFlow = 2000; extern void SaveParam(void); static volatile check_t Check; static volatile uint16_t rx_state; static volatile uint16_t rx_data_len; static volatile uint8_t cmd; uint8_t G_STATIC_OT_SETTING_FLAG = 0; // 20260429 正在设置静态OT,不进行飞行时间差滤波 // add by yuewei 20260424, for lcd display "ot-Err" uint8_t G_OT_ERROR_FLAG_CNT = 0; // add by yuewei 20260318, for lcd display remain time uint16_t ot_count_down = 0; // add by yuewei 20260309,to tell rtc hongwai start receive long data uint8_t HONGWAI_LONG_RX_FLAG = 0; // defalt:0,long data:1 uint32_t GetCheckState(void) { return Check.state; } uint32_t GetCheckPulse(void) { return Check.total_pulse; } void SetCheckFlow(double cum_flow, float spdLvl, float temp) { if (Check.state == CHECKED) { Check.start_cum_flow = cum_flow; // unit: cm^3 Check.curr_cum_flow = cum_flow; // unit: cm^3 Check.flow_cnt = 0; Check.total_spd_lvl = 0.0f; Check.total_water_temp = 0.0f; return; } Param_t *param; Check.curr_cum_flow = cum_flow; // unit: cm^3 Check.total_spd_lvl += spdLvl; Check.total_water_temp += temp; Check.flow_cnt++; GetParam(¶m); // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_index = CheckTempRangeIndex((float)(Check.total_water_temp / Check.flow_cnt)); uint16_t temp_index = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_index]); uint8_t c_idx = CheckCValueIndex(temp_index, (uint16_t)(Check.total_spd_lvl / Check.flow_cnt)); LOG("++++++++++++++++++++++c_idx=%d\n",c_idx); // Pb = Vs*6400*q/C Vs unit: L 6.4 = 6400 / 1000 // modified by yuewei 20260317 change q_value to q // Check.total_pulse = (uint32_t)((Check.curr_cum_flow - Check.start_cum_flow) / p->cur_c[c_idx] * 6.4 * param->q_value); Check.total_pulse = (uint32_t)((Check.curr_cum_flow - Check.start_cum_flow) / p->cur_c[c_idx] * 6.4 * param->q); } void check_init(void) { Check.state = CHECKED; Finsh_Uart_Mode |= CHECK_ITF_ON; Check.rx_idx = 0; Check.rx_over_time = 0; Check.rx_err = 0; Check.start_cum_flow = 0.0f; Check.curr_cum_flow = 0.0f; Check.flow_cnt = 0; Check.flow_rate = 0; Check.c_point_idx = 0; Check.total_pulse = 0; Check.checking_cnt = 0; Check.start_time = 0; Check.end_time = 0; rx_data_len = 0; rx_state = CHECK_RX_HEAD; } void CheckRxErr(void) { HONGWAI_LONG_RX_FLAG = 0; // add by yuewei 20260309 to deal hongwai long data ///////////////////////////// if (Check.rx_idx <= 4) // one byte recieved, it's interference, ignore it wxl2026-6-1 { rx_data_len = 0; rx_state = CHECK_RX_HEAD; return; } //////////////////////////////// // Check.tx_buf[0]='Y'; // Check.tx_buf[1]='0'+Check.rx_idx; // Check.tx_buf[2]=' '; // finsh_tx(Check.tx_buf, 3); Check.rx_err |= CHECK_RX_ERROR; ////////////////// // LOG("-%x-\r\n",Check.rx_buf[0]); //////////////////// Check.rx_idx = 0; if (Check.state == CHECKED || Check.state == CHECKING) // add by HBR 2026052109 to CHECKING ERR_H { lcd_set_timer(2); // modifed by yuewei 30->2, to display Err-H 5 Seconds } rx_data_len = 0; rx_state = CHECK_RX_HEAD; } void CheckRxData(volatile uint8_t data) { // volatile uint8_t cmd; uint8_t crc; uint16_t crc16; // add by yuewei 20260305 if (finsh_txing_flag == 1) { return; } if (rx_state == CHECK_RX_HEAD) { if (data == 0x68) { Check.rx_buf[Check.rx_idx++] = data; rx_state = CHECK_RX_CMD; } else if (data == 0xfe) { return; } else { // LOG("----------------------------1\n"); // LOG("Check.rx_idx=%d,data=%x\n",Check.rx_idx,data); if (Check.rx_idx >= 2) { CheckRxErr(); } return; } } else if (rx_state == CHECK_RX_CMD) { if (data >= 0x00) { Check.rx_buf[Check.rx_idx++] = data; // add by yuewei 20260317 if (data == 0xA5) { rx_state = CHECK_RX_CRC_MODBUS; } else { rx_state = CHECK_RX_S_ADDR; } } else { CheckRxErr(); // LOG("----------------------------2\n"); return; } } else if (rx_state == CHECK_RX_S_ADDR) { Check.rx_buf[Check.rx_idx++] = data; if (Check.rx_idx >= 5) { rx_state = CHECK_RX_D_ADDR; } } else if (rx_state == CHECK_RX_D_ADDR) { Check.rx_buf[Check.rx_idx++] = data; if (Check.rx_idx >= 8) { cmd = Check.rx_buf[1]; if (cmd == 0x00 || cmd == 0x10 || cmd == 0x11 || cmd == 0x12 // add by yuewei 20260316 || cmd == 0x13 || cmd == 0x14 || cmd == 0x15 || cmd == 0x16 // add by yuewei 20260331 || cmd == 0x17 || cmd == 0x18 || cmd == 0x24 || cmd == 0x26 // add by yuewei 20260331 || cmd == 0x3D || cmd == 0x65 || cmd == 0x67 || cmd == 0x69 // add by yuewei 20260305 || cmd == 0x53 || cmd == 0x63 || cmd == 0x64 || cmd == 0x6A || cmd == 0xE1 || cmd == 0xE2 || cmd == 0x02 || cmd == 0x03) { // add by yuewei 20260414 cmd = 0x02 ox03 rx_state = CHECK_RX_LEN; } else { rx_state = CHECK_RX_CRC; } } } else if (rx_state == CHECK_RX_LEN) { Check.rx_buf[Check.rx_idx++] = data; // modified by yuewei 20260304 start /* if (data < (CHECK_RX_BUF_LEN - 11)) { rx_data_len = data; rx_state = CHECK_RX_DATA; } else { CheckRxErr(); } */ if ((data == 0xF0) && (cmd == 0x69)) { HONGWAI_LONG_RX_FLAG = 1; // add by yuewei 20260309 to deal hongwai long data rx_data_len = 502; // 设置口径和温度补偿值 } else if ((data == 0xFF) && (cmd == 0x03)) { HONGWAI_LONG_RX_FLAG = 1; // add by yuewei 20260309 to deal hongwai long data rx_data_len = 512 + 4; // 表端获取升级包,特殊处理512+4->256+4 } else { rx_data_len = data; } rx_state = CHECK_RX_DATA; // modified by yuewei 20260304 end } else if (rx_state == CHECK_RX_DATA) { Check.rx_buf[Check.rx_idx++] = data; if (Check.rx_idx >= rx_data_len + 9) { if ((rx_data_len == 502) && (cmd == 0x69)) { rx_state = CHECK_RX_CRC_16; // 设置口径和温度补偿值,特殊处理 } else { rx_state = CHECK_RX_CRC; } } } else if (rx_state == CHECK_RX_CRC_16) { // 设置口径和温度补偿值,特殊处理 Check.rx_buf[Check.rx_idx++] = data; // add by yuewei 20260305 rx_state = CHECK_RX_CRC; // add by yuewei 20260305 } else if (rx_state == CHECK_RX_CRC) { Check.rx_buf[Check.rx_idx++] = data; // add by yuewei 20260305 start // 设置口径和温度补偿值,特殊处理 if ((rx_data_len == 502) && (cmd == 0x69)) { crc16 = data; crc16 = crc16 << 8; crc16 = crc16 | Check.rx_buf[Check.rx_idx - 2]; if (crc16 == check_sum_2_byte(&Check.rx_buf[1], Check.rx_idx - 3)) { rx_state = CHECK_RX_TAIL; } else { CheckRxErr(); // LOG("----------------------------4\n"); } } // add by yuewei 20260305 end else { crc = data; if (crc == check_sum(&Check.rx_buf[1], Check.rx_idx - 2)) { rx_state = CHECK_RX_TAIL; } else { CheckRxErr(); // LOG("----------------------------5\n"); } } } else if (rx_state == CHECK_RX_CRC_MODBUS) { // 读取ot需要特殊处理 Check.rx_buf[Check.rx_idx++] = data; // add by yuewei 20260317 if (Check.rx_idx >= 20) { crc16 = Check.rx_buf[19]; crc16 = crc16 << 8; crc16 = crc16 | Check.rx_buf[18]; if (crc16 == crc16_modbus(&Check.rx_buf[0], 18)) { rx_state = CHECK_RX_TAIL; } else { CheckRxErr(); } } } else if (rx_state == CHECK_RX_TAIL) { if (data != 0x16) { // LOG("----------------------------6\n"); // LOG("Check.rx_idx=%d,data=%x\n",Check.rx_idx,data); CheckRxErr(); } HONGWAI_LONG_RX_FLAG = 0; // add by yuewei 20260309 to deal hongwai long data Check.rx_buf[Check.rx_idx++] = data; Check.rx_flag |= CHECK_RX_VLD; // LOG("\n"); // for(int k = 0;k < Check.rx_idx; k++) // { // LOG("%2x ",Check.rx_buf[k]); // } // LOG("\n"); } Check.rx_over_time = 2; } void CheckRxTimeout(void) { if (Check.rx_over_time >= 2) { Check.rx_over_time--; } else if (Check.rx_over_time == 1) { Check.rx_flag |= CHECK_RX_VLD; Check.rx_over_time--; } } boolean_t CheckRxValid(void) { if (Check.rx_idx < 4) { return FALSE; } if (Check.rx_buf[0] != 0x68) { return FALSE; } if (Check.rx_buf[Check.rx_idx - 1] != 0x16) { return FALSE; } // add by yuewei 20260305 start // 设置口径和温度补偿值,特殊处理 if ((rx_data_len == 502) && (Check.rx_buf[1] == 0x69)) { uint16_t crc16 = Check.rx_buf[Check.rx_idx - 2]; crc16 = crc16 << 8; crc16 = crc16 | Check.rx_buf[Check.rx_idx - 3]; if (crc16 != check_sum_2_byte(&Check.rx_buf[1], Check.rx_idx - 4)) { return FALSE; } } // add by yuewei 20260305 end else { if (Check.rx_buf[1] == 0xa5) { // add by yuewei 20260317 to deal read ot uint16_t crc16 = Check.rx_buf[Check.rx_idx - 2]; crc16 = crc16 << 8; crc16 = crc16 | Check.rx_buf[Check.rx_idx - 3]; if (crc16 != crc16_modbus(&Check.rx_buf[0], 18)) { return FALSE; } } else { if (check_sum(&Check.rx_buf[1], Check.rx_idx - 3) != Check.rx_buf[Check.rx_idx - 2]) { return FALSE; } } } return TRUE; } void CheckComHead(uint8_t cmd) { Check.tx_buf[0] = 0xfe; Check.tx_buf[1] = 0x68; Check.tx_buf[2] = cmd; Check.tx_buf[3] = 0x11; Check.tx_buf[4] = 0x11; Check.tx_buf[5] = 0x11; Check.tx_buf[6] = 0x22; Check.tx_buf[7] = 0x22; Check.tx_buf[8] = 0x22; } void CheckComTx(uint8_t cmd) { CheckComHead(cmd); Check.tx_buf[9] = check_sum(&Check.tx_buf[2], 7); Check.tx_buf[10] = 0x16; } // add by yuewei 20260401 void check_com_cmd_response(uint8_t cmd, uint8_t state) { CheckComHead(cmd); Check.tx_buf[9] = 0x01; // L Check.tx_buf[10] = state; // 1:success, other:fail Check.tx_buf[11] = check_sum(&Check.tx_buf[2], 9); Check.tx_buf[12] = 0x16; } void CheckReadAddr(void) { uint8_t i; Param_t *param; GetParam(¶m); // modified by yuewei 20260313 read meter addr do not enter check mode // Check.state = CHECKING; // Check.checking_cnt = 4096; CheckComHead(0x52); Check.tx_buf[9] = 0x07; for (i = 0; i < DEV_ID_LEN; i++) { Check.tx_buf[10 + i] = param->dev_id[DEV_ID_LEN - 1 - i]; } Check.tx_buf[16] = 0x00; Check.tx_buf[17] = check_sum(&Check.tx_buf[2], 15); Check.tx_buf[18] = 0x16; finsh_tx(Check.tx_buf, 19); } void CheckSetAddr(void) { uint16_t i; Param_t *param; GetParam(¶m); if (Check.rx_idx < 18) { Check.rx_err |= CHECK_RX_ERROR; return; } if (Check.rx_buf[8] != 0x07) { Check.rx_err |= CHECK_RX_ERROR; return; } for (i = 0; i < DEV_ID_LEN; i++) { param->dev_id[i] = Check.rx_buf[9 + DEV_ID_LEN - 1 - i]; } // add by yuewei 20260313 save id to eeprom set_device_addr(param->dev_id); // SaveParam(); CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); } void CheckMeterStart(void) { Check.state = CHECKING; Check.checking_cnt = 4096; rt_base_t level = rt_hw_interrupt_disable(); Check.curr_cum_flow = CumFlow;//add by yuewei 20260630 to deal Check.curr_cum_flow = 0 after reset Check.start_cum_flow = Check.curr_cum_flow; Check.flow_cnt = 0; Check.total_spd_lvl = 0.0f; Check.total_water_temp = 0.0f; Check.start_time = RTC_CntInt; Check.end_time = Check.start_time; uint16_t state = get_tof_state(); if (state & TOF_ST_CALIB) { CumFlow = 0; CalibTime = 0; CalibSpdLvl = 0; CalibTemp = 0; Check.start_cum_flow = 0; Check.curr_cum_flow = 0; } rt_hw_interrupt_enable(level); CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); lcd_enter_check_mode(); //add by HBR 20260622 } void CheckMeterEnd(void) { rt_base_t level; uint16_t state; Check.state = CHECKED; Check.checking_cnt = 0; state = get_tof_state(); if (state & TOF_ST_CALIB) { level = rt_hw_interrupt_disable(); CumFlow = 0.0f; rt_hw_interrupt_enable(level); } CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); } void CheckReadFlowParam(void) { uint16_t i; Param_t *param; GetParam(¶m); CheckComHead(0x62); Check.tx_buf[9] = 0x16; // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_idx = CheckTempRangeIndex((float)(Check.total_water_temp / Check.checking_cnt)); uint16_t temp_idx = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_idx]); Check.tx_buf[10] = (uint8_t)Check.total_pulse; Check.tx_buf[11] = (uint8_t)(Check.total_pulse >> 8); Check.tx_buf[12] = (uint8_t)(Check.total_pulse >> 16); Check.tx_buf[13] = (uint8_t)(Check.total_pulse >> 24); for (i = 0; i < CHECK_POINT_NUM; i++) { Check.tx_buf[14 + i * 2] = (uint8_t)(p->cur_c[i]); Check.tx_buf[15 + i * 2] = (uint8_t)(p->cur_c[i] >> 8); } // modified by yuewei 20260316 change q_value to q // Check.tx_buf[30] = (uint8_t)(param->q_value); // Check.tx_buf[31] = (uint8_t)(param->q_value >> 8); Check.tx_buf[30] = (uint8_t)(param->q); Check.tx_buf[31] = (uint8_t)(param->q >> 8); Check.tx_buf[32] = check_sum(&Check.tx_buf[2], 30); Check.tx_buf[33] = 0x16; finsh_tx(Check.tx_buf, 34); } void CheckReadFlowParamInTf(void) { uint16_t i; uint32_t total_pulse; // add by yuewei 20260519 float rtc_interrupt_time_seconds = get_rtc_interrupt_time(); Check.end_time = get_rtc_cnt_int(); // modified by yuewei 20260519 start // uint16_t N = (uint16_t)((Check.end_time - Check.start_time) * 4); uint16_t N = (uint16_t)((Check.end_time - Check.start_time) * 4 * rtc_interrupt_time_seconds); // modified by yuewei 20260519 end Param_t *param; GetParam(¶m); CheckComHead(0x6B); Check.tx_buf[9] = 0x22; // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_idx = CheckTempRangeIndex((float)(Check.total_water_temp / Check.checking_cnt)); uint16_t temp_idx = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_idx]); total_pulse = Check.total_pulse; Check.tx_buf[10] = (uint8_t)total_pulse; Check.tx_buf[11] = (uint8_t)(total_pulse >> 8); Check.tx_buf[12] = (uint8_t)(total_pulse >> 16); Check.tx_buf[13] = (uint8_t)(total_pulse >> 24); for (i = 0; i < CHECK_POINT_NUM; i++) { Check.tx_buf[14 + i * 2] = (uint8_t)(p->cur_c[i]); Check.tx_buf[15 + i * 2] = (uint8_t)(p->cur_c[i] >> 8); } // modified by yuewei 20260316 change q_value to q // Check.tx_buf[30] = (uint8_t)(param->q_value); // Check.tx_buf[31] = (uint8_t)(param->q_value >> 8); Check.tx_buf[30] = (uint8_t)(param->q); Check.tx_buf[31] = (uint8_t)(param->q >> 8); Check.tx_buf[32] = (uint8_t)N; Check.tx_buf[33] = (uint8_t)(N >> 8); uint32_t cum_flow; cum_flow = (uint32_t)(Check.curr_cum_flow - Check.start_cum_flow); Check.tx_buf[34] = (uint8_t)cum_flow; Check.tx_buf[35] = (uint8_t)(cum_flow >> 8); Check.tx_buf[36] = (uint8_t)(cum_flow >> 16); Check.tx_buf[37] = (uint8_t)(cum_flow >> 24); uint32_t spdlvl = (uint32_t)(Check.total_spd_lvl * 10 / Check.flow_cnt); Check.tx_buf[38] = (uint8_t)spdlvl; Check.tx_buf[39] = (uint8_t)(spdlvl >> 8); Check.tx_buf[40] = (uint8_t)(spdlvl >> 16); Check.tx_buf[41] = (uint8_t)(spdlvl >> 24); uint16_t temp = (uint16_t)(Check.total_water_temp * 10 / Check.flow_cnt + 0.5); Check.tx_buf[42] = (uint8_t)temp; Check.tx_buf[43] = (uint8_t)(temp >> 8); Check.tx_buf[44] = check_sum(&Check.tx_buf[2], 42); Check.tx_buf[45] = 0x16; finsh_tx(Check.tx_buf, 46); Check.state = CHECKED; } void CheckSetFlowParam(void) { uint16_t i; uint16_t state; Param_t *param; GetParam(¶m); // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_idx = CheckTempRangeIndex((float)(Check.total_water_temp / Check.checking_cnt)); uint16_t temp_idx = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_idx]); // calib param collect not change check c value state = get_tof_state(); if (state & TOF_ST_METER) { // midified by yuewei 20260324 // memcpy(p->base_c, p->cur_c, sizeof(p->cur_c)); for (i = 0; i < CHECK_POINT_NUM; i++) { p->cur_c[i] = ((uint16_t)Check.rx_buf[10 + i * 2] << 8) | Check.rx_buf[9 + i * 2]; } } CheckComHead(0x63); Check.tx_buf[9] = 0x10; for (i = 0; i < CHECK_POINT_NUM; i++) { Check.tx_buf[10 + i * 2] = (uint8_t)(p->cur_c[i]); Check.tx_buf[11 + i * 2] = (uint8_t)(p->cur_c[i] >> 8); } Check.tx_buf[26] = check_sum(&Check.tx_buf[2], 24); Check.tx_buf[27] = 0x16; finsh_tx(Check.tx_buf, 28); // add by yuewei 20260313 save flow param to eeprom FLOW_PARA_DEF flow_para; flow_para.temp = (Check.total_water_temp / Check.checking_cnt); memcpy(flow_para.cur_c, p->cur_c, sizeof(p->cur_c)); set_flow_para(&flow_para); } void CheckReadDeltaTC(void) { uint8_t temp = Check.rx_buf[9]; uint16_t i; Param_t *param; GetParam(¶m); CheckComHead(0x64); Check.tx_buf[9] = 0x21; // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_idx = CheckTempRangeIndex((float)(Check.total_water_temp / Check.checking_cnt)); uint16_t temp_idx = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_idx]); for (i = 0; i < CHECK_POINT_NUM; i++) { Check.tx_buf[10 + i * 2] = (uint8_t)(p->cur_c[i]); Check.tx_buf[11 + i * 2] = (uint8_t)(p->cur_c[i] >> 8); } for (i = 0; i < CHECK_POINT_NUM; i++) { Check.tx_buf[26 + i * 2] = (uint8_t)(p->spd_lvl[i]); Check.tx_buf[27 + i * 2] = (uint8_t)(p->spd_lvl[i] >> 8); } Check.tx_buf[42] = temp; Check.tx_buf[43] = check_sum(&Check.tx_buf[2], 41); Check.tx_buf[44] = 0x16; finsh_tx(Check.tx_buf, 45); } void CheckReadCumFlow(void) { uint32_t cum = (uint32_t)(CumFlow * 0.1); uint8_t i; Param_t *param; uint16_t state; GetParam(¶m); CheckComHead(0x59); Check.tx_buf[9] = 0x17; for (i = 0; i < DEV_ID_LEN; i++) { Check.tx_buf[10 + i] = param->dev_id[DEV_ID_LEN - 1 - i]; } Check.tx_buf[16] = 0x00; state = get_tof_state(); if (state & TOF_ST_CALIB) { uint32_t ref_flow = (uint32_t)RefFlow; Check.tx_buf[17] = (uint8_t)ref_flow; Check.tx_buf[18] = (uint8_t)(ref_flow >> 8); Check.tx_buf[19] = (uint8_t)(ref_flow >> 16); Check.tx_buf[20] = (uint8_t)(ref_flow >> 24); Check.tx_buf[21] = (uint8_t)cum; Check.tx_buf[22] = (uint8_t)(cum >> 8); Check.tx_buf[23] = (uint8_t)(cum >> 16); Check.tx_buf[24] = (uint8_t)(cum >> 24); uint32_t spd_lvl = (uint32_t)(CalibSpdLvl * 1000); Check.tx_buf[25] = (uint8_t)spd_lvl; Check.tx_buf[26] = (uint8_t)(spd_lvl >> 8); Check.tx_buf[27] = (uint8_t)(spd_lvl >> 16); Check.tx_buf[28] = (uint8_t)(spd_lvl >> 24); uint32_t temp = (uint32_t)(CalibTemp * 100); Check.tx_buf[29] = (uint8_t)temp; Check.tx_buf[30] = (uint8_t)(temp >> 8); Check.tx_buf[31] = (uint8_t)(temp >> 16); Check.tx_buf[32] = (uint8_t)(temp >> 24); } else { Check.tx_buf[17] = 0x00; Check.tx_buf[18] = 0x00; Check.tx_buf[19] = 0x00; Check.tx_buf[20] = 0x00; Check.tx_buf[21] = (uint8_t)cum; Check.tx_buf[22] = (uint8_t)(cum >> 8); Check.tx_buf[23] = (uint8_t)(cum >> 16); Check.tx_buf[24] = (uint8_t)(cum >> 24); Check.tx_buf[25] = 0x00; Check.tx_buf[26] = 0x00; Check.tx_buf[27] = 0x00; Check.tx_buf[28] = 0x00; Check.tx_buf[29] = 0x00; Check.tx_buf[30] = 0x00; Check.tx_buf[31] = 0x00; Check.tx_buf[32] = 0x00; } Check.tx_buf[33] = check_sum(&Check.tx_buf[2], 31); Check.tx_buf[34] = 0x16; finsh_tx(Check.tx_buf, 35); } void CheckSwitchIrWorkMode(void) { Finsh_Uart_Mode &= ~CHECK_ITF_ON; CheckComTx(0xE0); finsh_tx(Check.tx_buf, 11); } void CheckSetTofState(void) { if (Check.rx_buf[9] == 0) { set_tof_state(TOF_ST_METER); } else if (Check.rx_buf[9] == 1) { set_tof_state(TOF_ST_CALIB); } CheckComTx(0xE1); finsh_tx(Check.tx_buf, 11); } void CheckSetRefFlow(void) { uint32_t ref_flow = Check.rx_buf[9] | (Check.rx_buf[10] << 8) | (Check.rx_buf[11] << 16) | (Check.rx_buf[12] << 24); RefFlow = (float)ref_flow; CheckComTx(0xE2); finsh_tx(Check.tx_buf, 11); } // add by yuewei 20260310 /** * @brief 通过按键设置表端进入检表模式 * @param 无 * @retval 无 */ void check_enter_check_mode_by_key_press(void) { Check.state = CHECKING; Check.checking_cnt = 4096; lcd_enter_check_mode(); //add by HBR 20260622 rt_base_t level = rt_hw_interrupt_disable(); Check.start_cum_flow = Check.curr_cum_flow; Check.flow_cnt = 0; Check.total_spd_lvl = 0.0f; Check.total_water_temp = 0.0f; Check.start_time = RTC_CntInt; Check.end_time = Check.start_time; uint16_t state = get_tof_state(); if (state & TOF_ST_CALIB) { CumFlow = 0; CalibTime = 0; CalibSpdLvl = 0; CalibTemp = 0; Check.start_cum_flow = 0; Check.curr_cum_flow = 0; } rt_hw_interrupt_enable(level); } // add by yuewei 20260304 /** * @brief 设置表端进入正常模式(0X31) * @param 无 * @retval 无 */ void check_enter_normal_mode(void) { CheckMeterEnd(); } // add by yuewei 20260310 /** * @brief 通过按键设置表端进入正常模式 * @param 无 * @retval 无 */ void check_enter_normal_mode_by_key_press(void) { rt_base_t level; uint16_t state; Check.state = CHECKED; Check.checking_cnt = 0; state = get_tof_state(); if (state & TOF_ST_CALIB) { level = rt_hw_interrupt_disable(); CumFlow = 0.0f; rt_hw_interrupt_enable(level); } } // add by yuewei 20260304 /** * @brief 清表数据(0X3C),主要清正、反向累计水量 * @param 无 * @retval 无 */ void check_clear_meter(void) { CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); // clear_bottom_data(); // clear base read clear_all_record(); // clear year,month,day,hour,5min records clear_log(); // clear log record } // add by yuewei 20260304 /** * @brief 设置声道数(0X3D) * @param 无 * @retval 无 */ void check_set_channel_num(void) { Param_t *param; GetParam(¶m); CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); /* small water meter only have one channel disable channel set // Check.rx_buf[9] param->chan_num = Check.rx_buf[9]; pTdcItf->ch_num = Check.rx_buf[9]; if (pTdcItf->ch_num == 1) { TdcItf.ch_bit_map = 1; } if (pTdcItf->ch_num == 2) { TdcItf.ch_bit_map = 3; } if (pTdcItf->ch_num == 4) { TdcItf.ch_bit_map = 0x0F; } // add by yuewei 20260519 tof_filter_init(pTdcItf->ch_num); // save chan_num to eeprom set_channel_numb(¶m->chan_num); */ // LOG("check_set_channel_num:%d\n", Check.rx_buf[9]); } // add by yuewei 20260429 /** * @brief 设置静态ot(0X58) * @param 无 * @retval 无 */ void check_set_static_ot(void) { uint8_t isValid = 1; uint8_t ch_num; uint16_t i, j; float TmpFloat[MUX_CH_NUM] = {0}; // 显式初始化 0 uint32_t Tu32; uint8_t ch; uint32_t cnt_int; // 先回复红外指令 CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); // 状态切换 + 稳定延时 set_tof_state(0); rt_thread_delay(20); // 20ms 系统延时更稳定 set_tof_state(TOF_ST_TEST); ch_num = GetChNum(); ot_count_down = ch_num * 512; // OT 检测倒计时 SKEW_PARA_DEF skew_para = {0}; // 结构体清 0 // 【关键】标记:OT 校准期间关闭滤波,避免干扰 G_STATIC_OT_SETTING_FLAG = 1; // 遍历所有通道采集 OT for (i = 0; i < ch_num; i++) { ch = TdcItf.mux_ch_no[i]; set_mux_ch(ch); us_delay(50); // rt_thread_delay(1); // 1ms 比 us_delay 更稳定可靠 // 任何通道空管 → OT 无效 if (alarm_status(ERR_CH0) || alarm_status(ERR_CH1) || alarm_status(ERR_CH2) || alarm_status(ERR_CH3)) { isValid = 0; break; } TmpFloat[i] = 0.0f; // 连续采样 512 次求平均 for (j = 0; j < 512; j++) { // RTC 计数步进 cnt_int = get_rtc_cnt_int(); cnt_int++; set_rtc_cnt_int(cnt_int); set_tdc_int_step(0x00); Tu32 = (cnt_int & 1u) ? TDC_CFG_FIRE_DOWN : TDC_CFG_FIRE_UP; // 启动 TDC 测量 tdc_start_tof(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG | Tu32); // 等待 TDC 完成(空循环不占 CPU 优化) while (get_tdc_int_step() != 0xFFu) ; // 累加时差 TmpFloat[i] += get_diff_tof(); // 进度打点 if ((j & 0x3Fu) == 0x00u) { LOG("."); } ot_count_down--; // 必须延时,否则 PathSkew 偏小 rt_thread_delay(10); // 10ms 系统延时,稳定不抖动 // us_delay(10000); // must insert delay, otherwise TdcPathSkew a little small feed_dog(); // wxl2026-5-19 } // 512 次平均后,绝对值超限 → OT 无效 if (fabsf(TdcItf.path_skew[ch] + TmpFloat[i] * (1.0f / 512)) * 100.00f > Paramx.n) { LOG("\nCh%d PathSkew Error! new PathSkew = %.3f ns\n", ch, TmpFloat[i] / 512.0f); isValid = 0; break; } } // ============================================== // 校准有效 → 保存 Skew 到 EEPROM // ============================================== if (isValid == 1) { for (i = 0; i < ch_num; i++) { ch = TdcItf.mux_ch_no[i]; TdcItf.path_skew[ch] += (TmpFloat[i] / 512.0f); skew_para.skew[ch] = TdcItf.path_skew[ch]; LOG("\nCh%d new PathSkew = %.3f ns\n", ch, TdcItf.path_skew[ch]); } set_skew_para(&skew_para); // 保存到 EEPROM write_alarm(LOG_SET_STATIC_OT, 1, 5555); } else { LOG("PathSkew Error!\n"); G_OT_ERROR_FLAG_CNT = 5; // 通知 LCD 显示 OT-Err } // 恢复平均差值标志 extern float DiffToFAvg128; DiffToFAvg128 = 0.0f; DiffToFAvg = 0.0f; // 恢复正常计量状态 set_tof_state(0); rt_thread_delay(20); set_tof_state(TOF_ST_METER); // 恢复正常滤波 G_STATIC_OT_SETTING_FLAG = 0; } // add by yuewei 20260304 /** * @brief 设置Δt和C(0X65) * @param 无 * @retval 无 */ void check_set_delta_t_and_c(void) { uint16_t i; Param_t *param; CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); GetParam(¶m); // modified by yuewei 20260316 to read in normal mode, only use check_spdLvl_c[0] // uint16_t temp_idx = CheckTempRangeIndex((float)(Check.total_water_temp / Check.checking_cnt)); uint16_t temp_idx = 0; CheckSpdLvlC_t *p = &(param->check_spdLvl_c[temp_idx]); for (i = 0; i < CHECK_POINT_NUM; i++) { p->cur_c[i] = ((uint16_t)Check.rx_buf[10 + i * 2] << 8) | Check.rx_buf[9 + i * 2]; } for (i = 0; i < CHECK_POINT_NUM; i++) { p->spd_lvl[i] = ((uint16_t)Check.rx_buf[26 + i * 2] << 8) | Check.rx_buf[25 + i * 2]; } DELTA_TC_FLOW_PARA_DEF deltaTC_para; deltaTC_para.temp = 50; // only use check_spdLvl_c[0] memcpy(deltaTC_para.cur_c, p->cur_c, sizeof(p->cur_c)); memcpy(deltaTC_para.spd_lvl, p->spd_lvl, sizeof(p->spd_lvl)); // save deltaTC to eeprom set_deltaTC_flow_para(&deltaTC_para); } // add by yuewei 20260316 /** * @brief 设置bnqr(0X67) * @param 无 * @retval 无 */ void check_set_bnqr(void) { // TBD n to deal Param_t *param; CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); GetParam(¶m); param->b = ((uint16_t)Check.rx_buf[10] << 8) | Check.rx_buf[9]; param->n = ((uint16_t)Check.rx_buf[12] << 8) | Check.rx_buf[11]; param->q = ((uint16_t)Check.rx_buf[14] << 8) | Check.rx_buf[13]; param->r = ((uint16_t)Check.rx_buf[16] << 8) | Check.rx_buf[15]; NBQR_PARA_DEF nbqr_para; nbqr_para.b = param->b; nbqr_para.n = param->n; nbqr_para.q = param->q; nbqr_para.r = param->r; // save bnqr to eeprom set_nbqr_para(&nbqr_para); float q3 = param->b; q3 = q3 / 10.0f; // 0.1m?/h->m?/h float q1 = param->r; q1 = q3 / q1; // Q1 = R/Q1 CheckSpdLvlC_t *p = &(param->check_spdLvl_c[0]); // only use check_spdLvl_c[0] p->spd_lvl[0] = GetSpdLvl(q1); p->spd_lvl[1] = GetSpdLvl(1.6 * q1); p->spd_lvl[2] = GetSpdLvl(3.2 * q1); p->spd_lvl[3] = GetSpdLvl(8 * q1); p->spd_lvl[4] = GetSpdLvl(0.1 * q3); p->spd_lvl[5] = GetSpdLvl(0.2 * q3); p->spd_lvl[6] = GetSpdLvl(0.35 * (1.6 * q1 + q3)); p->spd_lvl[7] = GetSpdLvl(q3); DELTA_TC_FLOW_PARA_DEF deltaTC_para; deltaTC_para.temp = 50; // only use check_spdLvl_c[0] memcpy(deltaTC_para.cur_c, p->cur_c, sizeof(p->cur_c)); memcpy(deltaTC_para.spd_lvl, p->spd_lvl, sizeof(p->spd_lvl)); // save deltaTC to eeprom set_deltaTC_flow_para(&deltaTC_para); LOG("check_set_bnqr b=%d,n=%d,q=%d,r=%d\n", param->b, param->n, param->q, param->r); } // add by yuewei 20260304 /** * @brief 设置口径和温度补偿值(0X69) * @param 无 * @retval 无 */ void check_set_diameter_and_temperature_compensation(void) { CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); uint8_t rx_buf[4]; float recvValue; uint16_t iCount = 28; for (uint16_t i = 0; i < iCount; i++) { memcpy(rx_buf, (uint8_t *)&Check.rx_buf[i * 12 + 9], 4); recvValue = *(float *)rx_buf; pTdcItf->quad_cell_ary[i].value = recvValue; memcpy(rx_buf, (uint8_t *)&Check.rx_buf[i * 12 + 13], 4); recvValue = *(float *)rx_buf; pTdcItf->quad_cell_ary[i].coe.m = recvValue; memcpy(rx_buf, (uint8_t *)&Check.rx_buf[i * 12 + 17], 4); recvValue = *(float *)rx_buf; pTdcItf->quad_cell_ary[i].coe.k = recvValue; } // diameter uint16_t iDiameter = Check.rx_buf[510]; iDiameter = ((iDiameter << 8) | Check.rx_buf[509]); // save to memory // Paramx.diameter = iDiameter; // save to eeprom set_diameter_and_quad_cell_data(iDiameter, pTdcItf->quad_cell_ary); // wxl2026-4-14 } // add by yuewei 20260304 /** * @brief 获取口径和温度补偿值(0X6A) * @param 无 * @retval 无 */ void check_get_diameter_and_temperature_compensation(void) { memset((uint8_t *)Check.tx_buf, 0, CHECK_TX_BUF_LEN); CheckComTx(0x6A); uint8_t *sendValue; uint16_t iCount = 28; for (uint16_t i = 0; i < iCount; i++) { sendValue = (uint8_t *)(&pTdcItf->quad_cell_ary[i].value); memcpy((uint8_t *)&Check.tx_buf[i * 12 + 9], sendValue, 4); sendValue = (uint8_t *)(&pTdcItf->quad_cell_ary[i].coe.m); memcpy((uint8_t *)&Check.tx_buf[i * 12 + 13], sendValue, 4); sendValue = (uint8_t *)(&pTdcItf->quad_cell_ary[i].coe.k); memcpy((uint8_t *)&Check.tx_buf[i * 12 + 17], sendValue, 4); } // diameter uint16_t iDiameter = Paramx.diameter; Check.tx_buf[10 + 500] = (uint8_t)iDiameter; Check.tx_buf[10 + 501] = (uint8_t)(iDiameter >> 8); uint16_t crc16; uint16_t iLenth = 502; crc16 = check_sum_2_byte(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[10 + iLenth] = (uint8_t)crc16; // crc l Check.tx_buf[11 + iLenth] = (uint8_t)(crc16 >> 8); // crc h Check.tx_buf[12 + iLenth] = 0x16; rt_enter_critical(); finsh_tx(Check.tx_buf, 13 + iLenth); rt_exit_critical(); } // add by yuewei 20260304 /** * @brief 读取自动匹配电平参数(0X85) * @param 无 * @retval 无 */ void check_get_auto_match_volage_level(void) { CheckComTx(0x85); finsh_tx(Check.tx_buf, 11); } // add by yuewei 20260304 /** * @brief 设置自动匹配电平参数(0X86) * @param 无 * @retval 无 */ void check_set_auto_match_volage_level(void) { CheckComTx(0x40); finsh_tx(Check.tx_buf, 11); } // add by yuewei 20260304 /** * @brief 读取静态ot(0XA5) * @param 无 * @retval 无 */ void check_get_static_ot(void) { uint16_t crc16; // 68 A5 00 00 00 00 00 // 80 00 50 FF 2A 00 // 00 00 00 00 90 01 00 05 65 04 00 00 A0 00 00 00 00 00 26 15 03 03 26 24 00 46 38 43 35 33 00 00 00 00 00 00 00 10 EE EE EE EE DE 3C 16 LOG("check_get_static_ot\n"); memset((uint8_t *)Check.tx_buf, 0, CHECK_TX_BUF_LEN); Check.tx_buf[0] = 0x68; Check.tx_buf[1] = 0xA5; Check.tx_buf[7] = 0x80; Check.tx_buf[9] = 0x50; Check.tx_buf[10] = 0xff; Check.tx_buf[11] = 0x2a; // L Check.tx_buf[12] = 0x00; // L uint16_t ot1 = (uint16_t)fabs(TdcItf.path_skew[0] * 1000); // ps uint16_t ot2 = (uint16_t)fabs(TdcItf.path_skew[1] * 1000); // ps uint16_t ot3 = (uint16_t)fabs(TdcItf.path_skew[2] * 1000); // ps uint16_t ot4 = (uint16_t)fabs(TdcItf.path_skew[3] * 1000); // ps Check.tx_buf[13] = (uint8_t)ot1; // ot1 l Check.tx_buf[14] = (uint8_t)(ot1 >> 8); // ot1 h Check.tx_buf[27] = (uint8_t)ot2; // ot2 l Check.tx_buf[28] = (uint8_t)(ot2 >> 8); // ot2 h Check.tx_buf[29] = (uint8_t)ot3; // ot3 l Check.tx_buf[30] = (uint8_t)(ot3 >> 8); // ot3 h Check.tx_buf[23] = (uint8_t)ot4; // ot4 l Check.tx_buf[24] = (uint8_t)(ot4 >> 8); // ot4 h crc16 = crc16_modbus(&Check.tx_buf[0], 55); Check.tx_buf[55] = (uint8_t)crc16; // crc l Check.tx_buf[56] = (uint8_t)(crc16 >> 8); // crc h Check.tx_buf[57] = 0x16; finsh_tx(Check.tx_buf, 58); } // add by yuewei 20260316 /** * @brief 设置硬件参数(0X00) * @param 无 * @retval 无 */ void check_set_hardware_param(void) { Param_t *param; GetParam(¶m); // modified by yuewei 20260610 start // param->pressure_sensor = Check.rx_buf[9]; param->pressure_sensor = 2; // 无论红外设置是否带压力传感器,始终为‘不带压力传感器’ // modified by yuewei 20260610 end uint32_t iTmp = Check.rx_buf[13]; iTmp = ((iTmp << 8) | Check.rx_buf[12]); iTmp = ((iTmp << 8) | Check.rx_buf[11]); iTmp = ((iTmp << 8) | Check.rx_buf[10]); param->pipe_coe = iTmp / 1000000.0f; LOG("check set pressure_sensor = %d\n", param->pressure_sensor); LOG("check set pipe_coe = %.6f\n", param->pipe_coe); HardWareParaDef HardWarePara; HardWarePara.pressure_sensor = param->pressure_sensor; HardWarePara.pipe_coe = param->pipe_coe; // save to eeprom set_hardware_para(&HardWarePara); check_com_cmd_response(0x00, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260316 /** * @brief 触发上报(0X01) * @param 无 * @retval 无 */ void check_set_trigger_nb_report(void) { LOG("check_set_trigger_nb_report\n"); check_com_cmd_response(0x01, 1); // 1->success finsh_tx(Check.tx_buf, 13); upload_dat.manual_runflag = 1; // wxl20260421 } // add by yuewei 20260415 /** * @brief * @param package_no, time_out_s * @retval 0 -> success, other -> fail */ int8_t check_req_diff_package_and_save(PATCH_INFO_DEF patch_info, uint16_t package_no, uint16_t time_out_s) { uint16_t delay_ms = 100; uint16_t receive_max_times = time_out_s / delay_ms; uint16_t last_package_num = (patch_info.patch_len / patch_info.per_packet_len) + 1; uint16_t last_package_bytes = patch_info.patch_len % patch_info.per_packet_len; for (int i = 1; i <= 3; i++) // every package try to req 3 times if not response { Check.rx_flag = 0; cmd = 0; rx_data_len = 0; rx_state = CHECK_RX_HEAD; Check.rx_idx = 0; // start req package CheckComHead(0x03); // cmd Check.tx_buf[9] = 14; // L // now version memcpy((uint8_t *)&Check.tx_buf[10], patch_info.cur_ver, 5); // target version memcpy((uint8_t *)&Check.tx_buf[15], patch_info.new_ver, 5); // bytes of per package Check.tx_buf[20] = (uint8_t)patch_info.per_packet_len; Check.tx_buf[21] = (uint8_t)(patch_info.per_packet_len >> 8); // current packet num patch_info.cur_num = package_no; Check.tx_buf[22] = (uint8_t)patch_info.cur_num; Check.tx_buf[23] = (uint8_t)(patch_info.cur_num >> 8); Check.tx_buf[24] = check_sum(&Check.tx_buf[2], 22); Check.tx_buf[25] = 0x16; finsh_tx(Check.tx_buf, 26); // wait for response for (int k = 1; k <= receive_max_times; k++) { feed_dog(); rt_thread_delay(delay_ms); // us_delay(delay_ms); if (Check.rx_flag & CHECK_RX_VLD) { Check.rx_flag &= ~CHECK_RX_VLD; if (cmd == 0x03) { cmd = 0; DIFF_PACKET_DEF Packet; Packet.packet_numb = package_no; memcpy(Packet.data, (uint8_t *)&Check.rx_buf[13], patch_info.per_packet_len); // if(package_no == last_package_num) // { // //the last package // Packet.packet_size = last_package_bytes; // if(write_diff_patch_to_flash(&Packet) == 1) // { // return 0; // } // else // { // return -1; // } // } // else // { // //the first or middle package // Packet.packet_size = patch_info.per_packet_len; // if(write_diff_patch_to_flash(&Packet) == 0x10) // { // return 0; // } // else // { // return -1; // } // } if (package_no == last_package_num) Packet.packet_size = last_package_bytes; else Packet.packet_size = patch_info.per_packet_len; if (write_diff_patch_to_flash(&Packet) == 1) return 0; else return -1; } } } } return -1; } // add by yuewei 20260414 /** * @brief (0X02) * @param 无 * @retval 无 */ void check_set_start_upgrade(void) { LOG("check_set_start_upgrade\n"); uint32_t iTmp; PATCH_INFO_DEF patch_info; // now version memcpy(patch_info.cur_ver, (uint8_t *)&Check.rx_buf[9], 5); // target version memcpy(patch_info.new_ver, (uint8_t *)&Check.rx_buf[14], 5); // total bytes iTmp = Check.rx_buf[22]; iTmp = ((iTmp << 8) | Check.rx_buf[21]); iTmp = ((iTmp << 8) | Check.rx_buf[20]); iTmp = ((iTmp << 8) | Check.rx_buf[19]); patch_info.patch_len = iTmp; // bytes of per package iTmp = Check.rx_buf[24]; iTmp = ((iTmp << 8) | Check.rx_buf[23]); patch_info.per_packet_len = iTmp; // crc iTmp = Check.rx_buf[26]; iTmp = ((iTmp << 8) | Check.rx_buf[25]); patch_info.packet_crc = iTmp; int8_t ret = set_patch_info(&patch_info); if (ret == 1) { // valid int packet_nums = (patch_info.patch_len / patch_info.per_packet_len) + 1; for (int i = 1; i <= packet_nums; i++) { int8_t req_save_ret = check_req_diff_package_and_save(patch_info, i, 5000); if (i == packet_nums) { // the last package if (req_save_ret == 0) { check_com_cmd_response(0x04, 1); // 1->success, other->fail finsh_tx(Check.tx_buf, 13); return; } else { check_com_cmd_response(0x04, 3); // 1->success, other->fail finsh_tx(Check.tx_buf, 13); return; } } else { // the middle package if (req_save_ret == 0) { continue; } else { check_com_cmd_response(0x04, 3); // 1->success, other->fail finsh_tx(Check.tx_buf, 13); return; } } } } else { // invalid check_com_cmd_response(0x04, ret); // 1->success, other->fail finsh_tx(Check.tx_buf, 13); } } // add by yuewei 20260331 /** * @brief (0X10) * @param 无 * @retval 无 */ void check_set_ip_and_port(void) { uint16_t iPort; Param_t *param; GetParam(¶m); LOG("check_set_ip_and_port\n"); SERVER_IP_PORT_DEF server_ip_para; // main ip server_ip_para.main_server_ip[0] = Check.rx_buf[9]; server_ip_para.main_server_ip[1] = Check.rx_buf[10]; server_ip_para.main_server_ip[2] = Check.rx_buf[11]; server_ip_para.main_server_ip[3] = Check.rx_buf[12]; // main port iPort = Check.rx_buf[14]; iPort = (iPort << 8) | Check.rx_buf[13]; server_ip_para.main_server_port = iPort; // sub ip server_ip_para.sub_server_ip[0] = Check.rx_buf[15]; server_ip_para.sub_server_ip[1] = Check.rx_buf[16]; server_ip_para.sub_server_ip[2] = Check.rx_buf[17]; server_ip_para.sub_server_ip[3] = Check.rx_buf[18]; // sub port iPort = Check.rx_buf[20]; iPort = (iPort << 8) | Check.rx_buf[19]; server_ip_para.sub_server_port = iPort; memcpy(param->main_server_ip, server_ip_para.main_server_ip, sizeof(server_ip_para.main_server_ip)); param->main_server_port = server_ip_para.main_server_port; memcpy(param->sub_server_ip, server_ip_para.sub_server_ip, sizeof(server_ip_para.sub_server_ip)); param->sub_server_port = server_ip_para.sub_server_port; // save to eeprom set_server_ip_port_para(&server_ip_para); check_com_cmd_response(0x10, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X11) * @param 无 * @retval 无 */ void check_set_report_base_time(void) { uint16_t iTemp; Param_t *param; GetParam(¶m); LOG("check_set_report_base_time\n"); REGULAR_REPORT_DEF regular_report_para; // base time regular_report_para.report_base_hour = Check.rx_buf[9]; regular_report_para.report_base_min = Check.rx_buf[10]; regular_report_para.report_base_sec = Check.rx_buf[11]; // interval(min) iTemp = Check.rx_buf[13]; iTemp = (iTemp << 8) | Check.rx_buf[12]; regular_report_para.report_interval = iTemp; param->report_base_hour = regular_report_para.report_base_hour; param->report_base_min = regular_report_para.report_base_min; param->report_base_sec = regular_report_para.report_base_sec; param->report_interval = regular_report_para.report_interval; // save to eeprom set_regular_report_para(®ular_report_para); check_com_cmd_response(0x11, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X12) * @param 无 * @retval 无 */ void check_set_dma_report_time(void) { Param_t *param; GetParam(¶m); LOG("check_set_dma_report_time\n"); DMA_REGULAR_REPORT_DEF dma_report_para; // start time dma_report_para.dma_report_start_hour = Check.rx_buf[9]; dma_report_para.dma_report_start_min = Check.rx_buf[10]; dma_report_para.dma_report_start_sec = Check.rx_buf[11]; // end time dma_report_para.dma_report_end_hour = Check.rx_buf[12]; dma_report_para.dma_report_end_min = Check.rx_buf[13]; dma_report_para.dma_report_end_sec = Check.rx_buf[14]; // interval(min) dma_report_para.dma_interval = Check.rx_buf[15]; param->dma_report_start[0] = dma_report_para.dma_report_start_hour; param->dma_report_start[1] = dma_report_para.dma_report_start_min; param->dma_report_start[2] = dma_report_para.dma_report_start_sec; param->dma_report_end[0] = dma_report_para.dma_report_end_hour; param->dma_report_end[1] = dma_report_para.dma_report_end_min; param->dma_report_end[2] = dma_report_para.dma_report_end_sec; param->dma_interval = dma_report_para.dma_interval; // save to eeprom set_dma_regular_report_para(&dma_report_para); check_com_cmd_response(0x12, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X13) * @param 无 * @retval 无 */ void check_set_date_time(void) { LOG("check_set_date_time\n"); // Check.rx_buf[9] YY-H no use set_rtc_date(Check.rx_buf[10], Check.rx_buf[11], Check.rx_buf[12]); set_rtc_time(Check.rx_buf[13], Check.rx_buf[14], Check.rx_buf[15]); save_cur_flow_flag = 1; // wxl2026-5-7 save to eeprom check_com_cmd_response(0x13, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X14) * @param 无 * @retval 无 */ void check_set_flow_param(void) { Param_t *param; uint32_t iTmp; GetParam(¶m); LOG("check_set_flow_param\n"); FLOW_ALARM_PARA_DEF flow_alarm_para; // large flow threshold iTmp = Check.rx_buf[12]; iTmp = ((iTmp << 8) | Check.rx_buf[11]); iTmp = ((iTmp << 8) | Check.rx_buf[10]); iTmp = ((iTmp << 8) | Check.rx_buf[9]); flow_alarm_para.large_flow_alarm_thres = iTmp; // large flow time iTmp = Check.rx_buf[14]; iTmp = ((iTmp << 8) | Check.rx_buf[13]); flow_alarm_para.large_flow_cnti_moni_time = iTmp; // continuous flow time iTmp = Check.rx_buf[16]; iTmp = ((iTmp << 8) | Check.rx_buf[15]); flow_alarm_para.cnti_flow_cnti_moni_time = iTmp; // leak flow threshold iTmp = Check.rx_buf[20]; iTmp = ((iTmp << 8) | Check.rx_buf[19]); iTmp = ((iTmp << 8) | Check.rx_buf[18]); iTmp = ((iTmp << 8) | Check.rx_buf[17]); flow_alarm_para.leak_flow_alarm_thres = iTmp; // leak flow time iTmp = Check.rx_buf[22]; iTmp = ((iTmp << 8) | Check.rx_buf[21]); flow_alarm_para.leak_flow_cnti_moni_time = iTmp; param->large_flow_alarm_thres = flow_alarm_para.large_flow_alarm_thres; param->large_flow_cnti_moni_time = flow_alarm_para.large_flow_cnti_moni_time; param->cnti_flow_cnti_moni_time = flow_alarm_para.cnti_flow_cnti_moni_time; param->leak_flow_alarm_thres = flow_alarm_para.leak_flow_alarm_thres; param->leak_flow_cnti_moni_time = flow_alarm_para.leak_flow_cnti_moni_time; // save to eeprom set_flow_alarm_para(&flow_alarm_para); check_com_cmd_response(0x14, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X15) * @param 无 * @retval 无 */ void check_set_pressure_param(void) { uint32_t iTmp; Param_t *param; GetParam(¶m); LOG("check_set_pressure_param\n"); // hight pressure param < low pressure param if (Check.rx_buf[9] < Check.rx_buf[10]) { check_com_cmd_response(0x15, 3); // 3->fail finsh_tx(Check.tx_buf, 13); return; } PRESS_ALARM_PARA_DEF press_alarm_para; // high pressure threshold iTmp = Check.rx_buf[9]; press_alarm_para.high_press_alarm_thres = iTmp; // low pressure threshold iTmp = Check.rx_buf[10]; press_alarm_para.low_press_alarm_thres = iTmp; param->high_press_alarm_thres = press_alarm_para.high_press_alarm_thres; param->low_press_alarm_thres = press_alarm_para.low_press_alarm_thres; // save to eeprom set_press_alarm_para(&press_alarm_para); check_com_cmd_response(0x15, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X16) * @param 无 * @retval 无 */ void check_set_temperature_param(void) { int16_t iTmpH, iTmpL; Param_t *param; GetParam(¶m); LOG("check_set_temperature_param\n"); // high temperature threshold iTmpH = Check.rx_buf[10]; iTmpH = ((iTmpH << 8) | Check.rx_buf[9]); // low temperature threshold iTmpL = Check.rx_buf[12]; iTmpL = ((iTmpL << 8) | Check.rx_buf[11]); // hight temperature param < low temperature param if (iTmpH < iTmpL) { check_com_cmd_response(0x16, 2); // 2->fail finsh_tx(Check.tx_buf, 13); return; } TEMP_ALARM_PARA_DEF temp_alarm_para; // high pressure threshold temp_alarm_para.high_temp_alarm_thres = iTmpH; // low pressure threshold temp_alarm_para.low_temp_alarm_thres = iTmpL; param->high_temp_alarm_thres = temp_alarm_para.high_temp_alarm_thres; param->low_temp_alarm_thres = temp_alarm_para.low_temp_alarm_thres; // save to eeprom set_temp_alarm_para(&temp_alarm_para); check_com_cmd_response(0x16, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X17) * @param 无 * @retval 无 */ void check_set_settle_day(void) { Param_t *param; GetParam(¶m); LOG("check_set_settle_day\n"); if (Check.rx_buf[9] > 31) { check_com_cmd_response(0x17, 2); // 2->fail finsh_tx(Check.tx_buf, 13); return; } SETTLEMENT_DAY_DEF settlement_day_para; settlement_day_para.settlement_day = Check.rx_buf[9]; param->settlement_day = settlement_day_para.settlement_day; // save to eeprom set_settlement_day_para(&settlement_day_para); check_com_cmd_response(0x17, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X18) * @param 无 * @retval 无 */ void check_set_base_read(void) { Param_t *param; uint64_t iTmp; GetParam(¶m); LOG("check_set_base_read\n"); METER_BOTTOM_DEF bottom_data; // cover // total positive bottom_data.fw[0] = Check.rx_buf[9]; bottom_data.fw[1] = Check.rx_buf[10]; bottom_data.fw[2] = Check.rx_buf[11]; bottom_data.fw[3] = Check.rx_buf[12]; // total inverse bottom_data.bw[0] = Check.rx_buf[13]; bottom_data.bw[1] = Check.rx_buf[14]; bottom_data.bw[2] = Check.rx_buf[15]; bottom_data.bw[3] = Check.rx_buf[16]; // save to eeprom set_meter_bottom_data(&bottom_data); check_com_cmd_response(0x18, 1); // 1->success finsh_tx(Check.tx_buf, 13); } // add by yuewei 20260331 /** * @brief (0X21) * @param 无 * @retval 无 */ void check_report_month_data(void) { uint16_t iLenth = 18 * 11; LOG("check_report_month_data\n"); uint8_t data[iLenth]; get_18month_record_data(data); CheckComHead(0x21); // cmd Check.tx_buf[9] = iLenth; // L memcpy((uint8_t *)&Check.tx_buf[10], data, iLenth); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } // add by yuewei 20260331 /** * @brief (0X23) * @param 无 * @retval 无 */ void check_report_day_data(void) { uint16_t iLenth = 30 * 12; LOG("check_report_day_data\n"); uint8_t data[iLenth]; get_30day_record_data(data); CheckComHead(0x23); // cmd Check.tx_buf[9] = 0xF1; // iLenth;//L 0xF1->30*12 memcpy((uint8_t *)&Check.tx_buf[10], data, iLenth); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } // add by yuewei 20260331 /** * @brief (0X25) * @param 无 * @retval 无 */ void check_report_hour_data(void) { uint16_t iLenth = 244; LOG("check_report_hour_data\n"); // start yyyymmdd != end yyyymmdd if ((Check.rx_buf[9] != Check.rx_buf[13]) || (Check.rx_buf[10] != Check.rx_buf[14]) || (Check.rx_buf[11] != Check.rx_buf[15]) || (Check.rx_buf[12] != Check.rx_buf[16])) { return; } uint8_t data[iLenth]; get_hour_record_data(Check.rx_buf[14], Check.rx_buf[15], Check.rx_buf[16], data); CheckComHead(0x25); // cmd Check.tx_buf[9] = iLenth; // L memcpy((uint8_t *)&Check.tx_buf[10], data, iLenth); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } // add by yuewei 20260331 /** * @brief (0X27) * @param 无 * @retval 无 */ void check_report_5_min_data(void) { uint16_t iLenth = 2 * 192; LOG("check_report_5_min_data\n"); uint8_t data[iLenth]; GET_5MIN_REOCORD_DEF record_data; record_data.start_time[0] = Check.rx_buf[10]; // wxl2026-5-18 record_data.start_time[1] = Check.rx_buf[11]; record_data.start_time[2] = Check.rx_buf[12]; record_data.start_time[3] = Check.rx_buf[13]; record_data.start_time[4] = Check.rx_buf[14]; record_data.start_time[5] = 0; record_data.end_time[0] = Check.rx_buf[16]; // wxl2026-5-18 record_data.end_time[1] = Check.rx_buf[17]; record_data.end_time[2] = Check.rx_buf[18]; record_data.end_time[3] = Check.rx_buf[19]; record_data.end_time[4] = Check.rx_buf[20]; record_data.end_time[5] = 0; get_5min_record_data(&record_data, 0, data); CheckComHead(0x27); // cmd Check.tx_buf[9] = iLenth; // L memcpy((uint8_t *)&Check.tx_buf[10], data, iLenth); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } // add by yuewei 20260331 /** * @brief (0X29) * @param 无 * @retval 无 */ void check_report_log_data(void) { uint16_t iLenth = 30 * 13; LOG("check_report_log_data\n"); uint8_t data[iLenth]; get_log_record(0, 30, data); CheckComHead(0x29); // cmd Check.tx_buf[9] = iLenth; // L memcpy((uint8_t *)&Check.tx_buf[10], data, iLenth); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } // add by yuewei 20260331 /** * @brief (0X2A) * @param 无 * @retval 无 */ void check_report_status(void) { uint16_t iLenth = 129; uint32_t iTemp; rtc_run_t *max_fr_rr; rtc_run_t *rr; LOG("check_report_status\n"); CheckComHead(0x2A); // cmd Check.tx_buf[9] = iLenth; // L // total positive iTemp = FwCumFlow * 0.0001; Check.tx_buf[10] = (uint8_t)iTemp; Check.tx_buf[11] = (uint8_t)(iTemp >> 8); Check.tx_buf[12] = (uint8_t)(iTemp >> 16); Check.tx_buf[13] = (uint8_t)(iTemp >> 24); // total inverse iTemp = BwCumFlow * 0.0001; Check.tx_buf[14] = (uint8_t)iTemp; Check.tx_buf[15] = (uint8_t)(iTemp >> 8); Check.tx_buf[16] = (uint8_t)(iTemp >> 16); Check.tx_buf[17] = (uint8_t)(iTemp >> 24); // daily max flow iTemp = (uint32_t)(get_max_flow_rate() * 1000); // 3位小数点 Check.tx_buf[18] = (uint8_t)(iTemp); Check.tx_buf[19] = (uint8_t)(iTemp >> 8); Check.tx_buf[20] = (uint8_t)(iTemp >> 16); Check.tx_buf[21] = (uint8_t)(iTemp >> 24); // daily max flow time get_max_flow_rate_time(&max_fr_rr); if ((max_fr_rr->year == 0) && (max_fr_rr->month == 0)) { // no data record Check.tx_buf[22] = 0; } else { Check.tx_buf[22] = 0x14; } Check.tx_buf[23] = max_fr_rr->year; Check.tx_buf[24] = max_fr_rr->month; Check.tx_buf[25] = max_fr_rr->day; Check.tx_buf[26] = max_fr_rr->hour; Check.tx_buf[27] = max_fr_rr->minute; Check.tx_buf[28] = max_fr_rr->second; // current temperature if (WaterTemp > 100.0f || WaterTemp < 0.0f) { iTemp = 0x8000; // yw 2026-5-22 } else { iTemp = (uint32_t)(WaterTemp * 10 + 0.5); } Check.tx_buf[29] = (uint8_t)(iTemp); Check.tx_buf[30] = (uint8_t)(iTemp >> 8); // water pressure if (Paramx.pressure_sensor == 1) { Check.tx_buf[31] = (uint8_t)(WaterPressure * 100); } else { Check.tx_buf[31] = 0x00;//无压力传感器,修改为零 } // current voltage // battery voltage unit: 0.1V /*if (McuVbat > McuVTxbat) { // 判断哪个电池低就上传哪个数据 iTemp = McuVTxbat / 100; } else { iTemp = McuVbat / 100; }*/ iTemp = McuVbat / 100; // wxl2026-6-2 Check.tx_buf[32] = (unsigned char)iTemp; // now time get_rtc_run(&rr); Check.tx_buf[33] = 0x14; Check.tx_buf[34] = rr->year; Check.tx_buf[35] = rr->month; Check.tx_buf[36] = rr->day; Check.tx_buf[37] = rr->hour; Check.tx_buf[38] = rr->minute; Check.tx_buf[39] = rr->second; Param_t *param; GetParam(¶m); // version Check.tx_buf[40] = 'V'; Check.tx_buf[41] = VER_TYPE; Check.tx_buf[42] = VER_OPERATOR; Check.tx_buf[43] = VER_MODULE; Check.tx_buf[44] = VER_FIRMWARE; // diameter Check.tx_buf[45] = (unsigned char)(param->diameter); Check.tx_buf[46] = (unsigned char)(param->diameter >> 8); // channel number Check.tx_buf[47] = param->chan_num; // main server ip Check.tx_buf[48] = param->main_server_ip[0]; Check.tx_buf[49] = param->main_server_ip[1]; Check.tx_buf[50] = param->main_server_ip[2]; Check.tx_buf[51] = param->main_server_ip[3]; // main server port Check.tx_buf[52] = (unsigned char)(param->main_server_port); Check.tx_buf[53] = (unsigned char)(param->main_server_port >> 8); // sub server ip Check.tx_buf[54] = param->sub_server_ip[0]; Check.tx_buf[55] = param->sub_server_ip[1]; Check.tx_buf[56] = param->sub_server_ip[2]; Check.tx_buf[57] = param->sub_server_ip[3]; // sub server port Check.tx_buf[58] = (unsigned char)(param->sub_server_port); Check.tx_buf[59] = (unsigned char)(param->sub_server_port >> 8); // report base time Check.tx_buf[60] = param->report_base_hour; Check.tx_buf[61] = param->report_base_min; Check.tx_buf[62] = param->report_base_sec; // report interval minutes Check.tx_buf[63] = (unsigned char)(param->report_interval); Check.tx_buf[64] = (unsigned char)(param->report_interval >> 8); // DMA report start time Check.tx_buf[65] = param->dma_report_start[0]; Check.tx_buf[66] = param->dma_report_start[1]; Check.tx_buf[67] = param->dma_report_start[2]; // DMA report end time Check.tx_buf[68] = param->dma_report_end[0]; Check.tx_buf[69] = param->dma_report_end[1]; Check.tx_buf[70] = param->dma_report_end[2]; // DMA report interval time Check.tx_buf[71] = param->dma_interval; // settlement day Check.tx_buf[72] = param->settlement_day; // high temperature alarm threshold Check.tx_buf[73] = (unsigned char)(param->high_temp_alarm_thres); Check.tx_buf[74] = (unsigned char)(param->high_temp_alarm_thres >> 8); // low temperature alarm threshold Check.tx_buf[75] = (unsigned char)(param->low_temp_alarm_thres); Check.tx_buf[76] = (unsigned char)(param->low_temp_alarm_thres >> 8); // large flow alarm threshold Check.tx_buf[77] = (unsigned char)(param->large_flow_alarm_thres); Check.tx_buf[78] = (unsigned char)(param->large_flow_alarm_thres >> 8); Check.tx_buf[79] = (unsigned char)(param->large_flow_alarm_thres >> 16); Check.tx_buf[80] = (unsigned char)(param->large_flow_alarm_thres >> 24); // large flow continue monitor time Check.tx_buf[81] = (unsigned char)(param->large_flow_cnti_moni_time); Check.tx_buf[82] = (unsigned char)(param->large_flow_cnti_moni_time >> 8); // continue flow continue monitor time Check.tx_buf[83] = (unsigned char)(param->cnti_flow_cnti_moni_time); Check.tx_buf[84] = (unsigned char)(param->cnti_flow_cnti_moni_time >> 8); // leak flow alarm threshold Check.tx_buf[85] = (unsigned char)(param->leak_flow_alarm_thres); Check.tx_buf[86] = (unsigned char)(param->leak_flow_alarm_thres >> 8); Check.tx_buf[87] = (unsigned char)(param->leak_flow_alarm_thres >> 16); Check.tx_buf[88] = (unsigned char)(param->leak_flow_alarm_thres >> 24); // leak flow continue monitor time Check.tx_buf[89] = (unsigned char)(param->leak_flow_cnti_moni_time); Check.tx_buf[90] = (unsigned char)(param->leak_flow_cnti_moni_time >> 8); // high press alarm threshold Check.tx_buf[91] = (unsigned char)(param->high_press_alarm_thres); // low press alarm threshold Check.tx_buf[92] = (unsigned char)(param->low_press_alarm_thres); // pressure sensor Check.tx_buf[93] = param->pressure_sensor; ////////////nb para///////// Nb_Run_t *nb_run; char tmp[3]; uint16_t i; GetNbRun(&nb_run); // IMEI len = 8 if (strlen(nb_run->imei) == 15) { tmp[0] = '0'; tmp[1] = nb_run->imei[0]; tmp[2] = 0; StrToHexBuf((char *)&Check.tx_buf[94], tmp, 2); StrToHexBuf((char *)&Check.tx_buf[95], &(nb_run->imei[1]), 14); } else { StrToHexBuf((char *)&Check.tx_buf[94], tmp, 16); } // cell id in AT+NUESTATS response Check.tx_buf[102] = (unsigned char)(nb_run->bts_id); Check.tx_buf[103] = (unsigned char)(nb_run->bts_id >> 8); Check.tx_buf[104] = 0x00; Check.tx_buf[105] = 0x00; // physical cell id Check.tx_buf[106] = (unsigned char)(nb_run->physical_cell_id); Check.tx_buf[107] = (unsigned char)(nb_run->physical_cell_id >> 8); // rsrp Check.tx_buf[108] = (unsigned char)(nb_run->rsrp); Check.tx_buf[109] = (unsigned char)(nb_run->rsrp >> 8); // snr Check.tx_buf[110] = (unsigned char)(nb_run->snr); Check.tx_buf[111] = (unsigned char)(nb_run->snr >> 8); // csq Check.tx_buf[112] = nb_run->rssi; // iccid len = 10 for (i = 0; i < 10; i++) { Check.tx_buf[113 + i] = (unsigned char)(((nb_run->ccid[2 * i] - '0') << 4) | (nb_run->ccid[2 * i + 1] - '0')); } ///////////////////////// // ErrorNo uint32_t *err_no; all_alarm_status(&err_no); Check.tx_buf[123] = (uint8_t)(*err_no); Check.tx_buf[124] = (uint8_t)(*err_no >> 8); Check.tx_buf[125] = (uint8_t)(*err_no >> 16); Check.tx_buf[126] = (uint8_t)(*err_no >> 24); // b Check.tx_buf[127] = (uint8_t)param->b; Check.tx_buf[128] = (uint8_t)(param->b >> 8); // n Check.tx_buf[129] = (uint8_t)param->n; Check.tx_buf[130] = (uint8_t)(param->n >> 8); // q Check.tx_buf[131] = (uint8_t)param->q; Check.tx_buf[132] = (uint8_t)(param->q >> 8); // r Check.tx_buf[133] = (uint8_t)param->r; Check.tx_buf[134] = (uint8_t)(param->r >> 8); // ErrorNo iTemp = TdcItf.pipe_coe * 1000000; Check.tx_buf[135] = (uint8_t)(iTemp); Check.tx_buf[136] = (uint8_t)(iTemp >> 8); Check.tx_buf[137] = (uint8_t)(iTemp >> 16); Check.tx_buf[138] = (uint8_t)(iTemp >> 24); Check.tx_buf[10 + iLenth] = check_sum(&Check.tx_buf[2], 8 + iLenth); Check.tx_buf[11 + iLenth] = 0x16; finsh_tx(Check.tx_buf, 12 + iLenth); } void CheckRxHandler(void) { uint8_t cmd = 0; if (Check.rx_flag & CHECK_RX_VLD) { Check.rx_flag &= ~CHECK_RX_VLD; if (!CheckRxValid()) { CheckRxErr(); //////return err data////////// // uint8_t i; // for(i=0;i 0) { Check.checking_cnt--; if (Check.checking_cnt == 0) { Check.state = CHECKED; } } }