Exemple #1
0
/* 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;
}
Exemple #2
0
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());
}
Exemple #5
0
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());
}