| | |
| | | |
| | | // CAxisDetailSettingsDlg 对话框 |
| | | |
| | | IMPLEMENT_DYNAMIC(CAxisDetailSettingsDlg, CDialogEx) |
| | | IMPLEMENT_DYNAMIC(CAxisDetailSettingsDlg, CBaseDlg) |
| | | |
| | | CAxisDetailSettingsDlg::CAxisDetailSettingsDlg(const CString& strRecipeName, int nAxisNO, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_AXIS_DETAIL_SETTINGS, pParent) |
| | | : CBaseDlg(IDD_DIALOG_AXIS_DETAIL_SETTINGS, pParent) |
| | | { |
| | | m_strRecipeName = strRecipeName; |
| | | m_nAxisNO = nAxisNO; |
| | | |
| | | m_pPLC = nullptr; |
| | | m_nInitialWidth = 0; |
| | | m_nInitialHeight = 0; |
| | | } |
| | | |
| | | CAxisDetailSettingsDlg::~CAxisDetailSettingsDlg() |
| | |
| | | GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MAX)->SetWindowText(formatDouble(axisDetails.decelerationTime.maxValue)); |
| | | } |
| | | |
| | | bool CAxisDetailSettingsDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr) |
| | | { |
| | | if (address.GetLength() < 2) { |
| | | return false; |
| | | } |
| | | |
| | | // 提取组件类型(第一个字符) |
| | | TCHAR componentChar = address[0]; |
| | | if (address.Left(2) == _T("ZR")) { |
| | | component = MC::SOFT_COMPONENT::ZR; |
| | | // 提取数字部分(去除ZR前缀) |
| | | CString numericAddress = address.Mid(2); |
| | | addr = _ttoi(numericAddress); |
| | | return addr != 0 || numericAddress.CompareNoCase(_T("0")) == 0; // 如果是 "0",也认为有效 |
| | | } |
| | | |
| | | // 对于其他组件,按照常规规则处理 |
| | | CString hexAddress = address.Mid(1); |
| | | switch (componentChar) { |
| | | case 'D': |
| | | component = MC::SOFT_COMPONENT::D; |
| | | addr = _ttoi(hexAddress); |
| | | break; |
| | | case 'M': |
| | | component = MC::SOFT_COMPONENT::M; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'X': |
| | | component = MC::SOFT_COMPONENT::X; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'Y': |
| | | component = MC::SOFT_COMPONENT::Y; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'W': |
| | | component = MC::SOFT_COMPONENT::W; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'L': |
| | | component = MC::SOFT_COMPONENT::L; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'S': |
| | | component = MC::SOFT_COMPONENT::S; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'B': |
| | | component = MC::SOFT_COMPONENT::B; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'F': |
| | | component = MC::SOFT_COMPONENT::F; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | default: |
| | | return false; |
| | | } |
| | | |
| | | // 检查地址是否有效 |
| | | if (addr == 0 && hexAddress.CompareNoCase(_T("0")) != 0) { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | void CAxisDetailSettingsDlg::writeAxisDataToPLC(int nAxisId) |
| | | { |
| | | // 获取轴数据 |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | AxisInfo axisData = recipeManager.getAxis(nAxisId); |
| | | |
| | | MC::SOFT_COMPONENT enComponent; |
| | | int nStartAddress, nEndAddress, nSize; |
| | | if (!ParsePLCAddress(CString(axisData.startAddress.c_str()), enComponent, nStartAddress)) { |
| | | AfxMessageBox(_T("无效的起始地址!")); |
| | | } |
| | | nEndAddress = nStartAddress + 300; |
| | | nSize = (nEndAddress - nStartAddress + 1) * 2; |
| | | |
| | | char szWrite[300] = { 0 }; |
| | | |
| | | auto writeIntToBuffer = [&](int value, int nWriteIndex) { |
| | | if (nWriteIndex + 4 <= sizeof(szWrite)) { |
| | | // 小端 |
| | | szWrite[nWriteIndex] = static_cast<char>(value & 0xFF); // 低字节 |
| | | szWrite[nWriteIndex + 1] = static_cast<char>((value >> 8) & 0xFF); // 次低字节 |
| | | szWrite[nWriteIndex + 2] = static_cast<char>((value >> 16) & 0xFF); // 次高字节 |
| | | szWrite[nWriteIndex + 3] = static_cast<char>((value >> 24) & 0xFF); // 高字节 |
| | | |
| | | // 大端 |
| | | //szWrite[nWriteIndex + 3] = static_cast<char>(value & 0xFF); // 高字节 |
| | | //szWrite[nWriteIndex + 2] = static_cast<char>((value >> 8) & 0xFF); // 次高字节 |
| | | //szWrite[nWriteIndex + 1] = static_cast<char>((value >> 16) & 0xFF); // 次低字节 |
| | | //szWrite[nWriteIndex] = static_cast<char>((value >> 24) & 0xFF); // 低字节 |
| | | } |
| | | }; |
| | | |
| | | // 写入手动速度 |
| | | // writeIntToBuffer(static_cast<int>(axisData.manualSpeed.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(axisData.manualSpeed.currentValue * 1000), 82); |
| | | // writeIntToBuffer(static_cast<int>(axisData.manualSpeed.maxValue * 1000), 0); |
| | | |
| | | // 写入自动速度 |
| | | // writeIntToBuffer(static_cast<int>(axisData.autoSpeed.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(axisData.autoSpeed.currentValue * 1000), 84); |
| | | // writeIntToBuffer(static_cast<int>(axisData.autoSpeed.maxValue * 1000), 0); |
| | | |
| | | // 写入加速时间 |
| | | // writeIntToBuffer(static_cast<int>(axisData.accelerationTime.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(axisData.accelerationTime.currentValue * 1000), 62); |
| | | // writeIntToBuffer(static_cast<int>(axisData.accelerationTime.maxValue * 1000), 0); |
| | | |
| | | // 写入减速时间 |
| | | // writeIntToBuffer(static_cast<int>(axisData.decelerationTime.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(axisData.decelerationTime.currentValue * 1000), 64); |
| | | // writeIntToBuffer(static_cast<int>(axisData.decelerationTime.maxValue * 1000), 0); |
| | | |
| | | // 写入微动量 |
| | | // writeIntToBuffer(static_cast<int>(axisData.jogDistance.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(axisData.jogDistance.currentValue * 1000), 81); |
| | | // writeIntToBuffer(static_cast<int>(axisData.jogDistance.maxValue * 1000), 0); |
| | | |
| | | // 定位点数据 |
| | | int nIndex = 100; |
| | | for (int i = 0; i < axisData.positions.size(); ++i) { |
| | | const auto& position = axisData.positions[i]; |
| | | // writeIntToBuffer(static_cast<int>(position.range.minValue * 1000), 0); |
| | | writeIntToBuffer(static_cast<int>(position.range.currentValue * 1000), nIndex + (i * 2)); |
| | | // writeIntToBuffer(static_cast<int>(position.range.maxValue * 1000), 0); |
| | | } |
| | | |
| | | // 向 PLC 写入信号 |
| | | m_pPLC->writeData(enComponent, nStartAddress, szWrite, nSize, [nStartAddress, &szWrite](IMcChannel* pChannel, int nAddr, DWORD nValue, int nFlag) { |
| | | if (nFlag == 0) { |
| | | TRACE("操作成功:地址=%d,值=%s\n", nStartAddress, szWrite); |
| | | } |
| | | else { |
| | | TRACE("操作失败:地址=%d,错误码=%d\n", nStartAddress, nFlag); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | void CAxisDetailSettingsDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | CBaseDlg::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_NUMBER, m_staticAxisNO); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_DESCRIP, m_staticAxisDescription); |
| | | DDX_Control(pDX, IDC_STATIC_START_ADDRESS, m_staticStartAddress); |
| | |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CAxisDetailSettingsDlg, CDialogEx) |
| | | BEGIN_MESSAGE_MAP(CAxisDetailSettingsDlg, CBaseDlg) |
| | | ON_NOTIFY(NM_CLICK, IDC_CUSTOM_AXIS_ANCHOR_POINT, &CAxisDetailSettingsDlg::OnGridItemChanged) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_DETAIL_SETTINGS_SAVE, &CAxisDetailSettingsDlg::OnBnClickedButtonAxisDetailSettingsSave) |
| | | ON_BN_CLICKED(IDC_BUTTON_SET_AXIS_POSITIONING_POINTS, &CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints) |
| | |
| | | |
| | | BOOL CAxisDetailSettingsDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | CBaseDlg::OnInitDialog(); |
| | | |
| | | // TODO: 在此添加额外的初始化 |
| | | CString strTitle; |
| | |
| | | // 保存轴数据到文件 |
| | | CString cstrMessage; |
| | | if (RecipeManager::getInstance().saveRecipe(std::string(CT2A(m_strRecipeName)))) { |
| | | writeAxisDataToPLC(m_nAxisNO); |
| | | cstrMessage.Format(_T("保存轴 [%d] 细部参数成功!"), m_nAxisNO); |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, std::string(CT2A(cstrMessage))); |
| | | } |