#include "Scanner.h" #include #include "filetools.h" #include "fpgacontrol.h" #include "MemoryInfo.h" #include "SysInforTool.h" #include "USBProtocol.h" #define BTNSTART 0 #define BTNSTOP 1 #define BTNPOWER 2 Scanner::Scanner(ScannerGlue glue) : motorZouzhi(), motorCuozhi(), 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) { cisvendor = GetCisType(); m_scaninfo = GetScanInfoFromJson(); capturer.reset(new MultiFrameCapture(m_glue,cisvendor)); capturer->SetParent(this); //固件版本 int version=7010; fpgacontrol fc(version); if (fc.ifneedupdatefpga()) { if (fc.updatefpga()) { system("poweroff"); } else { LOG("error error update fpga error"); } } auto btnevent = [this](const int eventtype) { if (!IsScanning()) //未扫描 { if (eventtype == BTNPOWER) { system("echo mem > /sys/power/state"); } else if (eventtype == BTNSTART) { // put(S_EVT_START_SCAN); } } else //扫描中 { if (eventtype == BTNSTOP) { put(S_EVT_STOP_SCAN); LOG("BTN_STOP put(S_EVT_STOP_SCAN)"); } } }; sensor = std::make_shared(sysEvent); this_thread::sleep_for(std::chrono::milliseconds(50)); m_keyboard.reset(new huagao::Keyboard(btnevent)); m_keyboard->init(); this_thread::sleep_for(std::chrono::milliseconds(50)); motorZouzhi.enablePower(true); motorZouzhi.setSpeed(4000); motorCuozhi.setSpeed(3000); motorCuozhi.setDirection(false); std::this_thread::sleep_for(std::chrono::milliseconds(50)); FsmState::setScanner(this); threadRunMessageLoop = std::thread(&Scanner::runMessageLoop, this); Motor::enablePower(true); this_thread::sleep_for(std::chrono::milliseconds(200)); } Scanner::~Scanner() { Motor::enablePower(false); sysEvent.Clear(); sysEvent.ShutDown(); bMsgLoop = false; threadRunMessageLoop.join(); m_DstScannum = 0; if (threadRunScan.joinable()) threadRunScan.join(); } void Scanner::updateSpeedMode(int speed) { m_scaninfo = GetScanInfoFromJson(); if(m_scaninfo.SpeedMode==0) m_scaninfo.SpeedMode=3; unsigned int t_dpi = m_config.params.dpi; if(typeid(*capturer)==typeid(MultiFrameCapture)) if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19) //长文稿采用600dpi模式扫描 t_dpi = 3; motorCuozhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor); motorZouzhi.speedChange(m_scaninfo.SpeedMode, t_dpi,m_config.params.isColor); } void Scanner::startScan() { if (threadRunScan.joinable()) threadRunScan.join(); stop_countdown(); updateSpeedMode(4); // //开始进行扫描 threadRunScan = std::thread(&Scanner::runScan, this); writesyslog(LOG_INFO, getmeminfo()); } void Scanner::runMessageLoop() { std::this_thread::sleep_for(std::chrono::milliseconds(3000));//避免scanpin io 开始异常 GetSysInfo();//待fpga 重启完成 FsmState *fsmState = FsmStateManagerEx::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; } if (typeid(*fsmState) == typeid(CoverOpenState)) { m_glue.m_deviceevent(1, "Cover Open"); } else if (event == S_EVT_SCAN_STOPPED) { if (!m_correctting) { m_glue.m_deviceevent(70, "Scan done"); } } else if (event == S_EVT_JAM_IN) { m_glue.m_deviceevent(4, "Feed error"); } else if (event == S_EVT_DOUBLEPAPER) { m_glue.m_deviceevent(16, "Double feed"); } else if (event == S_EVT_JAM_OUT || typeid(*fsmState) == typeid(ErrorJamState)) { m_glue.m_deviceevent(8, "Jam out"); } else if (typeid(*fsmState) == typeid(ErrorState) && m_jamIn == true) { 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) { m_glue.m_deviceevent(70, "Scan Stop"); } } } static int imageindex = 0; 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)); imageindex = 0; sensor->resetPaperPin(); capturer->clearimages(); 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; StopWatch sw2; while (m_DstScannum > 0) { sw1.reset(); m_isDoublePaper = false; m_jamPaper = false; m_jamIn = false; if (!sensor->isPaperStandby()) //无纸 { if (!sensor->waitPaperStandBy(0)) { put(S_EVT_STOP_SCAN); LOG("STOP STOP STOP RUNSCAN \n"); } break; } sensor->enableDoubleSensor(m_config.params.doubleFeeded); if (m_DstScannum == 0) //被取消扫描了 { break; } motorCuozhi.startAsyn(); if (!sensor->isPaperStandby()) { put(S_EVT_STOP_SCAN); isRested = false; break; } isRested = false; if (!sensor->waitPaperIn(3000))// { if (!m_isDoublePaper) { m_glue.m_deviceevent(4, "Feed error"); m_jamIn = true; put(S_EVT_JAM_IN); m_scaninfo.JamInNum++; //writesyslog(LOG_INFO, "paper jam in error \n"); } break; } printf("检测到纸张的时间:%f\r\n",sw.elapsed_ms());//检测到纸张 capturer->snap(); motorCuozhi.pauseWaitForThread(); int i = 0; int max = 7; if(m_config.params.pageSize >= (int)PaperSize::G400_LONGLETTER) max = m_scaninfo.SpeedMode>3?10:25; else max = m_scaninfo.SpeedMode>3?5:8; max = m_config.params.dpi > 2 ? 30 : max * m_config.params.dpi; if(m_config.params.pageSize == 17 || m_config.params.pageSize == 19) { max = 200; } waitpapertime = 200; sw2.reset(); while (!sensor->waitPaperOut(waitpapertime) && i < max) { i++; if (!sensor->isPaperIn()) { LOG("paper 假卡纸了。。。。。\n"); break; } } if (i == max && sensor->isPaperIn()) { if (!m_isDoublePaper) { m_glue.m_deviceevent(8, "Jam out"); //卡纸 m_jamPaper = true; put(S_EVT_JAM_OUT); m_scaninfo.JamOutNum++; LOG("paper 卡纸了。。。。。\n"); } else { // m_glue.m_deviceevent(16); //双张 // LOG("paper 双张了。。。。。\n"); m_scaninfo.DoubleNum++; } capturer->stopsnap(b_autosize); capturer->waitsnapdone(1);//等待采集完成 this_thread::sleep_for(std::chrono::milliseconds(500));//200 80ms 600 260ms break; } //LOG("\nclose double sensor %s\n",GetCurrentTimeStamp(2).c_str()); sensor->enableDoubleSensor(false); if(b_autosize) { int dly_speed= (5 - m_scaninfo.SpeedMode)*10; int delay = m_config.params.dpi==0x02?70:(m_config.params.dpi==0x03?350: 20); if((m_config.params.pageSize == 17 || m_config.params.pageSize == 19)&&(delay < 350)) { delay = 350; } if(m_config.params.pageSize == 18) delay = std::max(delay,80); delay += dly_speed; if (m_config.params.dpi == 3) { delay = 0; } this_thread::sleep_for(std::chrono::milliseconds(delay));//200 80ms 600 260ms } if(b_autosize) { int de = (5 - m_scaninfo.SpeedMode)*10*m_config.params.dpi; if (de == 3) { de = 0; } std::this_thread::sleep_for(std::chrono::milliseconds(de)); if(sensor->isPaperAtScan()) { m_glue.m_deviceevent((int)HG_ScannerStatus::PAPER_HOLE,"paper have hole"); capturer->waitsnapdone(1);//等待采集完成 capturer->stopsnap(b_autosize); break; } } capturer->stopsnap(b_autosize); capturer->waitsnapdone(m_isDoublePaper || m_jamPaper);//等待采集完成 m_DstScannum--; m_scaninfo.RollerNum++; m_scaninfo.TotalScanned++; if (m_DstScannum == 0) { this_thread::sleep_for(std::chrono::milliseconds(200)); put(S_EVT_STOP_SCAN); break; } sw.reset(); while (meminfo->GetMemoryUsed() > 90.0f||(m_config.params.dpi ==0x03 && capturer->getimageremain()>1)) //内存占用高于75% { if (sw.elapsed_s() < 50.0) { std::this_thread::yield(); } else { put(S_EVT_STOP_SCAN); break; } } printf("一张纸完成时间:%f\r\n",sw1.elapsed_ms()); if( m_config.params.dpi == 3) this_thread::sleep_for(std::chrono::milliseconds(3000)); } m_DstScannum = 0; sensor->enableDoubleSensor(false); sensor->resetPaperPin(); capturer->setScanFlag(false); int t_delay = m_config.params.dpi == 0x02 ? 150 : (m_config.params.dpi == 0x03 ? 350 : 100); this_thread::sleep_for(std::chrono::milliseconds(t_delay)); //走纸多转一会儿 确保扫描传感器过了之后 纸能出完 capturer->setFanMode(0); 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 = GetSMBType(), .FPGAVersion = 0, .Cistype = (HGCISType)GetCisType(), .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(); }