/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  ：distancer.c
 * 描  述  ：测距程序     
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/08/04 
*********************************************************************************/
#include "distancer.h"
#include "timer.h"
#include "delay.h"
#include "my_math.h"
#include "data_typedef.h"
#include "key.h"
#include "pc_protocol.h"

uint16_t distanceCnt1 = 0;
uint16_t distanceCnt2 = 0;

uint8_t distanceBuf1[DISTANCE_CNT_MAX] = {0};						//采样数据缓存
uint8_t distanceBuf2[DISTANCE_CNT_MAX] = {0};

uint8_t outputDistance1 = 255;													//多次采样处理过后的测距数据
uint8_t outputDistance2 = 255;
uint8_t outputDistance3 = 255;
uint8_t outputDistance4 = 255;

uint8_t restartGetDisDataMark = 0;											//重新开始采样标志



void showData(uint8_t num[], uint8_t n)
{
    uint8_t i;
		printf("\r\n");
    for(i=0; i<n; i++)
		{
      printf("%03d ",num[i]);
		}
		printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: DataSort
*	功能说明: 对输入的数组进行排序（从大到小排列）
*	形    参：
*       		x[]:需要处理的数组
*						n:数组的长度
*	返 回 值: 无
***********************************************************************
*/
void DataSort(uint8_t x[], uint8_t n)
{
	uint8_t i,j,k,t;  
	
	for (i=0; i<n-1; i++)
	{
		k = i;
		for(j=i+1; j<n; j++)
		{
			if(x[j] > x[k]) k = j;
		}
		if(k != i)
		{
			t = x[i];
			x[i] = x[k];
			x[k] = t;
		}
	}
}

/*
***********************************************************************
*	函 数 名: uint average(uint *p,uchar n)
*	功能说明: 去掉最大和最小值后求平均数
*	形    参：
*       		x[]:需要处理的数组
*						n:数组的长度
*						discardVal:丢弃值（两头各丢掉的数据数量）
*	返 回 值: 处理后的结果
***********************************************************************
*/
uint8_t Average(uint8_t x[], uint8_t n, uint8_t discardVal)
{
	uint8_t i = 0;
	uint8_t aver = 0;
	uint32_t sum = 0;
	
	for(i = discardVal; i < n-discardVal; i++)
	{
		sum = sum+x[i];
	}
	aver = sum/(n - discardVal*2);  
	return aver;
}

/*
***********************************************************************
*	函 数 名: DistanceDataUpdata
*	功能说明: 多次采样满溢测距数据处理程序
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void DistanceDataUpdata(void)
{
	static uint8_t currentStatus = 0x00;
	static uint8_t nextStatus = 0x00;

	static timer waitingTimer;
	
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		
		timer_set(&waitingTimer, CLOCK_SECOND*15);
	}
	
	if(restartGetDisDataMark == 1)
	{
		restartGetDisDataMark = 0;
		
		distanceCnt1 = 0;
		distanceCnt2 = 0;
		
		printf("\r\n重新采集满溢数据！\r\n");
		timer_restart(&waitingTimer);
	}
	
	if(putInProgress == 0)
	{
		if(timer_expired(&waitingTimer))
		{
			timer_restart(&waitingTimer);
			
			printf("\r\n测距数据处理！\r\n");
			
			printf("\r\ndistanceCnt1 = %d\r\n", distanceCnt1);
			showData(distanceBuf1, distanceCnt1);
			DataSort(distanceBuf1, distanceCnt1);
			showData(distanceBuf1, distanceCnt1);
			outputDistance1 = Average(distanceBuf1, distanceCnt1, 10);
			if((outputDistance1 > distanceParamAtStart) && (outputDistance1 != 255))
			{
				outputDistance1 = devChannel1DisMaxVal;
			}
			printf("\r\noutputDistance1 = %d\r\n", outputDistance1);
			
			printf("\r\ndistanceCnt2 = %d\r\n", distanceCnt2);
			showData(distanceBuf2, distanceCnt2);
			DataSort(distanceBuf2, distanceCnt2);
			showData(distanceBuf2, distanceCnt2);
			outputDistance2 = Average(distanceBuf2, distanceCnt2, 10);
			if((outputDistance2 > distanceParamAtStart) && (outputDistance2 != 255))
			{
				outputDistance2 = devChannel2DisMaxVal;
			}
			printf("\r\noutputDistance2 = %d\r\n", outputDistance2);
			
			//计算变量归零重新开始
			distanceCnt1 = 0;
			distanceCnt2 = 0;
			
			PC_ProCommandSend(0x62);
		}
	}
}

/*
***********************************************************************
*	函 数 名: OverflowDetectionTask
*	功能说明: 桶装满检测任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void OverflowDetectionTask(void)
{
	uint8_t a1 = 0, a2 = 0, a3 = 0, a4 = 0;
	uint8_t A1 = 0, A2 = 0, A3 = 0, A4 = 0;
	
	static uint8_t fullMarkPre1 = 0;
	static uint8_t fullMarkPre2 = 0;
	static uint8_t fullMarkPre3 = 0;
	static uint8_t fullMarkPre4 = 0;
	
	static timer timer_60s;
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&timer_60s, CLOCK_SECOND*10);
	}

	//根据设定的参数判断是否装满
	//第1通道满溢判断
	if((devChannel1DisDepthVal > 0) && (outputDistance1 <= devChannel1DisMaxVal))
	{
		a1 = devChannel1DisMaxVal - outputDistance1;
		A1 = ((uint16_t)a1*100)/devChannel1DisDepthVal;
		
// 		printf("\r\nd1 = %d, a1 = %d, A1 = %d\r\n", getDistance1, a1, A1);
		
		if(A1 >= devChannel1DisAlarmPercent)
		{
			fullMark1 = 1;
		}else{
			fullMark1 = 0;
		}
	}else{		//当前所测得的距大于设定的安装高度说明为空箱
		fullMark1 = 0;
	}
	
	//第2通道满溢判断
	if((devChannel2DisDepthVal > 0) && (outputDistance2 <= devChannel2DisMaxVal))
	{
		a2 = devChannel2DisMaxVal - outputDistance2;
		A2 = ((uint16_t)a2*100)/devChannel2DisDepthVal;
		
// 		printf("\r\nd2 = %d, a2 = %d, A2 = %d\r\n", getDistance2, a2, A2);
		
		if(A2 >= devChannel2DisAlarmPercent)
		{
			fullMark2 = 1;
		}else{
			fullMark2 = 0;
		}
	}else{		//当前所测得的距大于设定的安装高度说明为空箱
		fullMark2 = 0;
	}

	//第3通道满溢判断
	if((devChannel3DisDepthVal > 0) && (outputDistance3 <= devChannel3DisMaxVal))
	{
		a3 = devChannel3DisMaxVal - outputDistance3;
		A3 = ((uint16_t)a3*100)/devChannel3DisDepthVal;
		fullMark3 = (A3 >= devChannel3DisAlarmPercent) ? 1 : 0;
	}else{
		fullMark3 = 0;
	}

	//第4通道满溢判断
	if((devChannel4DisDepthVal > 0) && (outputDistance4 <= devChannel4DisMaxVal))
	{
		a4 = devChannel4DisMaxVal - outputDistance4;
		A4 = ((uint16_t)a4*100)/devChannel4DisDepthVal;
		fullMark4 = (A4 >= devChannel4DisAlarmPercent) ? 1 : 0;
	}else{
		fullMark4 = 0;
	}
	
	//根据满溢及故障情况设置指示灯
	if((netStatus == 2) || (devRunnigStatus == 2))
	{
		//设置有故障时的灯光颜色
		SetKeyLedOFF(1);
		SetKeyLedON(2);
		SetKeyLedOFF(3);
		SetKeyLedON(4);
	}else{
#ifdef FOUR_DROP_PORTS
		//四投放口面板每个投放口使用一个满溢指示灯。
		if(fullMark1) SetKeyLedON(1); else SetKeyLedOFF(1);
		if(fullMark2) SetKeyLedON(2); else SetKeyLedOFF(2);
		if(fullMark3) SetKeyLedON(3); else SetKeyLedOFF(3);
		if(fullMark4) SetKeyLedON(4); else SetKeyLedOFF(4);
#else
		//通道1
		if(fullMark1 == 1)
		{
			SetKeyLedOFF(1);
			SetKeyLedON(2);	
		}else{
			SetKeyLedON(1);
			SetKeyLedOFF(2);
		}
		
		//通道2
		if(fullMark2 == 1)
		{
			SetKeyLedOFF(3);
			SetKeyLedON(4);
		}else{
			SetKeyLedON(3);
			SetKeyLedOFF(4);
		}
#endif
	}
	
	
	//打印调试信息	
	if((fullMarkPre1 != fullMark1) || (fullMarkPre2 != fullMark2) ||
		 (fullMarkPre3 != fullMark3) || (fullMarkPre4 != fullMark4))
	{
		if(fullMark1 == 1)
		{
			printf("\r\nCH1装满\r\n");
		}else{
			printf("\r\nCH1已清空\r\n");
		}
		fullMarkPre1 = fullMark1;
		printf("\r\nd1 = %d, a1 = %d, A1 = %d%%\r\n", outputDistance1, a1, A1);
		
		if(fullMark2 == 1)
		{
			printf("\r\nCH2装满\r\n");
		}else{
			printf("\r\nCH2已清空\r\n");
		}
		fullMarkPre2 = fullMark2;
		
		printf("\r\nd2 = %d, a2 = %d, A2 = %d%%\r\n", outputDistance2, a2, A2);

		fullMarkPre3 = fullMark3;
		fullMarkPre4 = fullMark4;
		printf("\r\nd3 = %d, a3 = %d, A3 = %d%%\r\n", outputDistance3, a3, A3);
		printf("\r\nd4 = %d, a4 = %d, A4 = %d%%\r\n", outputDistance4, a4, A4);
		
		PC_ProCommandSend(0x62);
	}

// 	//打印调试信息	
// 	if(fullMarkPre1 != fullMark1)
// 	{
// 		if(fullMark1 == 1)
// 		{
// 			printf("\r\nCH1装满\r\n");
// 		}else{
// 			printf("\r\nCH1已清空\r\n");
// 		}
// 		fullMarkPre1 = fullMark1;
// 		printf("\r\nd1 = %d, a1 = %d, A1 = %d%%\r\n", getDistance1, a1, A1);
// 	}
// 	
// 	if(fullMarkPre2 != fullMark2)
// 	{
// 		if(fullMark2 == 1)
// 		{
// 			printf("\r\nCH2装满\r\n");
// 		}else{
// 			printf("\r\nCH2已清空\r\n");
// 		}
// 		fullMarkPre2 = fullMark2;
// 		
// 		printf("\r\nd2 = %d, a2 = %d, A2 = %d%%\r\n", getDistance2, a2, A2);
// 	}
// 	
// 	if(fullMarkPre3 != fullMark3)
// 	{
// 		if(fullMark3 == 1)
// 		{
// 			printf("\r\nCH3装满\r\n");
// 		}else{
// 			printf("\r\nCH3已清空\r\n");
// 		}
// 		fullMarkPre3 = fullMark3;
// 		printf("\r\nd3 = %d, a3 = %d, A3 = %d%%\r\n", getDistance3, a3, A3);
// 	}
// 	
// 	if(fullMarkPre4 != fullMark4)
// 	{
// 		if(fullMark4 == 1)
// 		{
// 			printf("\r\nCH4装满\r\n");
// 		}else{
// 			printf("\r\nCH4已清空\r\n");
// 		}
// 		fullMarkPre4 = fullMark4;
// 		printf("\r\nd4 = %d, a4 = %d, A4 = %d%%\r\n", getDistance4, a4, A4);
// 	}
	
	//装满后1分钟打印一次装满提示
	if(timer_expired(&timer_60s))
	{
		timer_restart(&timer_60s);
		
		printf("\r\n通道1：d1 = %d, a1 = %d, A1 = %d%%\r\n", outputDistance1, a1, A1);
		printf("\r\n通道2：d2 = %d, a2 = %d, A2 = %d%%\r\n", outputDistance2, a2, A2);
		printf("\r\n通道3：d3 = %d, a3 = %d, A3 = %d%%\r\n", outputDistance3, a3, A3);
		printf("\r\n通道4：d4 = %d, a4 = %d, A4 = %d%%\r\n", outputDistance4, a4, A4);
	}
}

/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/
