LAPTOP-T815PCOQ\25526
2024-11-28 468a5415022b3fec6c874f4ff690041a5fe2c195
1.IO模块读写PLC数据
已修改3个文件
171 ■■■■ 文件已修改
SourceCode/Bond/BondEq/BondEqDlg.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/View/IOMonitoringDlg.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -485,12 +485,13 @@
    // Cavity VacuumBake AfterBake AOI
    CIOMonitoringDlg dlg;
    dlg.SetIOManager("Cavity");
    dlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
    dlg.DoModal();
    //CAxisSettingsDlg axisDlg;
    //axisDlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
    //axisDlg.SetRecipeName(_T("Default"));
    //axisDlg.DoModal();
    //CAxisSettingsDlg dlg;
    //dlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
    //dlg.SetRecipeName(_T("Default"));
    //dlg.DoModal();
    /*
    CSettingsDlg dlg;
SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
@@ -5,6 +5,7 @@
#include "BondEq.h"
#include "afxdialogex.h"
#include "IOMonitoringDlg.h"
#include "ToolUnits.h"
#define TIMER_INIT                1
#define TIMER_READ_PLC_DATA        2
@@ -53,6 +54,12 @@
    // 计算页数
    m_nCurrentPage = 1;
    m_nTotalPages = (m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage;
}
void CIOMonitoringDlg::SetPLC(CPLC* pPLC)
{
    ASSERT(pPLC);
    m_pPLC = pPLC;
}
CFont* CIOMonitoringDlg::GetOrCreateFont(int nFontSize)
@@ -185,13 +192,33 @@
            CString currentText;
            pControl->GetWindowText(currentText);
            BOOL bOn = FALSE;
            if (currentText == _T("OFF")) {
                pControl->SetBkColor(RGB(0, 255, 0)); // 绿色背景
                pControl->SetText(_T("ON"));          // 更新文本为 ON
                //pControl->SetBkColor(RGB(0, 255, 0)); // 绿色背景
                //pControl->SetText(_T("ON"));          // 更新文本为 ON
                bOn = TRUE;
            }
            else {
                pControl->SetBkColor(RGB(255, 0, 0)); // 红色背景
                pControl->SetText(_T("OFF"));         // 更新文本为 OFF
                //pControl->SetBkColor(RGB(255, 0, 0)); // 红色背景
                //pControl->SetText(_T("OFF"));         // 更新文本为 OFF
                bOn = FALSE;
            }
            pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 4]);
            pControl->GetWindowText(currentText);
            int nAddress;
            MC::SOFT_COMPONENT component;
            if (ParsePLCAddress(currentText, component, nAddress) && m_pPLC) {
                TRACE("地址解析成功: %s\n", currentText);
                m_pPLC->writeBit(component, nAddress, bOn, [](IMcChannel* pChannel, int addr, DWORD value, int flag) {
                    if (flag == 0) {
                        TRACE("写入成功: 地址: %d, 值: %lu\n", addr, value);
                    }
                    else {
                        TRACE("写入失败: 地址: %d, 错误码: %d\n", addr, flag);
                    }
                });
            }
        });
        x += colWidthSmall;
@@ -291,23 +318,118 @@
    m_staticControls.clear();
}
void CIOMonitoringDlg::UpdatePLCStates()
bool CIOMonitoringDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr)
{
    // 随机值模拟
    for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) {
        // 模拟获取输入状态
        bool inputState = (rand() % 2 == 0); // 偶尔为 true/false
        auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]);
        inputControl->SetBkColor(inputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
        inputControl->SetText(inputState ? _T("ON") : _T("OFF"));
    if (address.GetLength() < 2) {
        return false;
    }
    // 提取组件类型(第一个字符)
    TCHAR componentChar = address[0];
    switch (componentChar) {
    case 'D':
        component = MC::SOFT_COMPONENT::D;
        break;
    case 'M':
        component = MC::SOFT_COMPONENT::M;
        break;
    case 'X':
        component = MC::SOFT_COMPONENT::X;
        break;
    case 'Y':
        component = MC::SOFT_COMPONENT::Y;
        break;
    default:
        return false;
    }
    CString hexAddress = address.Mid(1);
    addr = _tcstoul(hexAddress, nullptr, 16);
    return true;
}
void CIOMonitoringDlg::UpdatePLCStates()
{
    // 示例:从 PLC 获取值,这里用随机值模拟
    //for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) {
    //    // 模拟获取输入状态
    //    bool inputState = (rand() % 2 == 0); // 偶尔为 true/false
    //    auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]);
    //    inputControl->SetBkColor(inputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
    //    inputControl->SetText(inputState ? _T("ON") : _T("OFF"));
    //}
    //for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) {
    //    // 模拟获取输出状态
    //    bool outputState = (rand() % 2 == 0); // 偶尔为 true/false
    //    auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]);
    //    outputControl->SetBkColor(outputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
    //    outputControl->SetText(outputState ? _T("ON") : _T("OFF"));
    //}
    // 输入地址的读取
    if (!m_inputPLCAddresses.empty()) {
        // 获取起始地址和长度
        CString startAddressStr = m_inputPLCAddresses.front();
        CString endAddressStr = m_inputPLCAddresses.back();
        MC::SOFT_COMPONENT component;
        int startAddress, endAddress;
        // 解析起始和结束地址
        if (ParsePLCAddress(startAddressStr, component, startAddress) &&
            ParsePLCAddress(endAddressStr, component, endAddress)) {
            int inputSize = endAddress - startAddress + 1;
            // 回调处理输入数据
            auto funOnReadInput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
                if (nDataSize == (unsigned int)(m_inputPLCAddresses.size()) && flag == 0) {
                    for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) {
                        int offset = i;
                        int value = CToolUnits::toInt16(&pData[offset]);
                        auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]); // 第 0 列
                        inputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // 更新背景颜色
                        inputControl->SetText(value ? _T("ON") : _T("OFF"));               // 更新文本
                    }
                }
            };
            // 读取输入数据
            m_pPLC->readData(component, startAddress, inputSize, funOnReadInput);
        }
    }
    // 输出地址的读取
    if (!m_outputPLCAddresses.empty()) {
        // 获取起始地址和长度
        CString startAddressStr = m_outputPLCAddresses.front();
        CString endAddressStr = m_outputPLCAddresses.back();
        MC::SOFT_COMPONENT component;
        int startAddress, endAddress;
        // 解析起始和结束地址
        if (ParsePLCAddress(startAddressStr, component, startAddress) &&
            ParsePLCAddress(endAddressStr, component, endAddress)) {
            int outputSize = endAddress - startAddress + 1;
            // 回调处理输出数据
            auto funOnReadOutput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
                if (nDataSize == (unsigned int)(m_outputPLCAddresses.size()) && flag == 0) {
    for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) {
        // 模拟获取输出状态
        bool outputState = (rand() % 2 == 0); // 偶尔为 true/false
        auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]);
        outputControl->SetBkColor(outputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
        outputControl->SetText(outputState ? _T("ON") : _T("OFF"));
                        int offset = i;
                        int value = CToolUnits::toInt16(&pData[offset]);
                        auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); // 第 3 列
                        outputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // 更新背景颜色
                        outputControl->SetText(value ? _T("ON") : _T("OFF"));               // 更新文本
                    }
                }
            };
            // 读取输出数据
            m_pPLC->readData(component, startAddress, outputSize, funOnReadOutput);
        }
    }
}
@@ -431,7 +553,7 @@
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if (TIMER_READ_PLC_DATA == nIDEvent) {
        //ASSERT(m_pPLC);
        ASSERT(m_pPLC);
        UpdatePLCStates();
        Sleep(100);
    }
SourceCode/Bond/BondEq/View/IOMonitoringDlg.h
@@ -2,6 +2,7 @@
#include "afxdialogex.h"
#include "IOManager.h"
#include "BLLabel.h"
#include "CPLC.h"
// CIOMonitoringDlg 对话框
@@ -14,6 +15,7 @@
    CIOMonitoringDlg(CWnd* pParent = nullptr);   // 标准构造函数
    virtual ~CIOMonitoringDlg();
    void SetIOManager(const std::string& machineName); // 设置 IOManager 和机器名
    void SetPLC(CPLC* pPLC); // 设置 PLC
// 对话框数据
#ifdef AFX_DESIGN_TIME
@@ -31,9 +33,11 @@
    void CreateStaticControl(int x, int y, int width, int height, const CString& text, bool hasBorder = false, TextAlign alignment = AlignLeft, std::function<void()> clickCallback = nullptr); // 创建静态控件
    void DisplayCurrentPage();        // 显示当前页数据
    void ClearDynamicControls();    // 清除动态创建的控件
    bool ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr); // 解析 PLC 地址
    void UpdatePLCStates();            // 定时器更新状态的方法
private:
    CPLC* m_pPLC;
    int m_nInitialWidth;
    int m_nInitialHeight;
    int m_nCurrentPage; // 当前页