/******************************************************************************
版权所有: 深圳市**科技有限公司
文件名: 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