zynq_7010/zynq_7010_code/Scanner.cpp

508 lines
13 KiB
C++
Raw Permalink Normal View History

2023-07-17 03:29:37 +00:00
#include "Scanner.h"
#include <iostream>
2023-07-17 03:29:37 +00:00
#include "MemoryInfo.h"
#include "SysInforTool.h"
2023-11-18 03:48:39 +00:00
#include "StopWatch.h"
2023-07-17 03:29:37 +00:00
2023-10-10 10:12:15 +00:00
#define BTN_START 0
#define BTN_STOP 1 //按键停止扫描
#define BTN_LOW_POWER 2 //按键低功耗
#define BTN_NORMAL_POWER 3 //按键正常模式 (退出低功耗)
2023-07-17 03:29:37 +00:00
Scanner::Scanner(ScannerGlue glue)
2024-02-06 09:28:31 +00:00
: 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)
2023-07-17 03:29:37 +00:00
{
2023-11-18 03:48:39 +00:00
frame_time_ = 3000;
2023-07-17 03:29:37 +00:00
m_scaninfo = GetScanInfoFromJson();
capturer.reset(new MultiFrameCapture(m_glue));
2023-07-17 03:29:37 +00:00
capturer->SetParent(this);
2023-11-18 03:48:39 +00:00
capturer->set_image_callback(&have_img_callback);
2023-11-18 09:06:42 +00:00
2023-09-19 02:12:37 +00:00
//固件版本
int version=7010;
2023-07-17 03:29:37 +00:00
auto btnevent = [this](const int eventtype)
{
if (!IsScanning()) //未扫描
{
switch (eventtype)
2023-10-10 10:12:15 +00:00
{
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;
2023-10-10 10:12:15 +00:00
}
2023-07-17 03:29:37 +00:00
}
else //扫描中
{
2023-10-10 10:12:15 +00:00
if (eventtype == BTN_STOP)
2023-07-17 03:29:37 +00:00
{
put(S_EVT_STOP_SCAN);
printf("keyboard cancel scan\r\n");
2023-07-17 03:29:37 +00:00
}
}
};
sensor = std::make_shared<Sensor>(sysEvent);
2023-11-18 09:06:42 +00:00
2023-07-17 03:29:37 +00:00
m_keyboard.reset(new huagao::Keyboard(btnevent));
m_keyboard->init();
2023-11-18 09:06:42 +00:00
2023-07-17 03:29:37 +00:00
motorZouzhi.enablePower(true);
motorZouzhi.setSpeed(4000);
motorCuozhi.setSpeed(3000);
motorCuozhi.setDirection(false);
2023-09-19 02:40:47 +00:00
2023-07-17 03:29:37 +00:00
FsmState::setScanner(this);
threadRunMessageLoop = std::thread(&Scanner::runMessageLoop, this);
Motor::enablePower(true);
2024-02-06 09:28:31 +00:00
UpdateScanInfo();
2023-07-17 03:29:37 +00:00
}
Scanner::~Scanner()
{
Motor::enablePower(false);
sysEvent.Clear();
sysEvent.ShutDown();
bMsgLoop = false;
threadRunMessageLoop.join();
m_DstScannum = 0;
if (threadRunScan.joinable())
threadRunScan.join();
}
2023-10-21 09:20:07 +00:00
void Scanner::updateSpeedMode()
2023-07-17 03:29:37 +00:00
{
m_scaninfo = GetScanInfoFromJson();
2024-02-06 09:28:31 +00:00
int speed = m_scaninfo.SpeedMode;
printf("JSON文件获取当前速度%d\r\n",speed);
if(speed == 0)
speed = 3;
2023-10-07 06:08:42 +00:00
2023-09-14 02:46:04 +00:00
unsigned int t_dpi = m_config.params.dpi;
2023-09-19 02:40:47 +00:00
2023-10-31 10:05:43 +00:00
if(m_config.params.pageSize == (unsigned int)PaperSize::G400_MAXSIZE || m_config.params.pageSize == (unsigned int)PaperSize::G400_MAXAUTO ) //长文稿采用600dpi模式扫描
2023-10-21 09:20:07 +00:00
t_dpi = 3;
if (m_config.params.slow_moire) //摩尔纹特殊处理
2024-02-06 09:28:31 +00:00
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);
2023-10-21 09:20:07 +00:00
2024-02-06 09:28:31 +00:00
motorCuozhi.speedChange(Cuozhi_ParamEx_);
motorZouzhi.speedChange(Zouzhi_ParamEx_);
2023-07-17 03:29:37 +00:00
}
2024-02-06 09:28:31 +00:00
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;
2023-07-17 03:29:37 +00:00
2024-02-06 09:28:31 +00:00
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();
}
2023-11-18 03:48:39 +00:00
void Scanner::have_img_callback(int val)
{
if (val < 0)
{
frame_time_ = 3000;
}
frame_time_ = val ;
}
2023-07-17 03:29:37 +00:00
void Scanner::startScan()
{
if (threadRunScan.joinable())
threadRunScan.join();
stop_countdown();
2024-02-06 09:28:31 +00:00
2023-10-21 09:20:07 +00:00
updateSpeedMode();
2023-07-17 03:29:37 +00:00
// //开始进行扫描
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)
{
2023-11-18 03:48:39 +00:00
//printf("回调开盖1111\r\n");
m_glue.m_deviceevent(1, "Cover Open");
}
else if (typeid(*fsmState) == typeid(CoverOpenState) && !isScaning)
2023-07-17 03:29:37 +00:00
{
2023-11-18 03:48:39 +00:00
//printf("回调开盖2222\r\n");
2023-07-17 03:29:37 +00:00
m_glue.m_deviceevent(1, "Cover Open");
}
2023-07-17 03:29:37 +00:00
else if (event == S_EVT_SCAN_STOPPED)
{
2023-11-18 03:48:39 +00:00
//printf("回调停止1111\r\n");
2023-07-17 03:29:37 +00:00
if (!m_correctting)
{
m_glue.m_deviceevent(70, "Scan done");
}
}
else if (event == S_EVT_JAM_IN)
{
2023-11-18 03:48:39 +00:00
//printf("回调搓纸失败11111\r\n");
2023-07-17 03:29:37 +00:00
m_glue.m_deviceevent(4, "Feed error");
}
else if (event == S_EVT_DOUBLEPAPER)
{
//printf("回调:双张\r\n");
2023-07-17 03:29:37 +00:00
m_glue.m_deviceevent(16, "Double feed");
}
else if (event == S_EVT_JAM_OUT || typeid(*fsmState) == typeid(ErrorJamState))
{
//printf("回调:卡纸\r\n");
2023-07-17 03:29:37 +00:00
m_glue.m_deviceevent(8, "Jam out");
}
else if (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true)
{
2023-11-18 03:48:39 +00:00
//printf("回调搓纸失败22222\r\n");
2023-07-17 03:29:37 +00:00
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)
{
2023-11-18 03:48:39 +00:00
//printf("回调停止2222\r\n");
2023-07-17 03:29:37 +00:00
m_glue.m_deviceevent(70, "Scan Stop");
}
}
}
void Scanner::runScan()
{
LOG("-------------Scanner RunScan Start-------------\r\n");
capturer->open();
motorZouzhi.start();
motorCuozhi.pauseWaitForThread();
2023-08-31 08:37:05 +00:00
2023-07-17 03:29:37 +00:00
if (!isPaperInit)
{
preFeed();
2023-07-17 03:29:37 +00:00
isPaperInit = true;
}
2023-11-18 09:06:42 +00:00
this_thread::sleep_for(std::chrono::milliseconds(200));
sensor->resetPaperPin();
2023-07-17 03:29:37 +00:00
capturer->resetimageremain();
capturer->setScanFlag(true);
2023-08-09 07:31:27 +00:00
2023-07-17 03:29:37 +00:00
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;
2023-09-14 02:46:04 +00:00
StopWatch sw1;
2023-11-07 06:34:33 +00:00
isScaning = true;
int error_code = 0;
2023-07-17 03:29:37 +00:00
while (m_DstScannum > 0)
{
2023-11-07 06:34:33 +00:00
isScaning = true;
2023-09-14 02:46:04 +00:00
sw1.reset();
2023-07-17 03:29:37 +00:00
m_isDoublePaper = false;
m_jamPaper = false;
m_jamIn = false;
if (!sensor->isPaperStandby()) //无纸
{
if (!sensor->waitPaperStandBy(0))
{
put(S_EVT_STOP_SCAN);
}
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
sensor->enableDoubleSensor(m_config.params.doubleFeeded);
2023-09-19 02:40:47 +00:00
2023-07-17 03:29:37 +00:00
if (m_DstScannum == 0) //被取消扫描了
{
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
motorCuozhi.startAsyn(); //
2023-07-17 03:29:37 +00:00
if (!sensor->isPaperStandby())
{
put(S_EVT_STOP_SCAN);
isRested = false;
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
isRested = false;
2023-09-19 01:24:12 +00:00
if (!sensor->waitPaperIn(3000))//
2023-07-17 03:29:37 +00:00
{
if (!m_isDoublePaper)
{
m_jamIn = true;
put(S_EVT_JAM_IN);
m_scaninfo.JamInNum++;
}
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
2023-09-14 02:46:04 +00:00
printf("检测到纸张的时间:%f\r\n",sw.elapsed_ms());//检测到纸张
capturer->snap();
2023-11-18 03:48:39 +00:00
motorCuozhi.pauseWaitForThread();
capturer->wait_image_notify();
2023-11-18 03:48:39 +00:00
if (!sensor->isCoverClosed()) //中途开盖 笑麻了
{
break;
}
2023-07-17 03:29:37 +00:00
printf("一张纸所需要的采集时间:%dms\r\n",frame_time_);
2023-11-18 03:48:39 +00:00
if (sensor->waitPaperOut(frame_time_))
{
2023-07-17 03:29:37 +00:00
if (!m_isDoublePaper)
{
2023-11-18 03:48:39 +00:00
error_code = (int)HG_ScannerStatus::PAPER_JAM;
2023-07-17 03:29:37 +00:00
m_jamPaper = true;
put(S_EVT_JAM_OUT);
m_scaninfo.JamOutNum++;
2023-11-04 01:38:17 +00:00
printf("paper 卡纸了。。。。。\n");
2023-07-17 03:29:37 +00:00
}
else
error_code = (int)HG_ScannerStatus::DETECT_DOUBLE_FEED;
printf("error_code:%d\r\n",error_code);
capturer->waitsnapdone(error_code);//等待采集完成
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
2023-11-18 03:48:39 +00:00
sensor->enableDoubleSensor(false);
2023-07-17 03:29:37 +00:00
capturer->stopsnap(b_autosize);
2023-11-18 03:48:39 +00:00
error_code = m_isDoublePaper ? (int)HG_ScannerStatus::DETECT_DOUBLE_FEED : m_jamPaper ? (int)HG_ScannerStatus::PAPER_JAM :0;
capturer->waitsnapdone(error_code);//等待采集完成
2023-08-09 07:31:27 +00:00
{
m_DstScannum--;
m_scaninfo.RollerNum++;
m_scaninfo.TotalScanned++;
}
2023-07-17 03:29:37 +00:00
if (m_DstScannum == 0)
{
put(S_EVT_STOP_SCAN);
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
sw.reset();
2023-11-18 03:48:39 +00:00
////必须控制队列帧数。
while ( m_config.params.dpi == 0x01 && image_num_>=15)
{
printf("200DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
this_thread::sleep_for(std::chrono::milliseconds(300));
}
2023-12-25 06:16:56 +00:00
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));
}
2023-12-25 06:16:56 +00:00
// 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)
2023-07-17 03:29:37 +00:00
{
printf("600DPI 图像队列过多,正在等待图像取走:%d\r\n",image_num_);
this_thread::sleep_for(std::chrono::milliseconds(300));
}
while (meminfo->GetMemoryUsed() > 90.0f) //内存占用高于75% 其实我觉得开发人员应该自己控制好这个内存大小,让他绝对不可能超过这个内存大小
{
2023-08-31 08:37:05 +00:00
if (sw.elapsed_s() < 50.0)
2023-11-18 03:48:39 +00:00
std::this_thread::yield();
2023-07-17 03:29:37 +00:00
else
{
put(S_EVT_STOP_SCAN);
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
break;
}
}
2023-07-17 03:29:37 +00:00
}
2023-11-07 06:34:33 +00:00
isScaning = false;
2023-07-17 03:29:37 +00:00
m_DstScannum = 0;
sensor->enableDoubleSensor(false);
sensor->resetPaperPin();
capturer->setScanFlag(false);
capturer->stopsnap(b_autosize);
2023-08-09 07:31:27 +00:00
int t_delay = 500;
2023-09-15 06:05:42 +00:00
this_thread::sleep_for(std::chrono::milliseconds(t_delay)); //走纸多转一会儿 确保扫描传感器过了之后 纸能出完
2023-07-17 03:29:37 +00:00
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();
2023-09-19 02:40:47 +00:00
2023-07-17 03:29:37 +00:00
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,
2023-09-19 02:12:37 +00:00
.FPGAVersion = 0,
.Cistype = HGCISType::CIS_UNKOWNUN,
2023-07-17 03:29:37 +00:00
.ResSup = {200, 300, 0},
.MemTotal = 0,
.DiskTotal = 100,
.DiskUsed = 0,
.KernelVersion = "",
.Have_EthernPort = 0,
.ServiceVersion = fwverion,
.UsbProtocol = 1.0};
2023-09-19 02:40:47 +00:00
2023-07-17 03:29:37 +00:00
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;
2023-11-18 03:48:39 +00:00
if (threadRunScan.joinable())
threadRunScan.join();
2023-11-18 03:48:39 +00:00
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;
2024-02-06 09:28:31 +00:00
printf("Scanner->motorCuozhi is reseted \n");
}
}
void Scanner::paper_pullout()
{
if (!m_isPulling)
m_isPulling = true;
motorCuozhi.stop();
2024-02-06 09:28:31 +00:00
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;
}