/*
*********************************************************************************************************
*
*	模块名称 : 光敏电阻检测车模块
*	文件名称 : bsp_photoresistor.c
*	版    本 : V1.0
*	说    明 : 光敏电阻检测车
*
*	修改记录 :
*		版本号  日期       作者    说明
*		v1.0
*
*	Copyright (C)
*
*********************************************************************************************************
*/
#include "Ultrasonic.h"
#include "bsp_photoresistor.h"
int16_t  thr_pho_resistor_h = 0x174;
int16_t  ph_stable_value = 0;
uint16_t  ph_value[5];
int ph_wave_flag = 0;
int ph_wave_count = 0;
enum STATUS ph_state = 1;
enum STATUS Ph_Dec_in_flag;
enum STATUS ge_state = 1;//地磁是否正常标志
u8 mag_time_count;
int16_t VAL_PHOTO = 0;
int16_t ph_base = 0;
int16_t day_or_night = 0x765;//0x765
int16_t day_or_night2 = 0x200;//0x300
int16_t thr_night = 0x200;//0x300
int16_t thr_day = 0x174;//0x174
uint8_t pho_fault_count = 0;
int geo_wave_flag = 0;
int geo_wave_count = 0;
int no_car_count;
///////////////////////////////////

u8 tmp_thr_pho[10];//光敏阈值存储

/***************************test*************************************/
//////////////////////得到光敏电阻值////////////////////////////////
/***
功能：采集光敏电阻AD值
***/
void get_photoresistor_ad(void)
{
        int i=0;
        ADC_Cmd(ADC1,ENABLE);
        while(i<5)
        {
                ADC_ChannelCmd(ADC1,ADC_Channel_22,ENABLE);
                ADC_SoftwareStartConv(ADC1);
                while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
                ph_value[i++] = ADC_GetConversionValue(ADC1);
                ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
        }
        VAL_PHOTO = (ph_value[1] + ph_value[2] + ph_value[3])/3;
        
        CarRecDataStr.pr[0] = VAL_PHOTO>>8;
        CarRecDataStr.pr[1] = VAL_PHOTO;
        ADC_ChannelCmd(ADC1,ADC_Channel_22,DISABLE);
        ADC_Cmd(ADC1,DISABLE);
}

void judge_ph_state(void)
{
        static uint8_t count = 0;
        if(ph_state == YES)count = 0;
        else
        {
              if((VAL_PHOTO > 0x200)&&(VAL_PHOTO<0xF00))count++;
              if(count>=5)
              {
                      count = 0;
                      ph_state = YES;
              }
        }
}

/////////////////////光敏电阻检测车进入/////////////////////////
/***
输入：first_dec：更新参数的值；next_dec：正常检测
功能：光敏检测车进入
输出：1：有车；0：无车
***/
int ph_car_in(int flag)
{
	static uint8_t dec_car_in_count = 0;//光敏稳定变化计次
	static int16_t ph_in_before = 0;
	if(flag == 1)
	{

		ph_in_before = VAL_PHOTO;//首次更新ad值
		return 3;
	}
	if((ph_base - VAL_PHOTO)>THR_PHO_RESISTOR_H)
	{
                if(abs(VAL_PHOTO - ph_in_before) < THR_PHO_RESISTOR_H/5)
                {
                        dec_car_in_count++;
                        if(dec_car_in_count>=PR_DEC_COUNT)
                        {
                                dec_car_in_count = PR_DEC_COUNT;
                        }
                }
                else
                {
                        dec_car_in_count = 0;
                }
                ph_in_before = VAL_PHOTO;
	}
	else
	{
				dec_car_in_count = 0;
	}

	if(dec_car_in_count>=PR_DEC_COUNT)
	{
                dec_car_in_count = PR_DEC_COUNT;
				ph_stable_value = ph_in_before;//光敏检测车停稳值
				return 1;//检测到车进入
	}
	return 0;
}
//////////////////////光敏检测车离开//////////////////////////
/***
输入：first_dec：对参数进行清零；next_dec：正常检测
功能：光敏检测车离开
输出：1：车离开；0：车未离开
***/

int ph_car_out(void)
{
	//thr_pho_resistor_A
	static uint8_t dec_car_out_count=0;
	static int16_t ph_out_before = 0;
        if(ph_out_before==0)ph_out_before = VAL_PHOTO;
	if((VAL_PHOTO - ph_out_before) > THR_PHO_RESISTOR_H)//阈值减小，增加灵敏度
	{
		dec_car_out_count++;
		if(dec_car_out_count>=PR_DEC_COUNT)
		{
                        ph_out_before = 0;
			dec_car_out_count = 0;
                        return 1;//检测到车离开
		}
	}
	else
	{
		dec_car_out_count = 0;
                ph_out_before = VAL_PHOTO;
	}
	return 0;//未检测到车离开
}

/**********判断白天和晚上*************/
/***
功能：白天晚上自动识别
***/
void judge_day_night(int flag)
{


		static int ph_value_sum_count = 0;
		static int32_t  ph_value_sum = 0;
                if(flag == 1)
                {
                        ph_value_sum_count = 0;
                        ph_value_sum = 0;
                }
                get_photoresistor_ad();
                ph_value_sum_count++;
                ph_value_sum = ph_value_sum + VAL_PHOTO;
                if(ph_value_sum_count >= 30)
                {
                        ph_value_sum = ph_value_sum/ph_value_sum_count;
                        if(ph_stable_value - ph_value_sum > DAY_OR_NIGHT2)
                        {
                                thr_pho_resistor_h = THR_night;
                                ph_stable_value = ph_value_sum;
                        }
                        else if(ph_value_sum - ph_stable_value > DAY_OR_NIGHT2)
                        {
                                thr_pho_resistor_h = THR_day;
                                ph_stable_value = ph_value_sum;
                        }
                        ph_value_sum = 0;
                        ph_value_sum_count = 0;
                }
}



/*
enum //TIME_STATE//时刻表
{
    T_10s            = 2,//10s
    T_20s         = 5,//20s
    T_40s          = 10,//40s
    T_60s            = 15,//1minute
    T_200s    = 50,//200s
    T_5m          = 75,//5mintutes
	NO_CAR                = 76//5mintutes+
};
*/
/***
输入：计数值
功能：时刻判断
输出：具体时刻

***/
static int judge_time_state(int time)
{
	if(time<T_30s)
	{
		time = T_5m;
	}
	else if(time<T_40s)//40s
	{
		time = T_5m;
	}
	else if(time<T_200s)//小于200s
	{
		time=T_5m;
	}
	else if(time<=T_5m)//<5分钟
	{
		time=T_5m;
	}
	else if(time>=NO_CAR)//>5minutes
	{
		time=NO_CAR;
	}
	return time;
}
/****
输入：无
功能：检测车进入

输出：0：未检测到车进入；1：光敏检测到车进入；2：地磁检测到车进入；3：光敏和地磁都检测到车进入
****/
static int common_dec_car_in(void)
{
	int i = 0,j = 0;
	i = ph_car_in(next_dec);
	j = geomag_car_in();
	if(i==0&&j==0)
	{
		return 0;//未检测到车进入
	}
	else if(i==1&&j==0)
	{

                asm("NOP");
		return 1;//光敏检测到车进入
	}
	else if(i==0&&j==1)
	{
                asm("NOP");
		return 2;//地磁检测到车进入
	}
	else if(i==1&&j==1)
	{
                asm("NOP");
		return 3;//地磁光敏都检测到车进入
	}
	return 0;
}
/***
输入：光敏状态，地磁状态
功能：光敏，地磁状态判断
输出：0：都坏，1：只光敏好，2：只地磁好，3：都好
***/
static int ge_ph_state(int ph_state_i,int ge_state_j)
{
	if(ph_state_i==0&&ge_state_j==0)
	{
		return 0;
	}
	else if(ph_state_i==1&&ge_state_j==0)
	{
		return 1;
	}
	else if(ph_state_i==0&&ge_state_j==1)
	{
		return 2;
	}
	else if(ph_state_i==1&&ge_state_j==1)
	{
		return 3;
	}
	return 0;
}

/***
功能：
***/
void wave_time_check(void)
{
        if(geo_wave_flag == 1)//有波动
        {
                geo_wave_count ++;
                if(geo_wave_count>=4)
                {
                       geo_wave_count = 4;
                }
        }
        else
        {
                geo_wave_count = 0;
        }

        if(ph_wave_flag == 1)
        {
                ph_wave_count ++;
                if(ph_wave_count>=4)
                {
                       ph_wave_count = 4;
                }
        }
        else
        {
                ph_wave_count = 0;
        }
}
/***
输入：无
功能:检测车离开
输出：1：检测到车离开；0：未检测到车离开
***/
static int common_dec_car_out()
{
        //protect_count
	int i = 0,j = 0;
	i = ph_car_out();
	j = geomag_car_out();
        if(i==0)geo_wave_flag = 0;
        wave_time_check();
	if((i==1&&j==1)||(i==1&&geo_wave_flag==1)||(j==1&&ph_wave_flag==1))
	{
                if((i==1&&geo_wave_flag==1)&&geo_wave_count<4)
                {
                        return 0;//bsp_DelayMS(15000);
                }
                else if((j==1&&ph_wave_flag==1)&&ph_wave_count<4)
                {
                        return 0;//bsp_DelayMS(15000);
                }
                ph_wave_count = 0;
                geo_wave_count = 0;
                return 1;//检测到车离开
	}
	return 0;
}
/*行程开关*/
#define GPIOP_TRAVELSWITCH_K1   GPIOB
#define GPIOB_TRAVELSWITCH_K1   GPIO_Pin_0
/**
*获取行程开关状态，锁关闭时，立起来，返回1；锁打开时，返回0
*/
u8 GetSysStatus(void)
{

	if(GPIO_ReadInputDataBit( GPIOP_TRAVELSWITCH_K1, GPIOB_TRAVELSWITCH_K1 ) == RESET)
	{
		if(GPIO_ReadInputDataBit( GPIOP_TRAVELSWITCH_K1, GPIOB_TRAVELSWITCH_K1 ) == RESET)
		return 0;
	}
	if(GPIO_ReadInputDataBit( GPIOP_TRAVELSWITCH_K1, GPIOB_TRAVELSWITCH_K1 ) != RESET)
	{
		if(GPIO_ReadInputDataBit( GPIOP_TRAVELSWITCH_K1, GPIOB_TRAVELSWITCH_K1 ) != RESET)
		return 1;
	}

	return 2;

}

/***
输入：无
功能：各时间段，地磁和光敏配合检测车进入及离开
输出：无
***/

uint8_t DelayTime4s = 0;
int8_t UltraDecCarCnt = 0;
bool UltraFaultFlag = 0;
void time_state(void)
{
        char printf_buff[100];
	int time = 0,temp = 0;
	int dec_flag = 0;
        if(SystemPara.QmcFixPara[3]==0x01)return;
        if(DelayTime4s)return;
        DelayTime4s = 1;
	if((LIMIT_READ)||(QMC5883LStr.DataOkFlag == 0)||(LockCarState.MotorActResults == FALL_ERROR)||(LockCarState.MotorActResults == RISE_OK)||((LockCarState.MotorCmd!=CmdIdle)))
        {
          GPIOA->ODR &= ~(1<<5);
          return;	
        }
	mag_time_count++;       
        QMC5883LStr.DataOkFlag = FALSE;
        //SendData(PC_REQ);
//        if(HC_DEBUG){
//            sprintf(printf_buff,"Tim:%d;P_BASE:%d,P_CUR:%d;QMC_BASE:X=%d,Z=%d;QMC_CUR:X=%d,Z=%d\n;car_state = %d\r\n",mag_time_count,ph_base,VAL_PHOTO,QMC5883LStr.QMC_BASE[0],QMC5883LStr.QMC_BASE[2],QMC5883LStr.QMC_CUR[0],QMC5883LStr.QMC_CUR[2],CarRecDataStr.CarState);
//            int i = 0;
//            printf(printf_buff);
////            while(printf_buff[i]!='\n')
////              UsartPrint(&printf_buff[i++],1);
//        }
        //UsartPrint(&mag_time_count,1);
        
        UltraSonicDateFlag = FALSE;
        if(UltraSonicDetecResult)
        {
              //BeepStart(1,0);
              GPIOA->ODR |= 1<<5;
              UltraDecCarCnt++;
        }
        else
        {
             GPIOA->ODR &= ~(1<<5);
             UltraDecCarCnt--;
        }
        if(UltraDecCarCnt>10)UltraDecCarCnt = 10;
        if(UltraDecCarCnt<-30)UltraDecCarCnt=-30;
	if(CarRecDataStr.CarState==0)
	{
		time = judge_time_state(mag_time_count);
                if(mag_time_count<=T_4s)
                {
                    UltraDecCarCnt = 0;
                    UltraFaultFlag = 0;
                    no_car_count = 0;
                    memcpy(QMC5883LStr.QMC_BASE,QMC5883LStr.QMC_CUR,3*sizeof(int16_t));
                    BeepStart(1,0);
                    UltraDecCarCnt = 0;
                    
                }
                if(time>T_30s)
                {
                        dec_flag = geomag_car_in();
//                        UltraSonicDateFlag = FALSE;
//                        if(UltraSonicDetecResult)
//                        {
//                          BeepStart(1,0);
//                          UltraDecCarCnt++;
//                        }
//                        else
//                        {
//                          UltraDecCarCnt--;
//                        }
//                        if(UltraDecCarCnt>10)UltraDecCarCnt = 10;
//                        if(UltraDecCarCnt<-5)UltraDecCarCnt=-5;
                }
		switch(time)
		{
                    case T_5m:
                    {
                          if(UltraDecCarCnt>=10)have_car_send();
                          break;
                    }
                    case NO_CAR:
                    {
                            NO_car_deal();
                            break;
                    }
                    default:
                            break;
		}

	}
	else//检测车离开
	{
          
                if(mag_time_count>=NO_CAR)UltraFaultFlag = 1;
                if(mag_time_count < T_3M)//前三分钟不检测车离开
                {
                        return;
                }
                else
                {
                        mag_time_count = T_3M;
                }

		if(UltraFaultFlag==0)
                {
                    if(SystemPara.QmcFixPara[1]>=30)temp = 30;//超声波检测车离开可配置
                    else
                    {
                      temp = SystemPara.QmcFixPara[1];
                    }
                    if(UltraDecCarCnt<(10-temp))
                    {
                      UltraFaultFlag = 1;
                      NO_car_deal();
                    }
                }
                else
                {
                    if(geomag_car_out()==1)NO_car_deal();
                }
        }
}

