From 3a9d54f7454c6085cdd9fde71ea8e321b9ac0402 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期五, 12 九月 2025 11:50:01 +0800
Subject: [PATCH] 1.PanelDataReport事件上抛,以便上层检测到AOI 检测NG后停机; 2.CessetteSn种子数设定,保存到配置,以便程序关闭重开后,CessetteSn也能继续; 3.AOI增加工艺参数,修改解释规则;
---
SourceCode/Bond/Servo/CLoadPort.h | 2
SourceCode/Bond/Servo/Configuration.cpp | 14 +++
SourceCode/Bond/Servo/CMaster.h | 16 +++
SourceCode/Bond/Servo/Model.cpp | 3
Document/EO2860AVA-101工艺参数(2).xlsx | 0
SourceCode/Bond/Servo/CLoadPort.cpp | 13 +++
SourceCode/Bond/Servo/ServoDlg.cpp | 15 +++
SourceCode/Bond/Servo/CPageGlassList.cpp | 35 ++++++++
SourceCode/Bond/Servo/Configuration.h | 2
/dev/null | 0
SourceCode/Bond/Servo/CMeasurement.cpp | 10 ++
SourceCode/Bond/Servo/CEquipment.cpp | 10 ++
SourceCode/Bond/Servo/CMaster.cpp | 76 ++++++++++++++++++
SourceCode/Bond/Servo/CEquipment.h | 1
14 files changed, 189 insertions(+), 8 deletions(-)
diff --git "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0501\051.xlsx" "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0501\051.xlsx"
deleted file mode 100644
index 679a879..0000000
--- "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0501\051.xlsx"
+++ /dev/null
Binary files differ
diff --git "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0502\051.xlsx" "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0502\051.xlsx"
new file mode 100644
index 0000000..bd00318
--- /dev/null
+++ "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260\0502\051.xlsx"
Binary files differ
diff --git "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx" "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx"
deleted file mode 100644
index ae31ee6..0000000
--- "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx"
+++ /dev/null
Binary files differ
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index f89dcf9..aa339b2 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/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;
}
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index bf1808b..a469408 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -72,6 +72,7 @@
ONMAPMISMATCH onMapMismatch;
ONPORTSTATUSCHANGED onPortStatusChanged;
ONVCREVENTREPORT onSVDataReport;
+ ONVCREVENTREPORT onPanelDataReport;
} EquipmentListener;
diff --git a/SourceCode/Bond/Servo/CLoadPort.cpp b/SourceCode/Bond/Servo/CLoadPort.cpp
index e7725f2..22b517b 100644
--- a/SourceCode/Bond/Servo/CLoadPort.cpp
+++ b/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;
diff --git a/SourceCode/Bond/Servo/CLoadPort.h b/SourceCode/Bond/Servo/CLoadPort.h
index 12776df..523ab69 100644
--- a/SourceCode/Bond/Servo/CLoadPort.h
+++ b/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();
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 3b2d01f..e93c06e 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/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 模式");
- setState(MASTERSTATE::READY);
+ 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检测未通过.";
+ }
+ }
}
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index e79589d..8536ab2 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/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();
diff --git a/SourceCode/Bond/Servo/CMeasurement.cpp b/SourceCode/Bond/Servo/CMeasurement.cpp
index 8357d01..d93bc50 100644
--- a/SourceCode/Bond/Servo/CMeasurement.cpp
+++ b/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();
}
diff --git a/SourceCode/Bond/Servo/CPageGlassList.cpp b/SourceCode/Bond/Servo/CPageGlassList.cpp
index 38d93d3..fd107a7 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.cpp
+++ b/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) 鎵撳紑鍓创鏉垮苟璁剧疆鏁版嵁锛圕F_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;
diff --git a/SourceCode/Bond/Servo/Configuration.cpp b/SourceCode/Bond/Servo/Configuration.cpp
index c853bba..8b8d49a 100644
--- a/SourceCode/Bond/Servo/Configuration.cpp
+++ b/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);
+}
+
diff --git a/SourceCode/Bond/Servo/Configuration.h b/SourceCode/Bond/Servo/Configuration.h
index a1e06da..ea74b6a 100644
--- a/SourceCode/Bond/Servo/Configuration.h
+++ b/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);
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index b9c5505..b100f14 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/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);
}
}
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index 646641d..0924c6c 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/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();
}
--
Gitblit v1.9.3