api/sensor文件之api_paper_calibration.c

/******************************************************************************
版权所有:  深圳市**科技有限公司 
文件名:    api_paper_calibration.c
作者:      wangdy
创建日期:  2020/06/29
描述:      蓝牙模块初始化 
其它:      
修改历史:  //修改历史记录列表,每条修改记录应包含修改日期、修改者及修改内容简述
            序号    修改时间    修改人  修改内容
            ????    ????/??/??  ??????  参考样式       
******************************************************************************/

/************************************头文件************************************/

#include "printerConfig.h"
#include "bsp_w25x.h"
#include <string.h>
#include "yc_gpio.h"
#include "yc_timer.h"
#include "hard_config.h"
#include "bsp_sensor.h"
#include "api_sensorcheck.h"
#include "api_state_check.h"
#include "api_para_set.h"
#include "driver_adc.h"
#include "bsp_motor_control.h"
#include "printerConfig.h"
#include "var_global.h"
#include "driver_iwdg.h"
#include "api_paper_calibration.h"
#include "api_led_watchdog.h"
#include "api_key.h"

/*************************************宏定义*************************************/


/*************************************变量*************************************/

CaliValue_Table_TypeDef   CaliValue_Table = { 0 };

const uint16_t Cali_NoPaper_ADC[MAX_SENSOR_SCALE] = {
    1200,
    1200,
    1200,
    1200,
    650,
    231,
    203,
    190
};

/*************************************函数*************************************/

//表数据初始化 
static void CaliValueTable_Deinit(){
    int i = 0;
    int j = 0;
    for(i = CALI_MAX_SCALE - CALI_MIN_SCALE; i>= 0; i--){
        for(int j = 0; j<CALI_VALUE_TABLE_SIZE; j++){
            //初始化值  最大最小反填充   
            CaliValue_Table.ValueTable[i].Min_ValueTable[j] = CALI_ADC_MAX_VALUE;
            CaliValue_Table.ValueTable[i].Max_ValueTable[j] = CALI_ADC_MIN_VALUE;
            CaliValue_Table.ValueTable[i].ValueTableValidFlag = false;            //有效标记清除 
            CaliValue_Table.ValueTable[i].Min_Ave = CALI_ADC_MAX_VALUE;
            CaliValue_Table.ValueTable[i].Max_Ave = CALI_ADC_MAX_VALUE;
            CaliValue_Table.ValueTable[i].Min_Current_Index = 0;
            CaliValue_Table.ValueTable[i].Max_Current_Index = 0;
        }
    }
}

//更新表数据  
static void CaliValueTable_Update(int index,uint16_t value){
    uint32_t all_value_min = 0,all_value_max = 0;
    if(index > (CALI_MAX_SCALE - CALI_MIN_SCALE)){
        return;
    }
    
    //求最大表格  和最小表格的平均值 
    //最小  
    for(int j = 0; j< CALI_VALUE_TABLE_SIZE; j++){
        all_value_min += CaliValue_Table.ValueTable[index].Min_ValueTable[j];
    }
    CaliValue_Table.ValueTable[index].Min_Ave = all_value_min / CALI_VALUE_TABLE_SIZE;
    //最大 
    for(int j = 0; j< CALI_VALUE_TABLE_SIZE; j++){
        all_value_max += CaliValue_Table.ValueTable[index].Max_ValueTable[j];
    }
    CaliValue_Table.ValueTable[index].Max_Ave = all_value_max / CALI_VALUE_TABLE_SIZE;
    
    
    //将值加到数组里去(大于最大平均 或者小于最小平均 则替换数据)
    if(value < CaliValue_Table.ValueTable[index].Min_Ave){
        CaliValue_Table.ValueTable[index].Min_ValueTable[CaliValue_Table.ValueTable[index].Min_Current_Index++] = value;
        CaliValue_Table.ValueTable[index].Min_Current_Index %= CALI_VALUE_TABLE_SIZE;
        CaliValue_Table.ValueTable[index].Min_Min = value;        //最小值 
    }
    if(value > CaliValue_Table.ValueTable[index].Max_Ave){
        CaliValue_Table.ValueTable[index].Max_ValueTable[CaliValue_Table.ValueTable[index].Max_Current_Index++] = value;
        CaliValue_Table.ValueTable[index].Max_Current_Index %= CALI_VALUE_TABLE_SIZE;
    }
}


//双击校准  --- 间隙纸   
static CaliResult_TypeDef PaperCali_GapPaper(void)
{
    CaliResult_TypeDef        result;                        //间隙纸定标结果  
    static uint32_t MotorCurrCnt = 0;
    int scale_index = 0;                                //临时变量 
    bool  Find_Success_Flag = false;                    //找到结果了 
    uint32_t   Limit_Distance = CALIBRATE_FEEDLIMIT;    //最长多长 还找不到 就认为定标失败了 
    
    //初始化变量值 
    CaliValueTable_Deinit();                
    
    //开启电机及打印头电源 
    Matchine_5V_PrintHead_Motor_Power_On();
    delay_ms(100);
    MyPrintf("PaperCali_GapPaper\r\n"); 
    //循环查找  寻找定标位置及信息 
    while ((Limit_Distance > 0) ){
        //喂狗 
        IWDG_Feed;    
        //灯和按键  继续有效 
        LED_Update();
        
        //电机转动 2步走1个像素大小 
    PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,true);    //电机正转 走一步   
//        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_INVERSE,true);
        delay_us(500);
            
        //变量++
        MotorCurrCnt++;
        if(MotorCurrCnt < PIX_MOTOR_N_STEP){
            continue;
        }
        MotorCurrCnt = 0;
        Limit_Distance--;
        
        //找到合法值 
        for(scale_index = CALI_MAX_SCALE; scale_index>= CALI_MIN_SCALE; scale_index--){    
            //得到true index 
            int true_index = scale_index - CALI_MIN_SCALE;
            //逐位使能 
            EnableSensor(PAPER_GAP, scale_index);
            uint16_t  CurrentADCValue = StartSensorChannelADCValue();    //启动ADC 并且读出ADC值  
            DisableSensor(PAPER_GAP);                //失能传感器 
            //采集到数据  加入表内  
            CaliValueTable_Update(true_index,CurrentADCValue);
            
            #if 0
                MyPrintf("index:%d,min:%d,max:%d\n",scale_index,CaliValue_Table.ValueTable[true_index].Min_Ave,CaliValue_Table.ValueTable[true_index].Max_Ave);
            #endif 
            
            //先判断数值有没有完全满足条件  
            if(    (CaliValue_Table.ValueTable[true_index].Max_Ave > CaliValue_Table.ValueTable[true_index].Min_Ave) && 
                (CaliValue_Table.ValueTable[true_index].Max_Ave - CaliValue_Table.ValueTable[true_index].Min_Ave > GAP_MIN_MAX_AVE_THRESHOLD) ){
                CaliValue_Table.ValueTable[true_index].ValueTableValidFlag = true;
                CaliValue_Table.ValueTable[true_index].PaperGapThreshold =         //阈值 
                        (CaliValue_Table.ValueTable[true_index].Max_Ave + CaliValue_Table.ValueTable[true_index].Min_Ave)  / 2;
                CaliValue_Table.ValueTable[true_index].PaperGapDiffer =         //差值 
                        (CaliValue_Table.ValueTable[true_index].Max_Ave - CaliValue_Table.ValueTable[true_index].Min_Ave);
                //确定是找到间隙纸的位置  而非连续纸的位置 
                if(CurrentADCValue < CaliValue_Table.ValueTable[true_index].PaperGapThreshold){
                    Limit_Distance = 0;
                    Find_Success_Flag = true;        //找到突变位置成功了 
                }else {    //连续纸->间隙纸  重新找下一轮 
                    CaliValueTable_Deinit();        //恢复变量值  重新找 
                }    
                break;
            }else{
                CaliValue_Table.ValueTable[true_index].ValueTableValidFlag = false;
            }
        }
    }
    
    if(true == Find_Success_Flag) {
    
        //遍历  找到差值最大的index 
        uint16_t  Differ_Max = 0;                            //找到差值最大的
        uint16_t  Current_Threshold = 0;                    //当前的阈值 
        uint16_t  Min_Min = 0;
        uint16_t  Selected_Index = CALI_MAX_SCALE;            //选中的index 
        for(scale_index = CALI_MAX_SCALE; scale_index>= CALI_MIN_SCALE; scale_index--){
            int true_index = scale_index - CALI_MIN_SCALE;
            //如果该index合法 
            if(false == CaliValue_Table.ValueTable[true_index].ValueTableValidFlag){    
                continue;
            }
            //差值最大 
            if(CaliValue_Table.ValueTable[true_index].PaperGapDiffer >  Differ_Max){
                Differ_Max = CaliValue_Table.ValueTable[true_index].PaperGapDiffer;
                Current_Threshold = CaliValue_Table.ValueTable[true_index].PaperGapThreshold;
                Min_Min = CaliValue_Table.ValueTable[true_index].Min_Min;            //最小表内的平均值信息 
                Selected_Index = true_index + CALI_MIN_SCALE;        //真实index 
            }
        }
        
        #if 1
            MyPrintf("index: %d,max:%d,min:%d\n",Selected_Index,
            CaliValue_Table.ValueTable[Selected_Index - CALI_MIN_SCALE].Max_Ave,
            CaliValue_Table.ValueTable[Selected_Index - CALI_MIN_SCALE].Min_Ave);
        #endif 
        
        //走到撕纸处 
        Limit_Distance = PRINTHEAD_OPTICALCOUPLER_CALIBRATION_CUTTER;    
        while ((Limit_Distance > 0) ){
            //喂狗 
            IWDG_Feed;    
            //灯和按键  继续有效 
            LED_Update();
            
            //电机转动 2步走1个像素大小 
            PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,true);    //电机正转 走一步 
//            PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_INVERSE,true);
            delay_us(500);
                
            //变量++
            MotorCurrCnt++;
            if(MotorCurrCnt < PIX_MOTOR_N_STEP){
                continue;
            }
            MotorCurrCnt = 0;
            Limit_Distance--;    
        }
        
        //关闭电机使能 
        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,false);
//        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_INVERSE,false);
        //关闭电机及打印头电源 
        Matchine_5V_PrintHead_Motor_Power_Off();
        
        //更新值信息 
        result.isValidFlag = true;
        result.Gap_RefValue = Current_Threshold;
        result.SelectedIndex = Selected_Index; 
        result.HavePaper_RefValue = (Min_Min + Cali_NoPaper_ADC[Selected_Index]) / 2;
        #if 1
            MyPrintf("index:%d,gap_threshold: %d,have_threshold:%d\n",Selected_Index,result.Gap_RefValue,result.HavePaper_RefValue);
        #endif 
    }else {
        //关闭电机使能 
        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,false);
//        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,false);
        //关闭电机及打印头电源 
        Matchine_5V_PrintHead_Motor_Power_Off();
        
        //默认值  
        result.isValidFlag = false;
        result.Gap_RefValue = GAP_THRESHOLD_DEFAULT;
        result.SelectedIndex = SELECTED_INDEX_DEFAULT;    
        result.HavePaper_RefValue = NOPAPER_THRESHOLD_DEFAULT;
    }
    
    return result;
}

//校准 --- 连续纸  
static CaliResult_TypeDef PaperCali_ContinuePaper(void)
{
    CaliResult_TypeDef        result;                        //间隙纸定标结果  
    static uint32_t MotorCurrCnt = 0;
    uint32_t   Limit_Distance = 0;    //最长多长 还找不到 就认为定标失败了             
    
    //开启电机及打印头电源 
    Matchine_5V_PrintHead_Motor_Power_On();
    delay_ms(100);
        
    //走到撕纸处 
    Limit_Distance = CALIBRATE_CONTINUE_PAPER_FEEDLIMIT;    
    while ((Limit_Distance > 0) ){
        //喂狗 
        IWDG_Feed;    
        //灯和按键  继续有效 
        LED_Update();
        
        //电机转动 2步走1个像素大小 
        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,true);    //电机正转 走一步 
//        PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_INVERSE,true);
        delay_us(500);
            
        //变量++
        MotorCurrCnt++;
        if(MotorCurrCnt < PIX_MOTOR_N_STEP){
            continue;
        }
        MotorCurrCnt = 0;
        Limit_Distance--;    
    }
    
    //关闭电机使能 
    PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_POSITIVE,false);
//    PrintMotor_CalibrationRunOnPhase(MOTOR_RUN_INVERSE,false);
    //关闭电机及打印头电源 
    Matchine_5V_PrintHead_Motor_Power_Off();
    
    //默认值  
    result.isValidFlag = false;
    result.Gap_RefValue = GAP_THRESHOLD_DEFAULT;
    result.SelectedIndex = SELECTED_INDEX_DEFAULT;    
    result.HavePaper_RefValue = NOPAPER_THRESHOLD_DEFAULT;
    
    return result;
}

//校准进程   双击按键校准
void PaperCali_Process(void) {
    CaliResult_TypeDef Calresult = {0};
    static CalibrationParaStoreTypeDef calipara = {0};
    
    //开始进入标定进程  
    if(PAPER_GAP == Store_Para.Print_Paper_Type_Para.PrintPaperType){
        Calresult = PaperCali_GapPaper();
    }else if(PAPER_CONTINUE == Store_Para.Print_Paper_Type_Para.PrintPaperType){
        Calresult = PaperCali_ContinuePaper();
    }
    MyPrintf("PaperCali_Process\r\n"); 
    //存储进flash  定标完成了 开始存flash 
    //定标参数存储 

    calipara.SelectIndex = Calresult.SelectedIndex;
    calipara.GapRef = Calresult.Gap_RefValue;
    calipara.HavePaperRef = Calresult.HavePaper_RefValue;
    calipara.storeFlag = 0;
    
    //写参数入flash
    CalibrateParaWritetoFlash(&calipara);
    //参数更新 至全局变量 
    Store_CalibrationPara = calipara;
    
    #if 0
        MyPrintf("store finished\r\n");
        MyPrintf("SensorMode:%d,GapInten:%d,GapRef:%d\r\n",
            Store_Para.Print_Paper_Type_Para.PrintPaperType,
            calipara.SelectIndex,
            calipara.GapRef
        );
    #endif 
}

以下为.h文件:

/******************************************************************************
版权所有:  深圳**科技有限公司  
文件名:    api_calibration.h   
作者:      wangdy  
创建日期:  2021/6/4
描述:      纸张定标  
其它:      
修改历史:  //修改历史记录列表,每条修改记录应包含修改日期、修改者及修改内容简述
            序号    修改时间    修改人  修改内容
            ????    ????/??/??  ??????  参考样式       
******************************************************************************/

/*********************************防止多次编译*********************************/
#ifndef _API_PAPER_CALIBRATION_H
#define _API_PAPER_CALIBRATION_H

/************************************头文件************************************/
#include <stdint.h>
#include <stdbool.h>
#include "bsp_sensor.h"
#include "printerConfig.h"
#include "driver_adc.h"
#include "api_sensorcheck.h"

/************************************宏定义************************************/

//定标最大距离   
#define CALIBRATE_FEEDLIMIT                            800       //100 mm  定标最长 
#define CALIBRATE_CONTINUE_PAPER_FEEDLIMIT            80       //10 mm  连续纸走定长 
//走纸最大距离  
#define FEEDPAPER_FEEDLIMIT            500          //60  mm  走纸最长 

#define CALIBRATE_PAPER_MIN            (MM_DOT * 10)        //纸张部分检测的最小距离 mm
#define CALIBRATE_GAP_MIN              (MM_DOT)            //间隙部分检测的最小距离 mm
#define CALIBRATE_GAP_MAX             (MM_DOT * 40)        //间隙部分检测的最大距离 mm 


#define CALI_MAX_SCALE                5
#define CALI_MIN_SCALE                3
#define CALI_SCALE_VALID_SIZE        3

#define CALI_VALUE_TABLE_SIZE        8        //正好1mm 

#define CALI_ADC_MIN_VALUE            0 
#define CALI_ADC_MAX_VALUE            1200


//_#define GAP_THRESHOLD_DEFAULT        800
#define GAP_THRESHOLD_DEFAULT            1000     //间隙纸阈值
#define SELECTED_INDEX_DEFAULT        5
//_#define NOPAPER_THRESHOLD_DEFAULT    360
#define NOPAPER_THRESHOLD_DEFAULT        920     //有纸的阈值
#define GAP_MIN_MAX_AVE_THRESHOLD        500

/************************************枚举************************************/


/************************************结构体************************************/

typedef struct{
    uint16_t  Min_ValueTable[CALI_VALUE_TABLE_SIZE];    //最小值表 
    uint16_t  Max_ValueTable[CALI_VALUE_TABLE_SIZE];    //最大值表 
    bool      ValueTableValidFlag;                        //合法标记 
    uint16_t  Min_Ave;                                    //小表的平均值 
    uint16_t  Max_Ave;                                    //大表的平均值  
    uint16_t  Min_Min;                                    //小表里面的最小值 
    uint8_t   Min_Current_Index;                        //大表的当前的Index
    uint8_t   Max_Current_Index;                        //大表的当前的Index 
    uint16_t  PaperGapThreshold;                        //阈值信息         
    uint16_t  PaperGapDiffer;                            //阈值信息                     
}CaliValue_Table_Single_TypeDef;

typedef struct{
    CaliValue_Table_Single_TypeDef   ValueTable[CALI_SCALE_VALID_SIZE];
}CaliValue_Table_TypeDef;

//结果 
typedef struct{
    bool                isValidFlag;                    //有效标记 
    uint8_t                SelectedIndex;                    //选择的索引  
    int                    Gap_RefValue;                    //间隙纸对应的阈值信息  
    int                 HavePaper_RefValue;                //无纸对应的值信息 
}CaliResult_TypeDef;

/**********************************可导出变量**********************************/

/***********************************函数实现***********************************/
void PaperCali_Process();

#endif


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值