zynq_7010/zynq_7010_code/Scanner.cpp

508 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Scanner.h"
#include <iostream>
#include "MemoryInfo.h"
#include "SysInforTool.h"
#include "StopWatch.h"
#define BTN_START 0
#define BTN_STOP 1 //按键停止扫描
#define BTN_LOW_POWER 2 //按键低功耗
#define BTN_NORMAL_POWER 3 //按键正常模式 (退出低功耗)
Scanner::Scanner(ScannerGlue glue)
: motorZouzhi(),motorCuozhi(),motor_cfg_(),
m_glue(glue),m_isPulling(false),
m_isDoublePaper(false),isPaperInit(false),
m_jamPaper(false),m_jamIn(false),
m_correctting(false),waitpapertime(200),
m_scansysinfo(nullptr),auto_size_(false)
{
frame_time_ = 3000;
m_scaninfo = GetScanInfoFromJson();
capturer.reset(new MultiFrameCapture(m_glue));
capturer->SetParent(this);
capturer->set_image_callback(&have_img_callback);
//固件版本
int version=7010;
auto btnevent = [this](const int eventtype)
{
if (!IsScanning()) //未扫描
{
switch (eventtype)
{
case BTN_LOW_POWER:
stop_countdown();
system("sh /mnt/flash-disk/low_power.sh 1");
break;
case BTN_NORMAL_POWER:
system("sh /mnt/flash-disk/low_power.sh 0");
start_enter_lowpwoer();
break;
case BTN_START:
/* code */
break;
default:
break;
}
}
else //扫描中
{
if (eventtype == BTN_STOP)
{
put(S_EVT_STOP_SCAN);
printf("keyboard cancel scan\r\n");
}
}
};
sensor = std::make_shared<Sensor>(sysEvent);
m_keyboard.reset(new huagao::Keyboard(btnevent));
m_keyboard->init();
motorZouzhi.enablePower(true);
motorZouzhi.setSpeed(4000);
motorCuozhi.setSpeed(3000);
motorCuozhi.setDirection(false);
FsmState::setScanner(this);
threadRunMessageLoop = std::thread(&Scanner::runMessageLoop, this);
Motor::enablePower(true);
UpdateScanInfo();
}
Scanner::~Scanner()
{
Motor::enablePower(false);
sysEvent.Clear();
sysEvent.ShutDown();
bMsgLoop = false;
threadRunMessageLoop.join();
m_DstScannum = 0;
if (threadRunScan.joinable())
threadRunScan.join();
}
void Scanner::updateSpeedMode()
{
m_scaninfo = GetScanInfoFromJson();
int speed = m_scaninfo.SpeedMode;
printf("JSON文件获取当前速度%d\r\n",speed);
if(speed == 0)
speed = 3;
unsigned int t_dpi = m_config.params.dpi;
if(m_config.params.pageSize == (unsigned int)PaperSize::G400_MAXSIZE || m_config.params.pageSize == (unsigned int)PaperSize::G400_MAXAUTO ) //长文稿采用600dpi模式扫描
t_dpi = 3;
if (m_config.params.slow_moire) //摩尔纹特殊处理
t_dpi = speed = 16;
Zouzhi_ParamEx_ = motor_cfg_.GetMotorSpeedParam(true,MotorConfig::MTBDType::MT_TMC,speed,m_config.params.isColor,t_dpi);
Cuozhi_ParamEx_ = motor_cfg_.GetMotorSpeedParam(false,MotorConfig::MTBDType::MT_TMC,speed,m_config.params.isColor,t_dpi);
motorCuozhi.speedChange(Cuozhi_ParamEx_);
motorZouzhi.speedChange(Zouzhi_ParamEx_);
}
void Scanner::ConfigScanParam(HG_ScanConfiguration config)
{
m_config = config;
auto_size_ = m_config.params.pageSize==(int)PaperSize::G400_AUTO ||
m_config.params.pageSize==(int)PaperSize::G400_MAXAUTO ||
m_config.params.pageSize==(int)PaperSize::G400_MAXSIZE;
updateSpeedMode();
capturer->UpdateScanParam(m_config);
}
void Scanner::UpdateScanInfo()
{
m_scaninfo = GetScanInfoFromJson();
auto params = motor_cfg_.GetMotorSpeedParams(true,MotorConfig::MTBDType::MT_TMC);
for (int i = 0; i < params.size(); i++)
{
if (params[i].speed == m_scaninfo.SpeedMode)
{
auto fpgaparam = GetFpgaparam(params[i].dpi, params[i].colormode);
fpgaparam.Sp = params[i].sp;
SaveFpgaparam(fpgaparam);
if (params[i].dpi == 3 && params[i].colormode)
{
printf("sp sp sp sp sp sp sp sp sp:%d :%d\r\n",params[i].sp,fpgaparam.Sp);
}
}
// if(params[i].speed == 0x10)
// {
// auto fpgaparam = GetFpgaparam(params[i].dpi, params[i].colormode);
// fpgaparam.Sp = params[i].sp;
// SaveFpgaparam(fpgaparam);
// }
}
updateSpeedMode();
}
void Scanner::have_img_callback(int val)
{
if (val < 0)
{
frame_time_ = 3000;
}
frame_time_ = val ;
}
void Scanner::startScan()
{
if (threadRunScan.joinable())
threadRunScan.join();
stop_countdown();
updateSpeedMode();
// //开始进行扫描
threadRunScan = std::thread(&Scanner::runScan, this);
}
void Scanner::runMessageLoop()
{
std::this_thread::sleep_for(std::chrono::milliseconds(3000));//避免scanpin io 开始异常
GetSysInfo();//待fpga 重启完成
FsmState *fsmState = FsmStateManagerEx<InitState>::GetState();
while (bMsgLoop)
{
ScanEvent evt = sysEvent.Take();
fsmState = fsmState->on_event(evt);
processevent(fsmState, evt);
}
}
void Scanner::processevent(FsmState *fsmState, ScanEvent event)
{
if (fsmState == nullptr)
{
return;
}
//开盖模式1 扫描中开盖 2 未扫描的时候开盖 ,目前我想不到更好的方法,暂时先这样处理
if (event == S_EVT_COVER_OPENED && isScaning)
{
//printf("回调开盖1111\r\n");
m_glue.m_deviceevent(1, "Cover Open");
}
else if (typeid(*fsmState) == typeid(CoverOpenState) && !isScaning)
{
//printf("回调开盖2222\r\n");
m_glue.m_deviceevent(1, "Cover Open");
}
else if (event == S_EVT_SCAN_STOPPED)
{
//printf("回调停止1111\r\n");
if (!m_correctting)
{
m_glue.m_deviceevent(70, "Scan done");
}
}
else if (event == S_EVT_JAM_IN)
{
//printf("回调搓纸失败11111\r\n");
m_glue.m_deviceevent(4, "Feed error");
}
else if (event == S_EVT_DOUBLEPAPER)
{
//printf("回调:双张\r\n");
m_glue.m_deviceevent(16, "Double feed");
}
else if (event == S_EVT_JAM_OUT || typeid(*fsmState) == typeid(ErrorJamState))
{
//printf("回调:卡纸\r\n");
m_glue.m_deviceevent(8, "Jam out");
}
else if (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true)
{
//printf("回调搓纸失败22222\r\n");
m_glue.m_deviceevent(4, "Feed error");
}
if (!IsScanning() && (typeid(*fsmState) == typeid(ErrorJamState) ||
typeid(*fsmState) == typeid(CoverOpenState) ||
(typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true)))
{
if (!m_correctting)
{
//printf("回调停止2222\r\n");
m_glue.m_deviceevent(70, "Scan Stop");
}
}
}
void Scanner::runScan()
{
LOG("-------------Scanner RunScan Start-------------\r\n");
capturer->open();
motorZouzhi.start();
motorCuozhi.pauseWaitForThread();
if (!isPaperInit)
{
preFeed();
isPaperInit = true;
}
this_thread::sleep_for(std::chrono::milliseconds(200));
sensor->resetPaperPin();
capturer->resetimageremain();
capturer->setScanFlag(true);
bool b_autosize = m_config.params.pageSize==(int)PaperSize::G400_AUTO ||
m_config.params.pageSize==(int)PaperSize::G400_MAXAUTO ||
m_config.params.pageSize==(int)PaperSize::G400_MAXSIZE;
StopWatch sw;
StopWatch sw1;
isScaning = true;
int error_code = 0;
while (m_DstScannum > 0)
{
isScaning = true;
sw1.reset();
m_isDoublePaper = false;
m_jamPaper = false;
m_jamIn = false;
if (!sensor->isPaperStandby()) //无纸
{
if (!sensor->waitPaperStandBy(0))
{
put(S_EVT_STOP_SCAN);
}
isScaning = false;
break;
}
sensor->enableDoubleSensor(m_config.params.doubleFeeded);
if (m_DstScannum == 0) //被取消扫描了
{
isScaning = false;
break;
}
motorCuozhi.startAsyn(); //
if (!sensor->isPaperStandby())
{
put(S_EVT_STOP_SCAN);
isRested = false;
isScaning = false;
break;
}
isRested = false;
if (!sensor->waitPaperIn(3000))//
{
if (!m_isDoublePaper)
{
m_jamIn = true;
put(S_EVT_JAM_IN);
m_scaninfo.JamInNum++;
}
isScaning = false;
break;
}
printf("检测到纸张的时间:%f\r\n",sw.elapsed_ms());//检测到纸张
capturer->snap();
motorCuozhi.pauseWaitForThread();
capturer->wait_image_notify();
if (!sensor->isCoverClosed()) //中途开盖 笑麻了
{
break;
}
printf("一张纸所需要的采集时间:%dms\r\n",frame_time_);
if (sensor->waitPaperOut(frame_time_))
{
if (!m_isDoublePaper)
{
error_code = (int)HG_ScannerStatus::PAPER_JAM;
m_jamPaper = true;
put(S_EVT_JAM_OUT);
m_scaninfo.JamOutNum++;
printf("paper 卡纸了。。。。。\n");
}
else
error_code = (int)HG_ScannerStatus::DETECT_DOUBLE_FEED;
printf("error_code:%d\r\n",error_code);
capturer->waitsnapdone(error_code);//等待采集完成
isScaning = false;
break;
}
sensor->enableDoubleSensor(false);
capturer->stopsnap(b_autosize);
error_code = m_isDoublePaper ? (int)HG_ScannerStatus::DETECT_DOUBLE_FEED : m_jamPaper ? (int)HG_ScannerStatus::PAPER_JAM :0;
capturer->waitsnapdone(error_code);//等待采集完成
{
m_DstScannum--;
m_scaninfo.RollerNum++;
m_scaninfo.TotalScanned++;
}
if (m_DstScannum == 0)
{
put(S_EVT_STOP_SCAN);
isScaning = false;
break;
}
sw.reset();
////必须控制队列帧数。
while ( m_config.params.dpi == 0x01 && image_num_>=15)
{
printf("200DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
this_thread::sleep_for(std::chrono::milliseconds(300));
}
while ( m_config.params.dpi == 0x02 && image_num_ >= 8 && m_config.params.isColor == 1)
{
printf("300DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
this_thread::sleep_for(std::chrono::milliseconds(300));
}
// while ( m_config.params.dpi == 0x02 && image_num_ >= 20 && m_config.params.isColor == 0)
// {
// printf("300DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
// this_thread::sleep_for(std::chrono::milliseconds(300));
// }
while ( m_config.params.dpi == 0x03 && image_num_ >= 2)
{
printf("600DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
this_thread::sleep_for(std::chrono::milliseconds(300));
}
while (meminfo->GetMemoryUsed() > 90.0f) //内存占用高于75% 其实我觉得开发人员应该自己控制好这个内存大小,让他绝对不可能超过这个内存大小
{
if (sw.elapsed_s() < 50.0)
std::this_thread::yield();
else
{
put(S_EVT_STOP_SCAN);
isScaning = false;
break;
}
}
}
isScaning = false;
m_DstScannum = 0;
sensor->enableDoubleSensor(false);
sensor->resetPaperPin();
capturer->setScanFlag(false);
capturer->stopsnap(b_autosize);
int t_delay = 500;
this_thread::sleep_for(std::chrono::milliseconds(t_delay)); //走纸多转一会儿 确保扫描传感器过了之后 纸能出完
LOG("\n--------------------------scan done --------------------------------\n");
}
void Scanner::CreatCorrectData(int correctmode)
{
m_correctting = true;
capturer->createCorrect(correctmode);
}
void Scanner::preFeed()
{
int sleeptime = 300;
motorCuozhi.feeding();
std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
motorCuozhi.pause();
std::this_thread::sleep_for(std::chrono::milliseconds(300));
}
std::string Scanner::GetSysInfo()
{
meminfo = MemoryInfo::GetInstance();
auto scannerinfo = GetScanInfo();
auto fwverion = mapFradme_SP[scannerinfo.SpeedMode].FWVERSIO;
ScannerSysInfo info = {
.CPU = SCPU::CPU_3288,
.Systype = SysType::Sys_Linux_Debian,
.Screentype = ScreenType::ST_None,
.MtBoardVersion = 0x20220114,
.MtType = SMBType::MB_DRV_UNKNOWUN,
.FPGAVersion = 0,
.Cistype = HGCISType::CIS_UNKOWNUN,
.ResSup = {200, 300, 0},
.MemTotal = 0,
.DiskTotal = 100,
.DiskUsed = 0,
.KernelVersion = "",
.Have_EthernPort = 0,
.ServiceVersion = fwverion,
.UsbProtocol = 1.0};
m_scansysinfo.reset(new SysInforTool(info));
return m_scansysinfo->GetSysInfo();
}
void Scanner::emergency_stop(int id)
{
sensor->cancelWaitPaper();
sensor->enableDoubleSensor(false);
m_DstScannum = 0;
motorCuozhi.stop();
motorZouzhi.stop();
capturer->stopsnap(true);
put(S_EVT_SCAN_STOPPED);
SaveScaninfo(m_scaninfo);
start_enter_lowpwoer();
printf("emergency_stop capturer->close() \n");
}
void Scanner::stop_scan()
{
sensor->cancelWaitPaper();
sensor->enableDoubleSensor(false);
m_DstScannum = 0;
if (threadRunScan.joinable())
threadRunScan.join();
motorZouzhi.stop();
motorCuozhi.stop();
put(S_EVT_SCAN_STOPPED);
SaveScaninfo(m_scaninfo);
start_enter_lowpwoer();
printf("stop_scan stop_scan stop_scan\r\n");
}
void Scanner::reset()
{
if (!sensor->isPaperStandby())
{
motorCuozhi.reset();
isRested = true;
isPaperInit = false;
printf("Scanner->motorCuozhi is reseted \n");
}
}
void Scanner::paper_pullout()
{
if (!m_isPulling)
m_isPulling = true;
motorCuozhi.stop();
MotorSpeedParamEx ParamEx = motor_cfg_.GetMotorSpeedParam(true,MotorConfig::MTBDType::MT_TMC,1,1,1);
motorZouzhi.speedChange(ParamEx);
motorZouzhi.setDirection(1);
motorZouzhi.start();
if (sensor->waitPaperOut(5000))
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
motorZouzhi.stop();
motorZouzhi.speedRecover();
m_isPulling = false;
}