1.PanelDataReport事件上抛,以便上层检测到AOI 检测NG后停机;
2.CessetteSn种子数设定,保存到配置,以便程序关闭重开后,CessetteSn也能继续;
3.AOI增加工艺参数,修改解释规则;
已添加1个文件
已删除2个文件
已修改12个文件
195 ■■■■■ 文件已修改
Document/EO2860AVA-101工艺参数(1).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/EO2860AVA-101工艺参数(2).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/EO2860AVA-101工艺参数.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMeasurement.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.cpp 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Configuration.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Configuration.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Document/EO2860AVA-101¹¤ÒÕ²ÎÊý(1).xlsx
Binary files differ
Document/EO2860AVA-101¹¤ÒÕ²ÎÊý(2).xlsx
Binary files differ
Document/EO2860AVA-101¹¤ÒÕ²ÎÊý.xlsx
Binary files differ
SourceCode/Bond/Servo/CEquipment.cpp
@@ -1573,7 +1573,8 @@
        CGlass* pGlass = this->getGlassWithCassette(processData.getCassetteSequenceNo(),
            processData.getJobSequenceNo());
        if (pGlass == nullptr) {
            LOGE("<CEquipment-%s>找不到对应Glass, å…³è”工艺参数失败。", this->getName().c_str(),
            LOGE("<CEquipment-%s>找不到对应Glass, å…³è”工艺参数失败。CassetteSequenceNo:%d/%d",
                this->getName().c_str(),
                processData.getCassetteSequenceNo(),
                processData.getJobSequenceNo());
            return -1;
@@ -1822,7 +1823,12 @@
                getName().c_str(), cassetteNo, jobSequenceNo);
            return -1;
        }
        pGlass->setInspResult(m_nID, 0, judgeStringToInspResult(strPanelJudgeData));
        auto result = judgeStringToInspResult(strPanelJudgeData);
        pGlass->setInspResult(m_nID, 0, result);
        if (m_listener.onPanelDataReport != nullptr) {
            m_listener.onPanelDataReport(this, pGlass);
        }
        return 0;
    }
SourceCode/Bond/Servo/CEquipment.h
@@ -72,6 +72,7 @@
        ONMAPMISMATCH        onMapMismatch;
        ONPORTSTATUSCHANGED    onPortStatusChanged;
        ONVCREVENTREPORT    onSVDataReport;
        ONVCREVENTREPORT    onPanelDataReport;
    } EquipmentListener;
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -490,6 +490,19 @@
        return (m_nIndex + 1) * 1000 + m_nNextCassetteSequenceNo;
    }
    int CLoadPort::getPortCassetteSnSeed()
    {
        return m_nNextCassetteSequenceNo;
    }
    void CLoadPort::setPortCassetteSnSeed(int seed)
    {
        m_nNextCassetteSequenceNo = seed;
        if (m_nNextCassetteSequenceNo >= 1000) {
            m_nNextCassetteSequenceNo = 0;
        }
    }
    void CLoadPort::setIndex(unsigned int index)
    {
        m_nIndex = index;
SourceCode/Bond/Servo/CLoadPort.h
@@ -42,6 +42,8 @@
    public:
        short getNextCassetteSequenceNo();
        int getPortCassetteSnSeed();
        void setPortCassetteSnSeed(int seed);
        void setIndex(unsigned int index);
        unsigned int getIndex();
        BOOL isEnable();
SourceCode/Bond/Servo/CMaster.cpp
@@ -53,7 +53,7 @@
        m_ullRunTime = 0;
        m_state = MASTERSTATE::READY;
        m_pActiveRobotTask = nullptr;
        m_nLastError = 0;
        m_nLastError = ER_CODE_NOERROR;
        m_isCompareMapsBeforeProceeding = FALSE;
        m_bJobMode = FALSE;
        m_bEnableEventReport = true;
@@ -307,7 +307,7 @@
        return 0;
    }
    int CMaster::stop()
    int CMaster::stop(int nErCode/* = ER_CODE_NOERROR*/)
    {
        // è¿è¡Œæ—¶é—´ä¸ºç´¯åŠ ç»“æžœï¼Œæœ¬æ¬¡åœæ­¢æ—¶åˆ·æ–°ï¼›
        lock();
@@ -321,6 +321,7 @@
        // æ›´æ–°çŠ¶æ€
        m_nLastError = nErCode;
        setState(MASTERSTATE::STOPPING);
@@ -423,6 +424,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>EFEM切换Start状态失败");
                    m_nLastError = ER_CODE_OPERATION_MODE_FAIL;
                    m_strLastError = "EFEM切换Start状态失败.";
                    goto WAIT;
                }
@@ -436,6 +438,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>Bonder1切换Start状态失败");
                    m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL;
                    m_strLastError = "Bonder1切换Start状态失败.";
                    goto WAIT;
                }
@@ -449,6 +452,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>Bonder2切换Start状态失败");
                    m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL;
                    m_strLastError = "Bonder2切换Start状态失败.";
                    goto WAIT;
                }
@@ -462,6 +466,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>BakeCooling切换Start状态失败");
                    m_nLastError = ER_CODE_OPERATION_MODE_FAIL;
                    m_strLastError = "BakeCooling切换Start状态失败.";
                    goto WAIT;
                }
@@ -475,6 +480,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>VacuumBake切换Start状态失败");
                    m_nLastError = ER_CODE_OPERATION_MODE_FAIL;
                    m_strLastError = "VacuumBake切换Start状态失败.";
                    goto WAIT;
                }
@@ -488,6 +494,7 @@
                    });
                if (nRet != 0) {
                    LOGE("<Master>Measurement切换Start状态失败");
                    m_nLastError = ER_CODE_OPERATION_MODE_FAIL;
                    m_strLastError = "Measurement切换Start状态失败.";
                    goto WAIT;
                }
@@ -546,6 +553,7 @@
                        });
                    if (nRet != 0) {
                        LOGE("<Master>%s切换Stop状态发送失败", pEq[i]->getName().c_str());
                        m_nLastError = ER_CODE_OPERATION_MODE_FAIL;
                        m_strLastError = pEq[i]->getName() + "切换Stop状态发送失败.";
                        bIomcOk[i] = FALSE;
                        promises[i].set_value(); // é¿å… wait é˜»å¡ž
@@ -570,7 +578,11 @@
                }
                LOGI("<Master>所有设备成功切换到 Stop æ¨¡å¼");
                if(m_nLastError == ER_CODE_NOERROR)
                setState(MASTERSTATE::READY);
                else
                    setState(MASTERSTATE::ATHERERROR);
                continue;
            }
@@ -774,6 +786,7 @@
                                continue;
                            }
                            pGlass->queue();
                            pGlass->start();
                            pEFEM->setContext(m_pActiveRobotTask->getContext());
                            goto PORT_GET;
@@ -1450,6 +1463,8 @@
                    if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) {
                        CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext();
                        pGlass->complete();
                        CGlass* pBuddy = pGlass->getBuddy();
                        if (pBuddy != nullptr) pBuddy->complete();
                        this->saveState();
                        bool bMoved = glassFromInPorcessToComplete(pGlass);
                        if (bMoved) {
@@ -1572,6 +1587,25 @@
                strOut.append(szBuffer);
            }
            LOGD("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str());
        };
        listener.onPanelDataReport = [&](void* pEquipment, void* pContext) {
            LOGD("<CMaster-%s>onPanelDataReport", ((CEquipment*)pEquipment)->getName().c_str());
            CEquipment* pEq = (CEquipment*)pEquipment;
            CGlass* pGlass = (CGlass*)pContext;
            // å¦‚æžœAOI检测失败,要停机
            if (pEq->getID() == EQ_ID_MEASUREMENT) {
                LOGD("<CMaster-%s>onPanelDataReport 01", ((CEquipment*)pEquipment)->getName().c_str());
                if (pGlass->getAOIInspResult() == InspResult::Fail) {
                    LOGD("<CMaster-%s>onPanelDataReport 02", ((CEquipment*)pEquipment)->getName().c_str());
                    if (stop() == 0) {
                        m_nLastError = ER_CODE_AOI_NG;
                        m_strLastError = "AOI检测未通过.";
                    }
                }
            }
        };
        pEquipment->setListener(listener);
        pEquipment->setCcLink(&m_cclink);
@@ -1833,6 +1867,8 @@
            if (!m_inProcesGlasses.empty()) {
                CGlass* pGlass = m_inProcesGlasses.front();
                pGlass->complete();
                CGlass* pBuddy = pGlass->getBuddy();
                if (pBuddy != nullptr) pBuddy->complete();
                glassFromInPorcessToComplete(pGlass);
                this->saveState();
@@ -2279,6 +2315,22 @@
        pPort->localEanblePort(bEnable);
    }
    int CMaster::getPortCassetteSnSeed(int port)
    {
        ASSERT(1 <= port && port <= 4);
        int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 };
        CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]);
        return pPort->getPortCassetteSnSeed();
    }
    void CMaster::setPortCassetteSnSeed(int port, int seed)
    {
        ASSERT(1 <= port && port <= 4);
        int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 };
        CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]);
        return pPort->setPortCassetteSnSeed(seed);
    }
    void CMaster::setCompareMapsBeforeProceeding(BOOL bCompare)
    {
        m_isCompareMapsBeforeProceeding = bCompare;
@@ -2712,4 +2764,22 @@
        return (int)glasses.size();
    }
    int CMaster::getLastError()
    {
        return m_nLastError;
    }
    std::string& CMaster::getLastErrorText()
    {
        return m_strLastError;
    }
    void CMaster::test()
    {
        if (stop() == 0) {
            m_nLastError = ER_CODE_AOI_NG;
            m_strLastError = "AOI检测未通过.";
        }
    }
}
SourceCode/Bond/Servo/CMaster.h
@@ -33,6 +33,10 @@
#define CTStep_begin                    CTStep_LoadPort_Aligner
#define CTStep_end                      CTStep_Measurement_LoadPort
#define ER_CODE_NOERROR                0
#define ER_CODE_OPERATION_MODE_FAIL    -1
#define ER_CODE_AOI_NG                 -2
namespace SERVO {
    enum class MASTERSTATE {
        READY = 0,
@@ -41,7 +45,8 @@
        RUNNING_CONTINUOUS_TRANSFER,
        RUNNING_BATCH,
        STOPPING,
        MSERROR
        MSERROR,
        ATHERERROR
    };
    typedef std::function<void(void* pMaster, MASTERSTATE state)> ONMASTERSTATECHANGED;
@@ -88,7 +93,7 @@
        int start();
        int startContinuousTransfer();
        int startBatch();
        int stop();
        int stop(int nErCode = ER_CODE_NOERROR);
        void clearError();
        ULONGLONG getRunTime();
        MASTERSTATE getState();
@@ -125,6 +130,9 @@
        bool saveState() const;
        bool loadState(const std::string& path);
        int getWipGlasses(std::vector<CGlass*>& glasses);
        void test();
        int getPortCassetteSnSeed(int port);
        void setPortCassetteSnSeed(int port, int seed);
    private:
        inline void lock() { EnterCriticalSection(&m_criticalSection); }
@@ -165,6 +173,10 @@
        bool ceidDefined(uint32_t ceid) const override;
    public:
        int getLastError();
        std::string& getLastErrorText();
    public:
        // æ–°å¢žå‡½æ•°
        CProcessJob* acquireNextProcessJob();
        CGlass* acquireNextGlass();
SourceCode/Bond/Servo/CMeasurement.cpp
@@ -455,6 +455,16 @@
        params.push_back(CParam("检测速度", "", this->getName().c_str(), v * 0.001));
        i += 4;
        // 3.检测速度
        v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        params.push_back(CParam("检测速度", "", this->getName().c_str(), v * 0.001));
        i += 4;
        // 4.检测2数据
        v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        params.push_back(CParam("检测速度", "", this->getName().c_str(), v * 0.001));
        i += 4;
        return (int)params.size();
    }
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -340,6 +340,39 @@
    }
}
bool CopyUtf8ToClipboard(const std::string& utf8)
{
    // 1) UTF-8 -> UTF-16 é•¿åº¦ï¼ˆå«ç»“å°¾ '\0')
    int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0);
    if (wlen <= 0) return false;
    // 2) ä¸ºå‰ªè´´æ¿åˆ†é…å…¨å±€å¯ç§»åŠ¨å†…å­˜ï¼ˆå¿…é¡» GMEM_MOVEABLE)
    SIZE_T bytes = static_cast<SIZE_T>(wlen) * sizeof(wchar_t);
    HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, bytes);
    if (!hMem) return false;
    // 3) å¡«å…… UTF-16 æ–‡æœ¬
    wchar_t* wbuf = static_cast<wchar_t*>(GlobalLock(hMem));
    if (!wbuf) { GlobalFree(hMem); return false; }
    MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wbuf, wlen);
    GlobalUnlock(hMem);
    // 4) æ‰“开剪贴板并设置数据(CF_UNICODETEXT)
    if (!OpenClipboard(nullptr)) { GlobalFree(hMem); return false; }
    if (!EmptyClipboard()) { CloseClipboard(); GlobalFree(hMem); return false; }
    // æˆåŠŸåŽï¼Œå†…å­˜æ‰€æœ‰æƒäº¤ç»™å‰ªè´´æ¿ï¼Œä¸èƒ½å† GlobalFree
    if (!SetClipboardData(CF_UNICODETEXT, hMem)) {
        CloseClipboard();
        GlobalFree(hMem);
        return false;
    }
    CloseClipboard();
    return true;
}
// CPageGlassList å¯¹è¯æ¡†
IMPLEMENT_DYNAMIC(CPageGlassList, CDialogEx)
@@ -673,7 +706,7 @@
    // -------- Phase 1: å…ˆå¤„理“有 buddyId çš„记录”(能配就配;单向也配) ----------
    for (size_t i = 0; i < page.items.size(); ++i) {
        const auto& r = page.items[i];
        AfxMessageBox(r.pretty.c_str());
        // CopyUtf8ToClipboard(r.pretty);
        
        if (consumed.count(r.classId)) continue;
        if (r.buddyId.empty()) continue;
SourceCode/Bond/Servo/Configuration.cpp
@@ -176,3 +176,17 @@
    return GetPrivateProfileInt(_T("Master"), _T("CTRound"), 0, m_strFilepath);
}
char* pszPortSection[] = { "Port1", "Port2", "Port3", "Port4" };
int CConfiguration::getPortCassetteSnSeed(int port)
{
    ASSERT(1 <= port && port <= 4);
    return GetPrivateProfileInt(pszPortSection[port-1], _T("CassetteSnSeed"), 0, m_strFilepath);
}
void CConfiguration::setPortCassetteSnSeed(int port, int seed)
{
    ASSERT(1 <= port && port <= 4);
    WritePrivateProfileString(pszPortSection[port - 1], _T("CassetteSnSeed"),
        std::to_string(seed).c_str(), m_strFilepath);
}
SourceCode/Bond/Servo/Configuration.h
@@ -30,6 +30,8 @@
    BOOL isJobMode();
    void setContinuousTransferCount(int round);
    int getContinuousTransferCount();
    int getPortCassetteSnSeed(int port);
    void setPortCassetteSnSeed(int port, int seed);
public:
    void setP2RemoteEqReconnectInterval(int second);
SourceCode/Bond/Servo/Model.cpp
@@ -51,6 +51,9 @@
            cassetteType, transferMode, autoChangeEnable);
        m_master.setPortType(i, portEnable, portType, portMode, cassetteType,
            transferMode, autoChangeEnable);
        int seed = m_configuration.getPortCassetteSnSeed(i + 1);
        m_master.setPortCassetteSnSeed(i + 1, seed);
    }
}
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -217,6 +217,20 @@
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM);
                    m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
                    m_pMyStatusbar->setRunTimeText("启动失败.");
                    m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(TRUE);
                }
                else if (state == SERVO::MASTERSTATE::ATHERERROR) {
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM);
                    m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
                    m_pMyStatusbar->setRunTimeText(theApp.m_model.getMaster().getLastErrorText().c_str());
                    if (theApp.m_model.getMaster().getLastError() == ER_CODE_AOI_NG) {
                        AfxMessageBox(_T("AOI检测失败,请操作员介入解决问题!"));
                    }
                    m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(TRUE);
                }
                else if (state == SERVO::MASTERSTATE::RUNNING || state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER
                    || state == SERVO::MASTERSTATE::RUNNING_BATCH) {
@@ -645,6 +659,7 @@
void CServoDlg::OnMenuHelpAbout()
{
    theApp.m_model.getMaster().test();
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
}