/* this function takes in the UArray_T of the pixels, and outputs the Y, Pb, Pr representation */ CVC *rgb_pixels_to_CVC(UArray_T block, int denominator) { int num_pixels = UArray_length(block); float avg_Pb = 0.0; float avg_Pr = 0.0; Pnm_rgb cur_pix; Pnm_rgb_float cur_pix_float; CVC *YPbPr = malloc(sizeof(struct CVC)); assert(YPbPr); YPbPr->Y = malloc(sizeof(Lum_vals) * num_pixels); assert(YPbPr->Y); YPbPr->num_vals = num_pixels; for (int i = 0; i < num_pixels; i++) { cur_pix = (Pnm_rgb)UArray_at(block, i); cur_pix_float = normalize_pixel(cur_pix, denominator); YPbPr->Y[i] = get_Y(cur_pix_float); avg_Pb += get_Pb(cur_pix_float); avg_Pr += get_Pr(cur_pix_float); free(cur_pix_float); } YPbPr->avg_Pb = avg_Pb / (float)num_pixels; YPbPr->avg_Pr = avg_Pr / (float)num_pixels; return YPbPr; }
static FP32 fetch_flow( enum enumPumpSelect PumpSelect ) { FP32 f_org; FP32 Ba, Tr, Pr; FP32 pf; // 读取传感器(未归一化、未校准的)流量 switch( Configure.PumpType[PumpSelect] ) { default: case enumPumpNone: // 没有流量计 或 未安装 return 0.0f; case enumOrifice_1: // 1L孔板流量计 case enumOrifice_2: // 2L孔板流量计 { Ba = get_Ba(); Tr = get_Tr( PumpSelect ); Pr = get_Pr( PumpSelect ); pf = get_pf( PumpSelect ); f_org = Calc_fstd( pf, Tr, Pr, Ba ); } break; } if ( f_org < 0.001f ) { return 0.0f; } // 实验确定归一化倍率 switch ( PumpSelect ) { case PP_TSP: return f_org * 125.0f; case PP_R24_A: case PP_R24_B: return f_org * 1.0f; case PP_SHI_C: case PP_SHI_D: return f_org * 1.0f; default: case PP_AIR: return 0.0f; } }
/********************************** 功能说明 *********************************** * 传感器标定->计前压力 *******************************************************************************/ static void Calibrate_Pr( enum enumPumpSelect PumpSelect ) { struct uMenu const menu[] = { { 0x0201u, "标定计前压力" }, { 0x1000u, "零点" }, { 0x1800u, "倍率" } }; enum { opt_exit, opt_origin, opt_slope, opt_max, opt_min = 1 }; uint8_t option = opt_min; BOOL need_redraw = TRUE; uint16_t gray = Configure.DisplayGray; BOOL graychanged = FALSE; uint16_t *p_origin = &CalibrateRemote.origin[esid_pr][PumpSelect]; uint16_t *p_slope = &CalibrateRemote.slope [esid_pr][PumpSelect]; BOOL changed = FALSE; do { if ( need_redraw ) { cls(); Menu_Redraw( menu ); ShowPumpSelect( 0x0115u, PumpSelect ); need_redraw = FALSE; } ShowI16U( 0x100Cu, *p_origin, 0x0500u, NULL ); ShowI16U( 0x180Cu, *p_slope, 0x0503u, NULL ); Menu_Item_Mask( menu, option ); do{ Lputs( 0x0800u, "计压:" ); ShowFP32( 0x080C, get_Pr( PumpSelect ), 0x0602, "kPa" ); } while( ! hitKey( 25u )); Menu_Item_Mask( menu, option ); switch( getKey()) { case K_DOWN: ++option; if ( option >= opt_max ) { option = opt_min; } break; case K_UP: if( option <= opt_min ) { option = opt_max; } --option; break; case K_OK: switch( option ) { case opt_origin: if ( EditI16U( 0x100Cu, p_origin, 0x0500u )) { changed = TRUE; } break; case opt_slope: if ( EditI16U( 0x180Cu, p_slope, 0x0503u )) { changed = TRUE; } break; default: break; } break; case K_ESC: if( ! changed ) { option = opt_exit; } else { switch( MsgBox( "保存标定数据 ?", vbYesNoCancel + vbDefaultButton3 )) { case vbYes: CalibrateSave(); option = opt_exit; break; case vbNo: CalibrateSave(); option = opt_exit; break; default: break; } need_redraw = TRUE; } break; case K_OK_UP: if ( gray < 2200u ) { ++gray; } if( ! releaseKey( K_OK_UP,100 )) { while( ! releaseKey( K_OK_UP, 1 )) { ++gray; DisplaySetGrayVolt( gray * 0.01f ); } } graychanged = true; break; case K_OK_DOWN: if ( gray > 200u ) { --gray; } if( ! releaseKey( K_OK_DOWN, 100 )) { while( ! releaseKey( K_OK_DOWN, 1 )) { --gray; DisplaySetGrayVolt( gray * 0.01f ); } } graychanged = true; break; case K_OK_RIGHT: if ( gray < ( 2000u - 50u )) { gray += 100u; } graychanged = true; break; case K_OK_LEFT: if ( gray > ( 200 + 20u )) { gray -= 20u; } graychanged = true; break; default: break; } if( graychanged == true ) { DisplaySetGrayVolt( gray * 0.01f ); Configure.DisplayGray = gray; ConfigureSave(); graychanged = FALSE;; } } while( opt_exit != option ); }
void _task_Sample_R24( void ) { const enum enumSamplerSelect SamplerSelect = Q_R24; const enum enumPumpSelect PumpSelect_1 = PP_R24_A; const enum enumPumpSelect PumpSelect_2 = PP_R24_B; BOOL PumpState_1, PumpState_2; uint32_t tt, now_minute = get_Now() / 60u; struct uFile_R24 File; uint16_t fname; // 采样文件编号 uint32_t start; // 采样开始时间 uint8_t iloop; // 当前采样次数 PumpState_1 = FALSE; PumpState_2 = FALSE; Q_Pump[PumpSelect_1].xp_state = FALSE; Q_Pump[PumpSelect_2].xp_state = FALSE; start = SampleSet[SamplerSelect].start; iloop = SampleSet[SamplerSelect].iloop; if ( 0u != start ) { // 初始化采样任务 if ( 0u == iloop ) { // 计算第一次采样的开始时间 switch ( Configure.Mothed_Delay ) { case enumByDelay: // 延时采样 start = start + SampleSet[SamplerSelect].delay1; break; default: case enumByAccurate: // 定时采样 { uint16_t start_hour_minute = start % 1440u; if ( start_hour_minute > SampleSet[SamplerSelect].delay1 ) { start += 1440u; // 推迟到明天的这个时间采样 } start = start - start_hour_minute + SampleSet[SamplerSelect].delay1; } break; } iloop = 1u; } // 采样循环 while (( ! SampleSwitch[SamplerSelect].Clean ) && ( iloop <= SampleSet[SamplerSelect].set_loops )) { // 保存当前采样进度 SampleSet[SamplerSelect].start = start; SampleSet[SamplerSelect].iloop = iloop; SampleSetSave(); Q_Sampler[SamplerSelect].loops = iloop; // 采样状态: 计算采样次数 // 采样执行前进行延时等待 while (( ! SampleSwitch[SamplerSelect].Clean ) && ( now_minute < start )) { Q_Sampler[SamplerSelect].timer = (uint16_t)( start - now_minute ); // 采样状态: 剩余延时时间 // 检测外部控制动作 if ( SampleSwitch[SamplerSelect].Pause ) { PumpState_1 = PumpState_2 = FALSE; Q_Sampler[SamplerSelect].state = state_PAUSE; // 采样状态: 用户控制暂停 } else { PumpState_1 = PumpState_2 = FALSE; Q_Sampler[SamplerSelect].state = state_SUSPEND; // 采样状态: 延时(或间隔) } // 执行电机动作,并注意避免重复开关电机 if ( PumpState_1 != Q_Pump[PumpSelect_1].xp_state ) { Pump_OutCmd( PumpSelect_1, PumpState_1 ); Q_Pump[PumpSelect_1].xp_state = PumpState_1; } if ( PumpState_2 != Q_Pump[PumpSelect_2].xp_state ) { Pump_OutCmd( PumpSelect_2, PumpState_2 ); Q_Pump[PumpSelect_2].xp_state = PumpState_2; } delay( 1000u ); now_minute = get_Now() / 60u; // 显示查询数据 Q_Pump[PumpSelect_1].sum_time = 0u; Q_Pump[PumpSelect_1].vnd = 0.0f; Q_Pump[PumpSelect_2].sum_time = 0u; Q_Pump[PumpSelect_2].vnd = 0.0f; } // 采样执行前,确定要保存的文件(可能需要初始化,也可能需要恢复) fname = SampleSet[SamplerSelect].FileNum; // 取最后保存文件号 if ( ++fname > FileNum_Max ){ fname = 1u; } // 计算要使用文件号 File_Load_R24 ( fname, &File ); if ( 0u == File.sample_begin ) { // 清空统计数据,主要目的在于开始采样前显示的时候显示零 File.sum_min [Q_PP1] = 0u; File.max_pr [Q_PP1] = 0.0f; File.sum_tr [Q_PP1] = 0.0f; File.sum_pr [Q_PP1] = 0.0f; File.vnd [Q_PP1] = 0.0f; File.sum_Ba = 0.0f; File.sum_min [Q_PP2] = 0u; File.max_pr [Q_PP2] = 0.0f; File.sum_tr [Q_PP2] = 0.0f; File.sum_pr [Q_PP2] = 0.0f; File.vnd [Q_PP2] = 0.0f; } // 1.采样,执行采样 while ( ! SampleSwitch[SamplerSelect].Clean ) // && 判断采样时间到 { // 采样状态: 剩余采样时间 switch ( Configure.Mothed_Sample ) { default: case enumBySet: // 扣除掉电,按设置时间运行 if ( now_minute < ( start + SampleSet[SamplerSelect].sample_1 )) { Q_Sampler[SamplerSelect].timer = (uint16_t)(( start + SampleSet[SamplerSelect]. sample_1 ) - now_minute ); // 剩余运行时间(倒计时) } else { Q_Sampler[SamplerSelect].timer = 0u; } break; case enumBySum: // 不扣掉电,按累计时间运行(双路,A采大于B采,按A路运行即可) if ( File.sum_min[Q_PP1] < SampleSet[SamplerSelect].sample_1 ) { Q_Sampler[SamplerSelect].timer = SampleSet[SamplerSelect]. sample_1 - File.sum_min[Q_PP1]; // 剩余运行时间(倒计时) } else { Q_Sampler[SamplerSelect].timer = 0u; } break; } if ( Q_Sampler[SamplerSelect].timer <= 0 ){ break; } // 判断采样时间到 // 检测外部控制动作 if ( SampleSwitch[SamplerSelect].Fatal ) { PumpState_1 = PumpState_2 = FALSE; Q_Sampler[SamplerSelect].state = state_ERROR; // 采样状态: 发生故障暂停 } else if ( SampleSwitch[SamplerSelect].Pause ) { PumpState_1 = PumpState_2 = FALSE; Q_Sampler[SamplerSelect].state = state_PAUSE; // 采样状态: 用户控制暂停 } else { PumpState_1 = TRUE; // PumpState_2 = ?; switch ( Configure.Mothed_Sample ) { default: case enumBySet: // 扣除掉电,按设置时间运行 PumpState_2 = ( now_minute < ( start + SampleSet[SamplerSelect].sample_2 )); break; case enumBySum: // 不扣掉电,按累计时间运行(双路,A采大于B采,按A路运行即可) PumpState_2 = ( File.sum_min[Q_PP2] < SampleSet[SamplerSelect].sample_2 ); break; } Q_Sampler[SamplerSelect].state = state_SAMPLE; // 采样状态: 正常采样 } // 执行电机动作,并注意避免重复开关电机 if ( PumpState_1 != Q_Pump[PumpSelect_1].xp_state ) { Pump_OutCmd( PumpSelect_1, PumpState_1 ); Q_Pump[PumpSelect_1].xp_state = PumpState_1; } if ( PumpState_2 != Q_Pump[PumpSelect_2].xp_state ) { Pump_OutCmd( PumpSelect_2, PumpState_2 ); Q_Pump[PumpSelect_2].xp_state = PumpState_2; } delay( 1000u ); tt = get_Now() / 60u; if ( now_minute != tt ) // 1分钟到? { if ( state_SAMPLE == Q_Sampler[SamplerSelect].state ) { // 统计前初始化 if ( 0u == File.sample_begin ) { // 空文件,初始化 File.set_loops = SampleSet[SamplerSelect].set_loops; File.run_loops = iloop; File.set_time[Q_PP1] = SampleSet[SamplerSelect].sample_1; File.set_time[Q_PP2] = SampleSet[SamplerSelect].sample_2; File.set_flow[Q_PP1] = Configure.SetFlow[PumpSelect_1]; File.set_flow[Q_PP2] = Configure.SetFlow[PumpSelect_2]; File.sample_begin = now_minute * 60u + 1u; // 在实际开始采样前记录开始时间 } // 统计运行数据 if ( PumpState_1 ) { FP32 Ba = get_Ba(); FP32 Tr = get_Tr( PumpSelect_1 ); FP32 Pr = get_Pr( PumpSelect_1 ); if ( fabs( File.max_pr[Q_PP1] ) < fabs( Pr )) { File.max_pr[Q_PP1] = Pr; } File.sum_tr [Q_PP1] += Tr; File.sum_pr [Q_PP1] += Pr; File.vnd [Q_PP1] += get_fstd( PumpSelect_1 ); File.sum_Ba += Ba; File.sum_min [Q_PP1] += 1u; } if ( PumpState_2 ) { FP32 Tr = get_Tr( PumpSelect_2 ); FP32 Pr = get_Pr( PumpSelect_2 ); if ( fabs( File.max_pr[Q_PP2] ) < fabs( Pr )) { File.max_pr[Q_PP2] = Pr; } File.sum_tr [Q_PP2] += Tr; File.sum_pr [Q_PP2] += Pr; File.vnd [Q_PP2] += get_fstd( PumpSelect_2 ); File.sum_min [Q_PP2] += 1u; } File_Save_R24 ( fname, &File ); } now_minute = tt; } // 显示查询数据 Q_Pump[PumpSelect_1].sum_time = File.sum_min [Q_PP1]; Q_Pump[PumpSelect_1].vnd = File.vnd [Q_PP1]; Q_Pump[PumpSelect_2].sum_time = File.sum_min [Q_PP2]; Q_Pump[PumpSelect_2].vnd = File.vnd [Q_PP2]; } // 完成一次采样,对文件进行汇总 if (( 0u != File.sum_min[Q_PP1] ) || ( 0u != File.sum_min[Q_PP2] )) { // 采样统计数据非空时执行 SampleSet[SamplerSelect].FileNum = fname; SampleSetSave(); if ( ++fname > FileNum_Max ){ fname = 1u; } // 记录泵累计运行 PumpSumTimeSave( PumpSelect_1, PumpSumTimeLoad( PumpSelect_1 ) + File.sum_min[Q_PP1] ); PumpSumTimeSave( PumpSelect_2, PumpSumTimeLoad( PumpSelect_2 ) + File.sum_min[Q_PP2] ); } // 如果统计数据非空,清空的是新文件,否则,继续使用当前文件 File.sample_begin = 0u; File_Save_R24 ( fname, &File ); // 计算下次采样的 次数、开始时间 switch ( Configure.Mothed_Sample ) { default: case enumBySet: // 根据采样时间设置运行,扣除掉电,按设置时间运行 start = ( start + SampleSet[SamplerSelect].sample_1 ); break; case enumBySum: // 根据累计时间设置运行,不扣掉电,从当前时间延时 start = now_minute; break; } start += SampleSet[SamplerSelect].suspend_1; iloop ++; } // 采样已经完成,强制执行一次关泵动作(忽略记录的泵状态) Pump_OutCmd( PumpSelect_1, FALSE ); Q_Pump[PumpSelect_1].xp_state = FALSE; Pump_OutCmd( PumpSelect_2, FALSE ); Q_Pump[PumpSelect_2].xp_state = FALSE; // 删除采样任务 SampleSet[SamplerSelect].start = 0u; SampleSet[SamplerSelect].iloop = 0u; SampleSetSave(); } // 采样全部完成 Q_Sampler[SamplerSelect].state = state_FINISH; Q_Sampler[SamplerSelect].loops = 0u; Q_Sampler[SamplerSelect].timer = 0u; Q_Pump[PumpSelect_1].sum_time = 0u; Q_Pump[PumpSelect_1].vnd = 0.0f; Q_Pump[PumpSelect_2].sum_time = 0u; Q_Pump[PumpSelect_2].vnd = 0.0f; // osThreadTerminate( osThreadGetId()); }
void _task_Sample_TSP( void ) { const enum enumSamplerSelect SamplerSelect = Q_TSP; const enum enumPumpSelect PumpSelect = PP_TSP; BOOL PumpState; uint32_t tt, now_minute = get_Now() / 60u; struct uFile_TSP File; uint16_t fname; // 当前有效文件 uint32_t start; // 采样开始时间 uint8_t iloop; // 当前采样次数 PumpState = FALSE; Q_Pump[PumpSelect].xp_state = FALSE; start = SampleSet[SamplerSelect].start; iloop = SampleSet[SamplerSelect].iloop; if ( 0u != start ) { if ( 0u == iloop ) { // 初始化采样任务 switch ( Configure.Mothed_Delay ) { case enumByDelay: start = start + SampleSet[SamplerSelect].delay1; break; default: case enumByAccurate: { uint16_t start_hour_minute = start % 1440u; if ( start_hour_minute > SampleSet[SamplerSelect].delay1 ) { start += 1440u; // 推迟到明天的这个时间采样 } start = start - start_hour_minute + SampleSet[SamplerSelect].delay1; } break; } iloop = 1u; } while (( ! SampleSwitch[SamplerSelect].Clean ) && ( iloop <= SampleSet[SamplerSelect].set_loops )) { SampleSet[SamplerSelect].start = start; SampleSet[SamplerSelect].iloop = iloop; SampleSetSave(); Q_Sampler[SamplerSelect].loops = iloop; // 0.延时,等待采样(延时或者间隔状态) while (( ! SampleSwitch[SamplerSelect].Clean ) && ( now_minute < start )) { Q_Sampler[SamplerSelect].timer = (uint16_t)( start - now_minute ); if ( SampleSwitch[SamplerSelect].Pause ) { PumpState = FALSE; Q_Sampler[SamplerSelect].state = state_PAUSE; } else { PumpState = FALSE; Q_Sampler[SamplerSelect].state = state_SUSPEND; } if( PumpState != Q_Pump[PumpSelect].xp_state ) { Pump_OutCmd( PumpSelect, PumpState ); Q_Pump[PumpSelect].xp_state = PumpState; } delay( 1000u ); now_minute = get_Now() / 60u; // 显示查询数据 Q_Pump[PumpSelect].sum_time = 0u; Q_Pump[PumpSelect].vd = 0.0f; Q_Pump[PumpSelect].vnd = 0.0f; } // 1.0 如果空则需要初始化,否则内有有效数据 fname = SampleSet[SamplerSelect].FileNum; if ( ++fname > FileNum_Max ) { fname = 1u; } File_Load_TSP( fname, &File ); if ( 0u == File.sample_begin ) { File.sum_min = 0u; File.max_pr = File.sum_tr = File.sum_pr = File.vd = File.vnd = 0.0f; File.sum_Ba = 0.0f; // File.DataValidMask = 0x1234; File_Save_TSP( fname, &File ); } // 1.采样,执行采样 while ( ! SampleSwitch[SamplerSelect].Clean ) // NOT 采样时间到? { switch ( Configure.Mothed_Sample ) { default: case enumBySet: // 根据采样时间设置运行,扣除掉电,按设置时间运行 if ( now_minute < ( start + SampleSet[SamplerSelect].sample_1 )) { Q_Sampler[SamplerSelect].timer = (uint16_t)(( start + SampleSet[SamplerSelect]. sample_1 ) - now_minute ); // 剩余运行时间(倒计时) } else { Q_Sampler[SamplerSelect].timer = 0u; } break; case enumBySum: // 不扣掉电,按累计时间运行 if ( File.sum_min < SampleSet[SamplerSelect].sample_1 ) { Q_Sampler[SamplerSelect].timer = SampleSet[SamplerSelect]. sample_1 - File.sum_min; // 剩余运行时间(倒计时) } else { Q_Sampler[SamplerSelect].timer = 0u; } break; } if ( Q_Sampler[SamplerSelect].timer <= 0 ) { break; // 时间到?(倒计时时间为零) } if ( SampleSwitch[SamplerSelect].Fatal ) { PumpState = FALSE; Q_Sampler[SamplerSelect].state = state_ERROR; } else if ( SampleSwitch[SamplerSelect].Pause ) { PumpState = FALSE; Q_Sampler[SamplerSelect].state = state_PAUSE; } else { PumpState = TRUE; Q_Sampler[SamplerSelect].state = state_SAMPLE; } // 应避免重复开启 if ( PumpState != Q_Pump[PumpSelect].xp_state ) { Pump_OutCmd( PumpSelect, PumpState ); Q_Pump[PumpSelect].xp_state = PumpState; } // 保护压力设置成零,禁止保护功能。 if ( Configure.TSP_Pr_Portect != 0u ) { FP32 Pr_Protect = Configure.TSP_Pr_Portect * 0.01f; FP32 rPr = get_Pr( PumpSelect ); static uint16_t iRetry; bool tick_en = false; if ( fabs( rPr ) < Pr_Protect ) { iRetry = 0u; } else if ( iRetry < 15 ) { ++iRetry; tick_en = ( iRetry > 10 ); } else { // 确让压力超过限压,执行保护动作 SampleSwitch[SamplerSelect].Fatal = true; // Q_Sampler[SamplerSelect].state = state_ERROR; } // delay ( 1000u ); if ( ! tick_en ) { delay ( 1000u ); } else { // 报警提示 beep(); delay( 200u ); beep(); delay( 600u ); } } else { delay(1000u); } tt = get_Now() / 60u; if ( now_minute != tt ) // 1分钟到? { if ( state_SAMPLE == Q_Sampler[SamplerSelect].state ) { // 统计采样数据 if ( 0u == File.sample_begin ) { // 空文件,初始化 File.set_loops = SampleSet[SamplerSelect].set_loops; File.run_loops = iloop; File.set_time = SampleSet[SamplerSelect].sample_1; File.set_flow = Configure.SetFlow[SamplerSelect]; File.sample_begin = now_minute * 60u + 1u; // File.DataValidMask = 0x1234; } if ( PumpState ) { FP32 fstd = get_fstd( PumpSelect ); FP32 Ba = get_Ba(); FP32 Te = get_Te();// PumpSelect ); FP32 flow = Calc_flow( fstd, Te, 0.0f, Ba, Q_TSP ); // Calc_flow( fstd, Tr, Pr, Ba ); FP32 rTr = get_Tr( PumpSelect ); FP32 rPr = get_Pr( PumpSelect ); if ( fabs( File.max_pr ) < fabs( rPr )) { File.max_pr = rPr; } File.sum_tr += rTr; File.sum_pr += rPr; File.vnd += fstd; File.vd += flow; File.sum_Ba += Ba; File.sum_min += 1u; } File_Save_TSP( fname, &File ); } now_minute = tt; } // 显示查询数据 Q_Pump[PumpSelect].sum_time = File.sum_min; Q_Pump[PumpSelect].vd = File.vd; Q_Pump[PumpSelect].vnd = File.vnd; } // 1.2 结束当前采样 if ( File.sum_min > 0u ) { SampleSet[SamplerSelect].FileNum = fname; SampleSetSave(); if ( ++fname > FileNum_Max ) { fname = 1u; } File.sample_begin = 0u; // 清空文件, 标志本次采样循环结束 File_Save_TSP( fname, &File ); // 记录泵累计运行 PumpSumTimeSave( PumpSelect, PumpSumTimeLoad( PumpSelect ) + File.sum_min ); } // if( fname == 0 ){delay_us(10);beep();} //bug // 计算下次采样时间 switch ( Configure.Mothed_Sample ) { default: case enumBySet: // 根据采样时间设置运行,扣除掉电,按设置时间运行 start = ( start + SampleSet[SamplerSelect].sample_1 ); break; case enumBySum: // 根据累计时间设置运行,不扣掉电,从当前时间延时 start = now_minute; break; } start += SampleSet[SamplerSelect].suspend_1; iloop ++; } // 采样已经完成 Pump_OutCmd( PumpSelect, FALSE ); Q_Pump[PumpSelect].xp_state = FALSE; // 删除采样任务 SampleSet[SamplerSelect].start = 0u; SampleSet[SamplerSelect].iloop = 0u; SampleSetSave(); } // 采样完成状态 Q_Sampler[SamplerSelect].state = state_FINISH; Q_Sampler[SamplerSelect].loops = 0u; Q_Sampler[SamplerSelect].timer = 0u; Q_Pump[PumpSelect].vd = 0.0f; Q_Pump[PumpSelect].vnd = 0.0f; Q_Pump[PumpSelect].sum_time = 0u; // osThreadTerminate( osThreadGetId()); }