/** * @file FluxProtocol.c * @brief 流量计通讯协议部分 * * 用于声明便携制氧机参数 * * @author wang xiang en * @date 2025-04-18 * @version 版本号 * @copyright 版权声明((C)2025, YUWELL MEDTECH Co.ltd) */ #include #include "FluxProtocol.h" #include "FluxSD.h" #include "esp_log.h" #include "math.h" /* 定义用于存储当前工作模式的变量,默认是bs模式 */ extern bool is_test_mode_nom; /* 应用 event_homePage 中的测试状态显示变量 */ extern bool is_bs_test_ing; extern bool is_nom_test_ing; extern int flux_test_time_series[6]; extern char *test_rate[6]; extern uint32_t g_bs_test_event_group_bits[6]; /* 声明函数 */ extern void comulate_time_set(void); /* 定义控制LED小灯的任务句柄 */ extern TaskHandle_t bs_stateLED_task_handle; extern TaskHandle_t nom_stateLED_task_handle; /* 导出协议数据结构体 */ struct FluxProtocol fluxProtocol; /** * @brief 新建用于进行带常规测试的任务函数 * * @param[in] arg not used * */ void nom_test_task(void* arg) { float time = 0; while (1) { /* 开始测试前 下发积分时间,确保测试时间正确 */ comulate_time_set(); time = (float)lv_spinbox_get_value(ui_pageFluxRead_spinboxTime); flux_test_time_set(time); lv_label_set_text(ui_pageHome_labelStartTest,"Cancel Test Nom"); lv_bar_set_value(ui_pageHome_barNomTest,0,LV_ANIM_ON); /* 恢复LED显示任务 */ vTaskResume(nom_stateLED_task_handle); /* 测试开始 */ FLUX_TEST_START; /* 等待测试结束 */ vTaskDelay(time*1000 / portTICK_PERIOD_MS); /* 再等待2秒钟 */ vTaskDelay(2*1000 / portTICK_PERIOD_MS); /* 下发数据获取指令 */ flux_test_result_get(); /* 测试结束 */ lv_label_set_text(ui_pageHome_labelStartTest,"Start Test Nom"); is_nom_test_ing = false; /* 挂起LED显示任务 */ NOM_STATE_LED_TASK_SUSPEND; lv_bar_set_value(ui_pageHome_barNomTest,0,LV_ANIM_ON); vTaskDelete(NULL); } } /** * @brief 新建用于进行带BS测试的任务函数 * * @param[in] arg not used * */ void bs_test_task(void* arg) { /* 进行6次循环测计数 */ uint8_t testCount = 0; /* 默认所有频率结果正确 */ xEventGroupSetBits(g_bs_test_event_group,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6); ESP_LOGI("bs_test_task", "初始化后判断事件组的值%lu", xEventGroupGetBits(g_bs_test_event_group)); /* *0-5 对应15-40BPM测试结果 *6 对应是否正在等待测试结束 */ while(1) { /* 恢复LED显示任务 */ vTaskResume(bs_stateLED_task_handle); currentTestRate = BS_RATE_15BPM; FLUX_PROGRESS_BAR_CONTROL(0); uint8_t retest_count = 0; while(1) { /* 调节呼吸模拟器频率 */ bs_bpm_send(bs_addr_all[testCount]); lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],test_info[5]); vTaskDelay(10000 / portTICK_PERIOD_MS); /* 下发测试时间 */ flux_test_time_set(flux_test_time_series[testCount]); vTaskDelay(1000 / portTICK_PERIOD_MS); lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],test_info[0]); /* 下发启动指令 */ flux_test_start(); lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],test_info[1]); /* 等待测试结束 */ currentTestRate = (enum Bs_test_Rate)testCount; lv_bar_set_value(ui_pageHome_BarTestProgBS,0,LV_ANIM_ON); lv_label_set_text_fmt(ui_pageHome_labelstr21,test_rate[currentTestRate]); xEventGroupSetBits(g_bs_test_event_group,BIT6); /* 开始进行延时操作 */ vTaskDelay(flux_test_time_series[testCount]*1000 / portTICK_PERIOD_MS); lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],test_info[2]); vTaskDelay(2000 / portTICK_PERIOD_MS); /* 读取测试结果 */ flux_test_result_get(); #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试结果获取中"); #endif lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],test_info[3]); /* 等待2s进行结果获取 */ vTaskDelay(3000 / portTICK_PERIOD_MS); /* 清空进度条 */ xEventGroupClearBits(g_bs_test_event_group,BIT6); FLUX_PROGRESS_BAR_CONTROL(0); ESP_LOGI("bs_test_task", "判断事件组的值%lu", xEventGroupGetBits(g_bs_test_event_group)); /* 根据测试结果确定是否需要复测 */ if ((xEventGroupGetBits(g_bs_test_event_group) & g_bs_test_event_group_bits[testCount])!= 0) { /* 测试结果正常,进行下一挡位测试 */ testCount++; #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试结果正常,进行下一挡位测试"); #endif }else{ #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试结果异常,再次测试?"); #endif /* 测试失败,重复上一次测试 */ lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],"retry"); retest_count++; if(retest_count == 2) { lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s %s",test_rate[testCount],"failed"); #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试失败 进行下一档测试,暂时放弃该挡位"); #endif /* 当前挡位失败,进行下一挡位测试 */ retest_count = 0; testCount++; } } if (testCount == 6) { #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试结束"); #endif break; } } sd_append_bs_data(); lv_label_set_text_fmt(ui_pageHome_labelBSInfo,"%s",test_info[4]); #if LOG_RECORD_ENABLE WRITE_LOG_TO_SD("测试结束 任务回收"); #endif /* 任务测试完毕 删除任务 */ lv_label_set_text(ui_pageHome_labelStartTest1,"Start Test BS"); lv_label_set_text(ui_pageHome_labelBSInfo,"wait for test"); lv_label_set_text(ui_pageHome_labelstr21,"--BPM"); is_bs_test_ing = false; /* 挂起LED显示任务 */ BS_STATE_LED_TASK_SUSPEND; vTaskDelete(NULL); } } /** * @brief 测试状态显示线程 * * 设置一个LED小灯,测试的时候bling bling 闪 * * @param[in] arg not used * */ void bs_test_led_task(void* arg) { int32_t time_all = 0; int32_t bar_plus = 0; int32_t current_bar_value = 0; while(1) { vTaskDelay(BS_LED_BLINK_INTERVAL_MS / portTICK_PERIOD_MS); lv_obj_set_style_bg_color(ui_pageHome_panelBSLEDing,lv_color_hex(0x00FF00),LV_PART_MAIN); vTaskDelay(BS_LED_BLINK_INTERVAL_MS / portTICK_PERIOD_MS); lv_obj_set_style_bg_color(ui_pageHome_panelBSLEDing,lv_color_hex(0xFFFFFF),LV_PART_MAIN); /* 获取总的测试时间 */ time_all = flux_test_time_series[currentTestRate]; /* 获取每次需要累加的值*/ bar_plus = ceil(lv_bar_get_max_value(ui_pageHome_BarTestProgBS) / time_all); /* 获取当前的进度条值*/ current_bar_value = lv_bar_get_value(ui_pageHome_BarTestProgBS); if((current_bar_value + bar_plus < lv_bar_get_max_value(ui_pageHome_BarTestProgBS))&&(xEventGroupGetBits(g_bs_test_event_group)&BIT6)) { lv_bar_set_value(ui_pageHome_BarTestProgBS,current_bar_value + bar_plus,LV_ANIM_ON); } } } /** * @brief 测试状态显示线程 * * 设置一个LED小灯,测试的时候bling bling 闪 * * @param[in] arg not used * */ void nom_test_led_task(void* arg) { int32_t time_all = 0; int32_t bar_plus = 0; int32_t current_bar_value = 0; while(1) { vTaskDelay(NOM_LED_BLINK_INTERVAL_MS / portTICK_PERIOD_MS); lv_obj_set_style_bg_color(ui_pageHome_panelNomTest,lv_color_hex(0x00FF00),LV_PART_MAIN); vTaskDelay(NOM_LED_BLINK_INTERVAL_MS / portTICK_PERIOD_MS); lv_obj_set_style_bg_color(ui_pageHome_panelNomTest,lv_color_hex(0xFFFFFF),LV_PART_MAIN); /* 获取总的测试时间 */ time_all = lv_spinbox_get_value(ui_pageFluxRead_spinboxTime); /* 获取每次需要累加的值*/ bar_plus = lv_bar_get_max_value(ui_pageHome_barNomTest) / time_all; /* 获取当前的进度条值*/ current_bar_value = lv_bar_get_value(ui_pageHome_barNomTest); if (current_bar_value + bar_plus < lv_bar_get_max_value(ui_pageHome_barNomTest)) { lv_bar_set_value(ui_pageHome_barNomTest,current_bar_value+bar_plus,LV_ANIM_ON); } } } /** * @brief 向流量计下发测试时间 * * 时间下发 * * @param[in] time 向流量计下发测试的时间 * */ void flux_test_time_set(float var_time) { /* 设置15BPM测试时间 */ uint8_t bytes[4]; float time = var_time; memcpy(bytes, &time, 4); /* 下发命令 */ flux_frame.ADDR = FLUX_ADDR; flux_frame.FUNC = FLUX_FUNC_SET_SINGLE; flux_frame.DATA[0] = 0x00; flux_frame.DATA[1] = 0x02; flux_frame.DATA[2] = bytes[3]; flux_frame.DATA[3] = bytes[2]; /* 下发15BPM测试时间指令*/ ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame)); } /** * @brief 向流量计下发启动测试指令 * */ void flux_test_start(void) { /* 下发启动测试指令 */ flux_frame_start.ADDR = FLUX_ADDR; flux_frame_start.FUNC = FLUX_FUNC_SET_SINGLE; flux_frame_start.DATA[0] = 0x00; flux_frame_start.DATA[1] = 0x01; flux_frame_start.DATA[2] = 0x00; flux_frame_start.DATA[3] = 0x01; ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame_start)); } /** * @brief 向流量计下获取测试结果指令 * */ void flux_test_result_get(void) { /*下发数据获取指令*/ /* 起始地址为 0x00 */ flux_frame.DATA[0] = 0; flux_frame.DATA[1] = 0; /* 数据长度为 120 */ flux_frame.DATA[2] = 0; flux_frame.DATA[3] = 120; flux_frame.FUNC = FLUX_FUNC_READ; /*下发问询120个参数*/ ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame)); }