FluxDC/components/FluxUI/ui_event_homePage.c

675 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file ui_event_homePage.c
* @brief 此文件中实现了主页的UI事件处理函数
*
* 核心逻辑1.处理标准变更事件2.处理测试指令下发事件
*
* @author wang xiang en
* @date 2025-04-19
* @version 版本号
* @copyright 版权声明((C)2025, YUWELL MEDTECH Co.ltd
*/
#include "ui.h"
#include "FluxProtocol.h"
/* 使用定时器 */
#include <time.h>
#include "FluxSD.h"
/* 创建用于表征当前是否进行BS测试的全局变量 */
bool is_bs_test_ing = false;
bool is_nom_test_ing = false;
/* 创建任务控制句柄 */
TaskHandle_t bs_test_task_handle;
TaskHandle_t nom_test_task_handle;
/* 声明需要调用的静态函数 */
void comulate_time_set(void);
/* 更新当前标准体积数据 */
static void standard_volume_refresh(void);
/* 定时器执行函数声明 */
static void comulate_result_read(lv_timer_t * timer);
/************************************ 呼吸频率更改响应函数 start ******************************************* */
/**
* @brief 呼吸频率减操作
*
* 只对Spinbox进行-5协议发送在Spinbox的值更改响应事件中。
*
* @param[in] e not used
*/
void on_buttonRateMinus_clicked(lv_event_t * e)
{
uint16_t value = lv_spinbox_get_value(ui_pageHome_spinboxRate);
lv_spinbox_set_value(ui_pageHome_spinboxRate,value-5);
#if LOG_RECORD_ENABLE
example_write_log("on_buttonRateMinus_clicked 频率减事件");
#endif
}
/**
* @brief 呼吸频率加操作
*
* 只对Spinbox进行+5协议发送在Spinbox的值更改响应事件中。
*
* @param[in] e not used
*/
void on_buttonRatePlus_clicked(lv_event_t * e)
{
uint16_t value = lv_spinbox_get_value(ui_pageHome_spinboxRate);
lv_spinbox_set_value(ui_pageHome_spinboxRate,value+5);
#if LOG_RECORD_ENABLE
example_write_log("on_buttonRatePlus_clicked 频率加事件");
#endif
}
/**
* @brief 呼吸频率值改变响应事件,向流量计下发累时。
*
* 通过485协议下发命令实现流量计的累时。
* 使用0x06指令只修改单个16bit寄存器
*
* @note 协议格式:
* 例如01 06 00 02 41 F0 18 1E
*
* 意思是:
* 01设备地址
* 06功能码修改单个寄存器
* 00 02寄存器地址0x00 02
* 41 F0需要发送的数据 41 F0 00 00 对应浮点数 30
*
* @param[in] e not used
*/
void on_spinboxRate_valueChanged(lv_event_t * e)
{
/* 更改下方测试结果部分的频率信息 */
FluxMachineData.breathRate = lv_spinbox_get_value(e->target);
lv_label_set_text_fmt(ui_pageHome_labelResultRate,"%ld",FluxMachineData.breathRate);
/* 刷新标准体积数据,频率不同标准体积也不同。 */
standard_volume_refresh();
/* 根据设定的出气次数设定积分时间 */
comulate_time_set();
/* 下发计算好的积分时间*/
uint8_t bytes[4];
float time = (float)lv_spinbox_get_value(ui_pageFluxRead_spinboxTime);
memcpy(bytes, &time, 4);
/* 下发命令 */
flux_frame.ADDR = FLUX_ADDR;
/* 0x06指令 */
flux_frame.FUNC = FLUX_FUNC_SET_SINGLE;
/* 寄存器地址 0x00 02 */
flux_frame.DATA[0] = 0x00;
flux_frame.DATA[1] = 0x02;
/* 只修改时间寄存器32bit的前两个字节数据16bit */
flux_frame.DATA[2] = bytes[3];
flux_frame.DATA[3] = bytes[2];
ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame));
/* 更新SD卡中需要存储的频率数据 */
sdData.flux_test_result.current_rate = FluxMachineData.breathRate;
}
/**
* @brief 根据spinbox中的值修改 pageFluxRead 页中的显示积分时间
*
* @attention 不能在spinboxTime_valueChanged中调用
* 否则容易造成 死循环。
*
*/
void comulate_time_set(void)
{
/* 获取当前呼吸频率 */
FluxMachineData.breathRate = lv_spinbox_get_value(ui_pageHome_spinboxRate);
uint16_t currntTimes = lv_dropdown_get_selected(ui_pageFluxRead_dropdownPulseTimes);
ESP_LOGI("comulateTimeSend","currentTimes:%d",currntTimes);
if (currntTimes == 0)//进行十次积分
{
/* 10次脉冲计量 */
switch (FluxMachineData.breathRate)
{
case 15:
/*呼吸频率为15BPM时积分时间设定为40秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,40);
break;
case 20:
/*呼吸频率为20BPM时积分时间设定为30秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,30);
break;
case 25:
/*呼吸频率为25BPM时积分时间设定为24秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,24);
break;
case 30:
/*呼吸频率为30BPM时积分时间设定为20秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,20);
break;
case 35:
/*呼吸频率为35BPM时积分时间设定为16秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,18);
break;
case 40:
/*呼吸频率为40BPM时积分时间设定为15秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,15);
break;
default:
break;
}
}else if (currntTimes == 1)
{
/* 20次脉冲 */
switch (FluxMachineData.breathRate)
{
case 15:
/*呼吸频率为15BPM时积分时间设定为40秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,80);
break;
case 20:
/*呼吸频率为20BPM时积分时间设定为30秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,60);
break;
case 25:
/*呼吸频率为25BPM时积分时间设定为24秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,48);
break;
case 30:
/*呼吸频率为30BPM时积分时间设定为20秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,40);
break;
case 35:
/*呼吸频率为35BPM时积分时间设定为16秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,36);
break;
case 40:
/*呼吸频率为40BPM时积分时间设定为15秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,30);
break;
default:
break;
}
}else if (currntTimes == 2)
{
/* 30次脉冲 */
switch (FluxMachineData.breathRate)
{
case 15:
/*呼吸频率为15BPM时积分时间设定为40秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,120);
break;
case 20:
/*呼吸频率为20BPM时积分时间设定为30秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,90);
break;
case 25:
/*呼吸频率为25BPM时积分时间设定为24秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,72);
break;
case 30:
/*呼吸频率为30BPM时积分时间设定为20秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,60);
break;
case 35:
/*呼吸频率为35BPM时积分时间设定为16秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,54);
break;
case 40:
/*呼吸频率为40BPM时积分时间设定为15秒*/
lv_spinbox_set_value(ui_pageFluxRead_spinboxTime,45);
break;
default:
break;
}
}
#if LOG_RECORD_ENABLE
example_write_log("comulate_time_set 重置脉冲次数");
#endif
}
/**
* @brief 更新测试时间
*
* 修改单次测试脉冲总数10 20 30 次后,更新测试时间,
* 向流量计下发测试时间。
*
* @param[in] e not used
*/
void on_dropdownPulseTimes_valueChanged(lv_event_t * e)
{
/* 根据脉冲次数设置测试时间 */
comulate_time_set();
/* 下发测试时间 */
uint8_t bytes[4];
float time = (float)lv_spinbox_get_value(ui_pageFluxRead_spinboxTime);
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];
ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame));
}
/************************************ 呼吸频率更改响应函数 end ******************************************* */
/************************************ 挡位更改响应函数 start ******************************************* */
/**
* @brief 挡位切换后的响应事件
*
* 只更新标准不通过485下发数据。
*
* @note 加减操作已在SquareLine工程内部实现无需手动调用。
* @param[in] e not used
*/
void on_spinboxStage_valueChanged(lv_event_t * e)
{
/*获取当前挡位并更新标准体积数据*/
int32_t value = lv_spinbox_get_value(e->target);
lv_label_set_text_fmt(ui_pageHome_labelResultStage,"%ld",value);
standard_volume_refresh();
/* 更新当前挡位数据 */
sdData.flux_test_result.current_stage = value;
}
/**
* @brief 标准体积数据刷新
*
* 修改标准体积数据,设置最大最小值。
* 最后根据标准判定当前读取到的体积流量是否合格
*
*/
static void standard_volume_refresh(void)
{
/*获取当前的呼吸频率及挡位*/
fluxProtocol.currentBPM = lv_spinbox_get_value(ui_pageHome_spinboxRate);
fluxProtocol.currentStage = lv_spinbox_get_value(ui_pageHome_spinboxStage);
/*获取当前测试设备类型*/
fluxProtocol.currentDevice = lv_dropdown_get_selected(ui_pageSetting_dropdownDeviceType);
if (fluxProtocol.currentDevice == Spirit3)
{
/*判定当前测试设备为Spirit-3*/
/*获取标准体积数据*/
fluxProtocol.nominalVolumeStage = Spirit3_Volume[fluxProtocol.currentStage-1];
}else if (fluxProtocol.currentDevice == Spirit6)
{
/*判定当前测试设备为Spirit-6*/
fluxProtocol.nominalVolumeStage = Spirit6_Volume[fluxProtocol.currentStage-1];
}else if(fluxProtocol.currentDevice == YU_Lite8)
{
/*判定当前测试设备为YU-Lite-8*/
fluxProtocol.nominalVolumeStage = YULite8_Volume[fluxProtocol.currentStage-1];
}
float Volume_nominal = fluxProtocol.nominalVolumeStage /fluxProtocol.currentBPM*1.0;
float VolumeMax = Volume_nominal*1.15;
float VolumeMin = Volume_nominal*0.85;
lv_label_set_text_fmt(ui_pageHome_labelNominalVolume,"%.2f",Volume_nominal);
lv_label_set_text_fmt(ui_pageHome_labelNominalVolumeMax,"%.2f",VolumeMax);
lv_label_set_text_fmt(ui_pageHome_labelNominalVolumeMin,"%.2f",VolumeMin);
/* 更新BS界面中各频率值 */
/*根据标准值判定当前检测结果是否合格*/
RefreshResult();
#if LOG_RECORD_ENABLE
example_write_log("standard_volume_refresh 刷新标准体积");
#endif
}
/************************************ 挡位更改响应函数 end ******************************************* */
/************************************ 开始测试按键按下 start ******************************************* */
/**
* @brief 开始测试按键按下后响应事件
*
* @details 执行流程:
* 1. 下发测试时间,确保测试时间正确
* 2. 创建定时器,配置定时器计时时间
* 3. 下发启动测试指令
*
* @param[in] e not used
*/
void on_buttonStartTest_clicked(lv_event_t * e)
{
/* 判断是否正在测试 */
if(is_nom_test_ing)
{
/* 如果正在测试,按下后取消测试 */
vTaskDelete(nom_test_task_handle);
/* 挂起LED闪烁 */
NOM_STATE_LED_TASK_SUSPEND;
/* 等待开始测试 */
is_nom_test_ing = false;
/* 清空已完成的测试结果 */
NOM_ALL_RESULT_CLEAR;
/* 清空进度条 */
lv_bar_set_value(ui_pageHome_barNomTest,0,LV_ANIM_ON);
lv_label_set_text(ui_pageHome_labelStartTest,"Start Test NOM");
}else{
/* 如果没有测试,按下后开始测试 */
/* 创建NOM测试任务 */
xTaskCreate(nom_test_task, "nom_test_task", 1024*4, NULL, 5, &nom_test_task_handle);
is_nom_test_ing = true;
lv_label_set_text(ui_pageHome_labelStartTest,"Cancel Test NOM");
}
#if 0
uint8_t bytes[4];
float time = (float)lv_spinbox_get_value(ui_pageFluxRead_spinboxTime);
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];
ESP_ERROR_CHECK(ModbusRTU_Send_0306(ECHO_UART_PORT_NUM1,&flux_frame));
/*创建定时器*/
lv_timer_t * comulateResultReadTimer;
/* 基于定时器进行任务调用 */
comulateResultReadTimer = lv_timer_create(comulate_result_read, 500, NULL);
/* 只重复一次 */
lv_timer_set_repeat_count(comulateResultReadTimer, 1);
/* 根据测试时间确定定时器延时 */
int32_t timeS = lv_spinbox_get_value(ui_pageFluxRead_spinboxTime);
lv_timer_set_period(comulateResultReadTimer, timeS*1000+2000);
/*下发启动测试指令*/
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));
/* 修改Label 开始测试 */
lv_label_set_text(ui_pageHome_labelStartTest,"Testing...");
/* 开始计时 */
lv_timer_enable(comulateResultReadTimer);
#endif
}
/**
* @brief 定时器响应函数
*
* 时间到达后执行
* 定时器响应函数,用于定时获取测试结果,并更新界面。
*
* @param[in] timer not used
*/
static void comulate_result_read(lv_timer_t * timer)
{
/*下发数据获取指令*/
/* 起始地址为 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));
lv_label_set_text(ui_pageHome_labelStartTest,"Test Complete!");
}
/**
* @brief BS界面 带BS测试 按键按下事件
*
* 按键按下后执行以下操作
* 1.设置15BPM测试时间
* 2.开始测试
* 3.等待结果
* 4.重复测试
*
* @param[in] e not used
*/
void on_buttonStartTestBS_clicked(lv_event_t * e)
{
/* 判断是否正在测试 */
if(is_bs_test_ing)
{
/* 如果正在测试,按下后取消测试 */
vTaskDelete(bs_test_task_handle);
/* 挂起LED闪烁 */
BS_STATE_LED_TASK_SUSPEND;
/* 等待开始测试 */
is_bs_test_ing = false;
/* 清空已完成的测试结果 */
BS_ALL_RESULT_CLEAR;
lv_label_set_text(ui_pageHome_labelStartTest1,"Start Test BS");
}else{
/* 如果没有测试,按下后开始测试 */
/* 创建BS测试任务 */
xTaskCreate(bs_test_task, "bs_test_task", 1024*4, NULL, 5, &bs_test_task_handle);
is_bs_test_ing = true;
lv_label_set_text(ui_pageHome_labelStartTest1,"Cancel Test BS");
}
#if 0
/* 屏幕中显示下发成功 */
lv_label_set_text(ui_pageHome_labelBSInfo,test_info[0]);
/* 屏幕中显示下发成功 */
lv_label_set_text(ui_pageHome_labelBSInfo,test_info[1]);
/* 创建定时器 */
lv_timer_t * bsTestTimer;
/* 创建定时器调用函数 */
bsTestTimer = lv_timer_create(bs_test_timer_func, 4*1000, NULL);
lv_timer_set_period(bsTestTimer, 4*1000);
lv_timer_set_repeat_count(bsTestTimer, 1);
/* 开启定时器 */
lv_timer_enable(bsTestTimer);
/* 显示正在测试中 */
lv_label_set_text(ui_pageHome_labelBSInfo,test_info[2]);
#endif
}
/**
* @brief BS界面设备类型选择响应函数
*
* 值改变后执行以下操作
* 1.更新Home界面显示设备类型
* 2.更新测试标准值
* 3.根据测试标准刷新判断结果
*
* @param[in] e not used
*/
void on_dropdown_deviceTypeBS_valueChanged(lv_event_t * e)
{
char buf[32]={};
uint16_t index = lv_dropdown_get_selected(e->target);
/* 更新SD卡中的数据存储 */
sdData.flux_test_result.current_device_type = index;
/* 更新Home界面显示设备类型 */
lv_dropdown_get_selected_str(e->target,buf,32);
lv_label_set_text(ui_pageHome_labelTitle, buf);
/* 更新挡位显示范围 */
if (index == Spirit3)
{
lv_spinbox_set_range(ui_pageHome_spinboxStage,1,4);
lv_spinbox_set_range(ui_pageHome_spinboxStageBS,1,4);
}else{
lv_spinbox_set_range(ui_pageHome_spinboxStage,1,6);
lv_spinbox_set_range(ui_pageHome_spinboxStageBS,1,6);
}
/* 刷新标准值 */
on_spinboxStageBS_valueChanged(e);
#if LOG_RECORD_ENABLE
example_write_log("on_dropdownDeviceType_valueChanged 设备类型修改成功");
#endif
}
/**
* @brief BS界面 当前挡位发生修改事件
*
* 按键按下后执行以下操作
* 1.更新屏幕显示标准数据
* 2.根据标准判断是否合格
*
* @param[in] e not used
*/
void on_spinboxStageBS_valueChanged(lv_event_t * e)
{
/* 获取当前挡位 */
int32_t currentStage = lv_spinbox_get_value(ui_pageHome_spinboxStageBS);
/* 获取当前测试设备类型 */
uint16_t currentDevice = lv_dropdown_get_selected(ui_pageHome_DropdownTestTypeBS);
/* 获取该挡位下的体积数据 */
float nominalVolumeStage = 0;
if (currentDevice == Spirit3)
{
/*判定当前测试设备为Spirit-3*/
nominalVolumeStage = Spirit3_Volume[currentStage-1];
}else if (currentDevice == Spirit6)
{
/*判定当前测试设备为Spirit-6*/
nominalVolumeStage = Spirit6_Volume[currentStage-1];
}else if(currentDevice == YU_Lite8)
{
/*判定当前测试设备为YU-Lite-8*/
nominalVolumeStage = YULite8_Volume[currentStage-1];
}
/* 设置15 - 40 BPM对应标准体积值及其上下限 */
{
float tmp_nml = 0;
float tmp_max = 0;
float tmp_min = 0;
/* 计算15BPM标准体积值 */
tmp_nml = nominalVolumeStage/15.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate15STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate15UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate15DOWN, "%.1f",tmp_min);
/* 计算20BPM标准体积值 */
tmp_nml = nominalVolumeStage/20.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate20STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate20UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate20DOWN, "%.1f",tmp_min);
/* 计算25BPM标准体积值 */
tmp_nml = nominalVolumeStage/25.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate25STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate25UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate25DOWN, "%.1f",tmp_min);
/* 计算30BPM标准体积值 */
tmp_nml = nominalVolumeStage/30.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate30STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate30UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate30DOWN, "%.1f",tmp_min);
/* 计算35BPM标准体积值 */
tmp_nml = nominalVolumeStage/35.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate35STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate35UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate35DOWN, "%.1f",tmp_min);
/* 计算40BPM标准体积值 */
tmp_nml = nominalVolumeStage/40.0;
tmp_max = tmp_nml*1.15;
tmp_min = tmp_nml*0.85;
lv_label_set_text_fmt(ui_pageHome_LabelRate40STD, "%.1f",tmp_nml);
lv_label_set_text_fmt(ui_pageHome_LabelRate40UP, "%.1f",tmp_max);
lv_label_set_text_fmt(ui_pageHome_LabelRate40DOWN, "%.1f",tmp_min);
}
/* 更新BS界面中各频率值 */
/*根据标准值判定当前检测结果是否合格*/
//RefreshResult();
#if LOG_RECORD_ENABLE
example_write_log("on_spinboxStageBS_valueChanged 刷新标准体积");
#endif
}